นักเทียบท่า: ได้รับอนุญาตถูกปฏิเสธในขณะที่พยายามเชื่อมต่อกับซ็อกเก็ต Docker daemon ที่ unix: ///var/run/docker.sock


176

ฉันใหม่สำหรับนักเทียบท่า ฉันแค่พยายามใช้นักเทียบท่าในเครื่องของฉัน (Ubuntu 16.04) กับเจนกิ้นส์

ฉันกำหนดค่างานใหม่ด้วยสคริปต์ขั้นต่ำ

node {
    stage('Build') {
      docker.image('maven:3.3.3').inside {
        sh 'mvn --version'
      }
    }
}

แต่มันล้มเหลวด้วยข้อผิดพลาดด้านล่าง

ป้อนคำอธิบายรูปภาพที่นี่


1
มันเป็นเสาหินเจนกินส์หรือมีการตั้งค่าต้นแบบทาส? ตรวจสอบกับผู้ใช้ที่คุณกำลังดำเนินการคำสั่งนักเทียบท่าตรวจสอบ ดูว่า /var/run/docker.sock มีการเข้าถึง RW ไปยังกลุ่ม
Ram Kamath


2
ขั้นตอนหลังการติดตั้งdocker
radistao

คำตอบ:


297

ผู้ใช้jenkinsจะต้องเพิ่มในกลุ่มdocker:

sudo usermod -a -G docker jenkins

จากนั้นรีสตาร์ทเจนกินส์

แก้ไข

หากคุณมาถึงคำถามของการล้นสแต็กนี้เนื่องจากคุณได้รับข้อความนี้จากนักเทียบท่า แต่คุณไม่ได้ใช้เจนกินส์ส่วนใหญ่อาจเป็นข้อผิดพลาดเดียวกัน: ผู้ใช้ที่ไม่มีสิทธิ์ของคุณไม่ได้อยู่ในกลุ่มนักเทียบท่า

คุณทำได้:

sudo usermod -a -G docker alice

หรือชื่อผู้ใช้ของคุณคืออะไร

คุณสามารถตรวจสอบที่สิ้นสุดการทำgrep docker /etc/groupและดูอะไรเช่นนี้

docker:x:998:alice

ในหนึ่งบรรทัด

จากนั้นเปลี่ยน ID กลุ่มผู้ใช้เป็นdocker:

newgrp docker

90
และผู้ใช้ relogin
Ilya Kolesnikov

8
คำตอบที่ดี แต่เพื่อให้กว้างกว่านี้เราสามารถทำได้: sudo usermod -a -G docker $USERและออกจากระบบหรือรีบูต ลิงก์
Julien Nyambal

10
ฉันต้องรีสตาร์ทเซิร์ฟเวอร์เพื่อให้ใช้งานได้จริง
etagwerker

3
ฉันต้องยกเลิกการเชื่อมต่อ / เชื่อมต่อโหนดของฉันอีกครั้งเพื่อให้ทำงานได้ (พวกเขาเชื่อมต่อผ่าน ssh)
GaspardP

29
ไม่จำเป็นต้องลงชื่อเข้าใช้อีกครั้งเพียงใช้newgrp dockerแทนในเซสชันเทอร์มินัลเดียวกัน
C14L

68

โซลูชั่นแรกของฉันคือ:

usermod -aG docker jenkins
usermod -aG root jenkins
chmod 664 /var/run/docker.sock

แต่ไม่มีใครทำงานให้ฉันฉันลอง:

chmod 777 /var/run/docker.sock

ใช้งานได้ แต่ฉันไม่รู้ว่าเป็นการโทรที่ถูกต้องหรือไม่


4
สาเหตุที่ทำให้มันล้มเหลวอาจเป็นเพราะคุณต้องเปิดเครื่องใหม่ มันล้มเหลวหลังจากทำ 664 แต่จากนั้นฉันก็เปิดเชลล์ใหม่มันใช้งานได้
PHGamer

1
ฉันพยายามเปิดใหม่ แต่ก็เริ่มทำงานหลังจาก chmod 777 ล่าสุด
แดกดัน

ปัญหาคือว่าหลังจากรีบูต 777 ถูกรีเซ็ตเป็น 660 สิ่งที่แก้ไขปัญหาสำหรับฉันคือ 'usermod -aG users jenkins'
แดกดัน

ฉันรู้ว่ามันถูกรีเซ็ต แต่ไม่ได้ตั้งค่าการอนุญาต docker.sock เป็น 777 สิ่งนี้จะทำให้ทุกคนรูทบนระบบของคุณ พวกเขาสามารถพูดคุยกับนักเทียบท่าและสร้างภาชนะที่มีสิทธิพิเศษโดยไม่มีข้อ จำกัด
แลนซ์ฮัดสัน

3
แม้จะใช้งานได้ดีกับผู้เขียนและแม้กระทั่งสำหรับฉันการให้สิทธิ์การเข้าถึงdocker.sockไฟล์เพิ่มเติมไม่ใช่วิธีแก้ปัญหาที่ดีที่สุดคุณจะต้องดำเนินการตามusermodคำแนะนำ ... จากนั้นรีบูตระบบของคุณมิฉะนั้นจะไม่มีผล
Mariano Ruiz

32

ประสบความสำเร็จสำหรับฉัน

sudo usermod -a -G docker $USER
reboot

5
ไม่จำเป็นต้องรีบูต เพียงออกจากระบบจากนั้นเข้าสู่ระบบอีกครั้ง ฉันกำลังพูดถึง usermod
Abdennour TOUMI

1
บน Ubuntu 18.04 ฉันต้องรีบูตเพื่อให้การตั้งค่าใช้งานได้
Nikhil

1
ใน Ubuntu 20.04 ฉันต้องการการรีบูต ปิดเซสชันไม่เพียงพอ
framontb

หรือเรียกใช้ su $ {USER} แทนที่จะออกจากระบบ
goonerify

19

2018/08/19

ฉันติดอยู่กับเรื่องนี้มาหลายวันแล้วและเนื่องจากฉันไม่พบคำตอบที่สมบูรณ์เกี่ยวกับสาเหตุและวิธีฉันจะโพสต์ข้อความหนึ่งสำหรับคนอื่น ๆ ที่สะดุดกับปัญหาเดียวกันและคำตอบจากด้านบนไม่ได้ผล

นี่คือ 3 ขั้นตอนสำคัญเมื่อใช้งาน Jenkins ภายในนักเทียบท่า:

  1. คุณเชื่อมต่อซ็อกเก็ต/var/run/docker.sockเข้ากับภาชนะเจนกินส์เพื่อให้สามารถใช้งานนักเทียบท่าจากโฮสต์ได้
  2. คุณต้องติดตั้งนักเทียบท่าภายในคอนเทนเนอร์เพื่อใช้งาน นี่เป็นบทความที่ยอดเยี่ยมและเรียบง่ายเกี่ยวกับวิธีการทำเช่นนั้น โปรดทราบว่าเวอร์ชันที่ใหม่กว่าอาจติดตั้งนักเทียบท่าไว้แล้ว
  3. คุณเรียกใช้sudo usermod -a -G docker jenkinsเพื่อเพิ่มเจนกินส์ในกลุ่มนักเทียบท่า อย่างไรก็ตามที่นี่คุณอาจพบปัญหาการอนุญาตหาก host docker และ container docker ไม่มี id กลุ่มเดียวกันดังนั้นจึงจำเป็นอย่างยิ่งที่จะต้องปรับ gid ของ docker container ให้เหมือนกับ Gid host dock

คุณสามารถทำเช่นนี้เป็นส่วนหนึ่งของการเปิดตัวสคริปต์หรือเพียงโดยใช้และทำมันด้วยตนเอง:execgroupmod -g <YOUR_HOST_DOCKER_GID> docker

นอกจากนี้อย่าเปลี่ยนการอนุญาตของ/var/run/docker.sock777 หรือสิ่งอื่น ๆ เช่นนั้นเนื่องจากเป็นความเสี่ยงด้านความปลอดภัยที่ยิ่งใหญ่คุณได้ให้สิทธิ์แก่ทุกคนในการใช้นักเทียบท่าบนเครื่องของคุณ

หวังว่านี่จะช่วยได้


1
ขอบคุณ - โปรดทราบว่าสำหรับภาพ Jenkins Docker ปัจจุบันคำสั่ง docker ได้รับการติดตั้งแล้ว (และ apt-get ไม่ใช่) จุดอื่น ๆ ของคุณ - การเพิ่ม Jenkins ไปยังกลุ่มที่เหมาะสมและมั่นใจว่า GID นั้นตรงกับโฮสต์ Docker จับได้เห็นชัดตรงเผง.
Steve Bonds

1
ช่วยชีวิตฉันด้วยปัญหารหัสกลุ่ม ขอบคุณ!
lenkovi

13

ฉันเพิ่มผู้ใช้เจนกินส์ให้กับกลุ่มรูทแล้วรีสตาร์ทเจนกินส์และมันก็เริ่มทำงานได้

sudo usermod -a -G root jenkins
sudo service jenkins restart

16
นี่เป็นวิธีปฏิบัติด้านความปลอดภัยที่ไม่ดี วิธีการที่ต้องการคือคำตอบนี้
kevindaub

11

เปลี่ยนสิทธิ์การเข้าถึงของไฟล์ docker.sock

chmod 777 /var/run/docker.sock

หรือคุณสามารถใช้sudoในการเริ่มต้นคำสั่ง

chmod 777จะอนุญาตการดำเนินการทั้งหมดสำหรับผู้ใช้ทั้งหมดในขณะที่chmod 666จะอนุญาตให้ผู้ใช้ทุกคนอ่านและเขียน แต่ไม่สามารถเรียกใช้ไฟล์ได้


นี่คือสิ่งที่ฉันต้องการขอบคุณ!
crazynx

9

เพียงเพิ่มdockerเป็นกลุ่มเสริมสำหรับjenkinsผู้ใช้

sudo usermod -a -G docker jenkins

ไม่เคยพอเมื่อใช้ภาพหางเป็นตัวแทนเจนกินส์ นั่นคือถ้าคุณJenkinsfileเริ่มต้นด้วยpipeline{agent{dockerfileหรือpipeline{agent{image:

pipeline {
    agent {
        dockerfile {
            filename 'Dockerfile.jenkinsAgent'
        }
    }
    stages {

นี่เป็นเพราะเจนกินส์ทำdocker runคำสั่งซึ่งทำให้เกิดปัญหาสามประการ

  • ตัวแทนจะ (อาจ) ไม่มีการติดตั้งโปรแกรมนักเทียบท่า
  • ตัวแทนจะไม่ได้มีการเข้าถึงซ็อกเก็ตภูตหางและเพื่อจะพยายามที่จะเรียกนักเทียบท่าในหางซึ่งจะไม่แนะนำให้ใช้
  • เจนกินส์ให้ ID ผู้ใช้ที่เป็นตัวเลขและ ID กลุ่มตัวเลขที่ Agent ควรใช้ ตัวแทนจะไม่มีกลุ่มเสริมใด ๆ เพราะdocker runไม่ได้ทำการเข้าสู่ระบบคอนเทนเนอร์ (มันเป็นเหมือนsudo)

การติดตั้ง Docker สำหรับ Agent

การทำให้โปรแกรม Docker พร้อมใช้งานภายในอิมเมจ Docker นั้นเพียงแค่ต้องการใช้ขั้นตอนการติดตั้ง Dockerใน Dockerfile ของคุณ:

# Dockerfile.jenkinsAgent
FROM debian:stretch-backports
# Install Docker in the image, which adds a docker group
RUN apt-get -y update && \
 apt-get -y install \
   apt-transport-https \
   ca-certificates \
   curl \
   gnupg \
   lsb-release \
   software-properties-common

RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
RUN add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/debian \
   $(lsb_release -cs) \
   stable"

RUN apt-get -y update && \
 apt-get -y install \
   docker-ce \
   docker-ce-cli \
   containerd.io

...

การแชร์ซ็อกเก็ต Docker daemon

ดังที่ได้กล่าวไว้ก่อนหน้าการแก้ไขปัญหาที่สองหมายถึงการเรียกใช้คอนเทนเนอร์ Jenkins Docker ดังนั้นจึงแบ่งปันซ็อกเก็ต Docker daemon กับ Docker daemon ที่อยู่นอกคอนเทนเนอร์ ดังนั้นคุณต้องบอกให้ Jenkins เรียกใช้ Docker container ด้วยการแชร์ดังนี้:

pipeline {
    agent {
        dockerfile {
            filename 'Dockerfile.jenkinsAgent'
            args '-v /var/run/docker.sock:/var/run/docker.sock'
        }
    }

การตั้งค่า UID และ GID

การแก้ไขในอุดมคติสำหรับปัญหาที่สามจะถูกตั้งค่ากลุ่มเสริมสำหรับตัวแทน ดูเหมือนจะเป็นไปไม่ได้ การแก้ไขเดียวที่ฉันรู้คือเรียกใช้ Agent กับ Jenkins UID และ Docker GID (ซ็อกเก็ตมีสิทธิ์ในการเขียนกลุ่มและเป็นเจ้าของโดยroot.docker) แต่โดยทั่วไปแล้วคุณไม่ทราบว่า ID เหล่านั้นคืออะไร (พวกเขาถูกจัดสรรเมื่อuseradd ... jenkinsและและgroupadd ... dockerเมื่อมีการติดตั้ง Jenkins และ Docker บนโฮสต์) และคุณไม่สามารถเพียงแค่บอกเจนกินส์กับผู้ใช้jenkinsและกลุ่มdocker

args '-v /var/run/docker.sock:/var/run/docker.sock -u jenkins:docker'

เพราะนั่นบอกให้นักเทียบท่าใช้ผู้ใช้และกลุ่มที่มีชื่อjenkinsและdocker อยู่ในรูปภาพและอิมเมจ Docker ของคุณอาจไม่มีjenkinsผู้ใช้และกลุ่มและแม้ว่ามันจะไม่มีการรับประกันก็จะมี UID และ GID เดียวกัน โฮสต์และไม่มีการรับประกันว่าdockerGID จะเหมือนกัน

โชคดีที่เจนกินส์รันdocker buildคำสั่งสำหรับ Dockerfile ของคุณในสคริปต์เพื่อให้คุณสามารถใช้เวทย์มนตร์เชลล์สคริปต์เพื่อส่งผ่านข้อมูลนั้นในฐานะนักเทียบท่าสร้างอาร์กิวเมนต์:

pipeline {
    agent {
        dockerfile {
            filename 'Dockerfile.jenkinsAgent'
            additionalBuildArgs  '--build-arg JENKINSUID=`id -u jenkins` --build-arg JENKINSGID=`id -g jenkins` --build-arg DOCKERGID=`stat -c %g /var/run/docker.sock`'
            args '-v /var/run/docker.sock:/var/run/docker.sock -u jenkins:docker'
        }
    }

ที่ใช้idคำสั่งเพื่อรับUIDและGIDของjenkinsผู้ใช้และstatคำสั่งเพื่อรับข้อมูลเกี่ยวกับซ็อกเก็ต Docker

Dockerfile ของคุณสามารถใช้ข้อมูลที่จะตั้งค่าjenkinsของผู้ใช้และdockerกลุ่มตัวแทนที่ใช้groupadd, groupmodและuseradd:

# Dockerfile.jenkinsAgent
FROM debian:stretch-backports
ARG JENKINSUID
ARG JENKINSGID
ARG DOCKERGID
...
# Install Docker in the image, which adds a docker group
RUN apt-get -y update && \
 apt-get -y install \
   apt-transport-https \
   ca-certificates \
   curl \
   gnupg \
   lsb-release \
   software-properties-common

RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
RUN add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/debian \
   $(lsb_release -cs) \
   stable"

RUN apt-get -y update && \
 apt-get -y install \
   docker-ce \
   docker-ce-cli \
   containerd.io

...
# Setup users and groups
RUN groupadd -g ${JENKINSGID} jenkins
RUN groupmod -g ${DOCKERGID} docker
RUN useradd -c "Jenkins user" -g ${JENKINSGID} -G ${DOCKERGID} -M -N -u ${JENKINSUID} jenkins

นี่เป็นโซลูชันที่ครอบคลุมที่ยอดเยี่ยมและเป็นวิธีเดียวที่ใช้ได้ผลสำหรับฉันเมื่อใช้ซ็อกเก็ตนักเทียบท่าที่แชร์กับนักเทียบท่าผ่าน dockerfile ควรเป็นโพสต์บล็อกของตัวเอง ขอบคุณสำหรับสิ่งนี้!
Greg Olmstead

ดูเหมือนว่าคุณจะผ่านไปได้-u jenkins:$(getent group docker | cut -d: -f3)ไหม
Gillespie

เมื่อผ่าน args อาจจะดีกว่าที่จะเปลี่ยนบรรทัดต่อไปนี้: args '-v /var/run/docker.sock:/var/run/docker.sock -u jenkins:docker'โดยargs '-v /var/run/docker.sock:/var/run/docker.sock -u jenkins:jenkins --group-add docker' เมื่อผ่าน -u jenkins: docker คุณเปลี่ยนกลุ่มผู้ใช้หลักซึ่งหมายความว่าเมื่อผู้ใช้เขียนไฟล์ให้พูดในพื้นที่ทำงานมันจะตั้งค่าไฟล์ ผู้ใช้กับเจนกินส์และกลุ่มที่จะเทียบท่า ซึ่งอาจไม่ใช่สิ่งที่เราตั้งใจ
Nicolas Forney

8

ฉันมี Jenkins ทำงานอยู่ใน Docker และเชื่อมต่อ Jenkins กำลังใช้ซ็อกเก็ต Docker จากเครื่องโฮสต์ Ubuntu 16.04 ผ่านไดรฟ์ข้อมูลไปยัง /var/run/docker.sock

สำหรับฉันทางออกคือ:

1) ข้างใน Docker container ของ Jenkins ( docker exec -it jenkins bashบนเครื่องโฮสต์)

usermod -a -G docker jenkins
chmod 664 /var/run/docker.sock
service jenkins restart (or systemctl restart jenkins.service)
su jenkins

2) บนเครื่องโฮสต์:

sudo service docker restart

664 หมายถึง - อ่านและเขียน (แต่ไม่ได้ดำเนินการ) สำหรับเจ้าของและผู้ใช้จากกลุ่ม


นี่เป็นทางออกเดียวที่ไม่จำเป็นต้องเข้าสู่ระบบ / เข้าสู่ระบบเช่นวิธีการแก้ปัญหาที่ทำงานเมื่อพยายามเรียกใช้ในเชลล์สคริปต์
PV

3

ในขณะที่ทำการตั้งค่าการผลิตฉันได้รับอนุญาตฉันพยายามแก้ไขปัญหาด้านล่างเพื่อแก้ไขปัญหา

ข้อความผิดพลาด

ubuntu@node1:~$ docker run hello-world
docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.38/containers/create: dial unix /var/run/docker.sock: connect: permission denied.
See 'docker run --help'.

การแก้ไข:สิทธิ์ของซ็อกเก็ตที่ระบุในข้อความแสดงข้อผิดพลาด /var/run/docker.sock:

ubuntu@ip-172-31-21-106:/var/run$ ls -lrth docker.sock
srw-rw---- 1 root root 0 Oct 17 11:08 docker.sock
ubuntu@ip-172-31-21-106:/var/run$ sudo chmod 666 /var/run/docker.sock
ubuntu@ip-172-31-21-106:/var/run$ ls -lrth docker.sock
srw-rw-rw- 1 root root 0 Oct 17 11:08 docker.sock

หลังจากเปลี่ยนแปลงการอนุญาตสำหรับ docket.sock จากนั้นดำเนินการคำสั่งด้านล่างเพื่อตรวจสอบสิทธิ์

ubuntu@ip-172-31-21-106:/var/run$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:c3b4ada4687bbaa170745b3e4dd8ac3f194ca95b2d0518b417fb47e5879d9b5f
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

2

ในกรณีของฉันมันไม่เพียง แต่เพิ่มjenkinsผู้ใช้ในdockerกลุ่ม แต่ทำให้กลุ่มนั้นเป็นกลุ่มหลักของjenkinsผู้ใช้

# usermod -g docker jenkins
# usermod -a -G jenkins jenkins

อย่าลืมเชื่อมต่อโหนดทาสเจนกินส์หรือรีสตาร์ทเซิร์ฟเวอร์เจนกินส์ขึ้นอยู่กับกรณีของคุณ


2

2019/02/16

ขั้นตอนส่วนใหญ่เหมือนกันสำหรับฉันตามที่คนอื่นเขียน อย่างไรก็ตามฉันไม่สามารถเพิ่มเจนกินส์ให้กับนักเทียบท่ากลุ่มโดยใช้ usermod ด้วยวิธีแก้ปัญหาที่กล่าวถึง

ฉันลองคำสั่งต่อไปนี้จากhost dockerและจากcontainer docker running :

sudo usermod -a -G docker jenkins

(ฉันเข้าสู่container docker runningโดยใช้คำสั่งต่อไปนี้จากhost docker :

docker exec -t -i my_container_id_or_name /bin/bash

)

ได้รับจากโฮสต์นักเทียบท่า :

usermod: ไม่มี 'jenkins' ของผู้ใช้

ได้รับจากตู้เทียบท่า :

เราเชื่อว่าคุณได้รับการบรรยายตามปกติจากผู้ดูแลระบบท้องถิ่น มันมักจะเดือดลงไปในสามสิ่งนี้:

#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.

[sudo] รหัสผ่านสำหรับเจนกินส์:

ฉันไม่รู้รหัสผ่าน

โดยไม่ต้องมีsudoส่วนหนึ่งของคำสั่งในคอนเทนเนอร์นักเทียบท่าฉันได้รับ:

usermod: การอนุญาตถูกปฏิเสธ usermod: ไม่สามารถล็อค / etc / passwd; ลองอีกครั้งในภายหลัง

การแก้ไข: ฉันเข้าสู่คอนเทนเนอร์นักเทียบท่าที่กำลังเรียกใช้จากโฮสต์นักเทียบเคียงด้วยคำสั่งต่อไปนี้:

docker exec -t -i -u root my_container_id_or_name /bin/bash

ตอนนี้ฉันป้อนเป็นrootและออกคำสั่งต่อไปนี้:

usermod -a -G docker jenkins

จากโฮสต์ hosterฉันรีสตาร์ทคอนเทนเนอร์ docker ที่รันด้วยคำสั่งต่อไปนี้:

docker restart my_container_id_or_name

หลังจากนั้นฉันเริ่มงานเจนกินส์และมันก็ประสบความสำเร็จ

ฉันใช้ผู้ใช้รูทเพื่อออกusermodคำสั่งสำหรับผู้ใช้jenkinsเท่านั้น


2

2019/05/26

สิ่งนี้ได้ผลสำหรับฉัน!

ตัวอย่างนักเทียบท่าประกอบ:

version: "3"
services:
  jenkins:
    image: jenkinsci/blueocean
    privileged: true
    ports:
      - "8080:8080"
    volumes:
      - $HOME/learning/jenkins/jenkins_home:/var/jenkins_home
    environment:
      - DOCKER_HOST=tcp://socat:2375
    links:
      - socat

  socat:
     image: bpack/socat
     command: TCP4-LISTEN:2375,fork,reuseaddr UNIX-CONNECT:/var/run/docker.sock
     volumes:
        - /var/run/docker.sock:/var/run/docker.sock
     expose:
        - "2375"

2

ฉันประสบปัญหาคล้ายกันซึ่งเป็นปัญหาสิทธิ์และสาเหตุของปัญหานี้เป็นเพราะ Docker daemon / เซิร์ฟเวอร์ทำงานเป็นrootผู้ใช้เสมอและต้องการให้คุณนำหน้าคำสั่ง docker sudoเสมอ

Docker daemon เชื่อมโยงกับซ็อกเก็ต Unix แทนพอร์ต TCP โดยค่าเริ่มต้นแล้วซ็อกเก็ต Unix จะเป็นของผู้ใช้rootและผู้ใช้รายอื่นสามารถเข้าถึงได้โดยใช้sudoเท่านั้น

ในการแก้ไขปัญหานี่คือสิ่งที่ใช้ได้กับฉัน:

ก่อนอื่นตรวจสอบว่าคุณมีกลุ่มนักเทียบท่าที่สร้างไว้แล้วหรือไม่:

cat /etc/group

หากคุณไม่พบdockerในรายการที่ปรากฏขึ้นคุณจะต้องสร้าง:

sudo groupadd docker

ถัดไปยืนยันของคุณuserและของคุณgroupโดยใช้คำสั่งด้านล่าง:

cat /etc/group

เลื่อนดูเพื่อดูกลุ่มนักเทียบท่า ควรเป็นรูปแบบนี้

docker:x:140:promisepreston

ที่dockerเป็นของฉันgroupและpromiseprestonฉันuser

ตอนนี้เราสามารถเพิ่มผู้ใช้ของคุณในกลุ่มนักเทียบท่า

สำหรับไฟล์ Docker Container เท่านั้น:

คัดลอกและเรียกใช้คำสั่งด้านล่างในเทอร์มินัลของคุณตามที่ระบุไว้โดยไม่ต้องแก้ไขในอย่างไรก็ตามไม่ว่ารูปภาพ / คอนเทนเนอร์ / คำสั่งของนักเทียบท่าที่คุณต้องการเรียกใช้หรือกำลังพยายามเรียกใช้

sudo usermod -aG docker $USER

หลังจากเรียกใช้คำสั่งด้านบนคุณจะต้องออกจากระบบและกลับเข้าสู่ระบบเพื่อให้ความเป็นสมาชิกกลุ่มของคุณได้รับการประเมินอีกครั้ง อย่างไรก็ตามบน Linux คุณสามารถเรียกใช้คำสั่งต่อไปนี้ด้านล่างเพื่อเปิดใช้งานการเปลี่ยนแปลงในกลุ่ม ( คัดลอกและเรียกใช้คำสั่งด้านล่างในเทอร์มินัลของคุณตามที่ระบุไว้โดยไม่ต้องแก้ไขในอย่างไรก็ตามโดยไม่คำนึงถึง คุณต้องการเรียกใช้หรือพยายามเรียกใช้หรือกำลังแยกปัญหาการอนุญาต ):

newgrp docker 

ตอนนี้คุณสามารถตรวจสอบว่าคุณสามารถเรียกใช้คำสั่งนักเทียบท่าโดยไม่มีสิทธิ์ sudo โดยการเรียกใช้คำสั่งที่ทำให้เกิดปัญหาสิทธิ์อีกครั้งพูด ( แทนที่my-commandด้วยชื่อของภาพ / ภาชนะ / คำสั่งของคุณ ):

docker run my-command

สำหรับไฟล์ระบบไฟล์ Docker และ Local:

หากคุณมีสำเนาของไฟล์ในระบบไฟล์ในเครื่องของคุณคุณสามารถเปลี่ยนความเป็นเจ้าของไดเรกทอรีแอปพลิเคชันที่จัดเก็บไฟล์แอปพลิเคชันโดยใช้รูปแบบนี้:

sudo​​ ​ chown​​ ​ <your_user>:<your_group>​​ ​ -R​​ my-app-directory/

ดังนั้นในกรณีของฉันมันจะเป็น:

sudo chown promisepreston:docker -R my-app-directory/

หมายเหตุ:โปรดเรียกใช้คำสั่งนี้ภายในไดเรกทอรีหลักซึ่งเป็นที่เก็บไดเรกทอรีของแอปพลิเคชัน

นั่นคือทั้งหมดที่

ฉันหวังว่านี่จะช่วยได้



1

ฉันกำลังเรียกใช้เจนกินส์อยู่ในคอนเทนเนอร์นักเทียบท่า ทางออกที่ง่ายที่สุดสำหรับฉันคือการสร้างภาพที่กำหนดเองที่ตั้งค่า GID แบบไดนามิกเช่น:

FROM jenkins/jenkins:lts
...
CMD DOCKER_GID=$(stat -c '%g' /var/run/docker.sock) && \
    groupadd -for -g ${DOCKER_GID} docker && \
    usermod -aG docker jenkins && \
    sudo -E -H -u jenkins bash -c /usr/local/bin/jenkins.sh

ดู: https://github.com/jenkinsci/docker/issues/263

หรือคุณสามารถเปิดเจนกินส์ด้วยตัวเลือกต่อไปนี้:

-v /var/run/docker.sock:/var/run/docker.sock \
-u jenkins:$(getent group docker | cut -d: -f3)

สิ่งนี้จะถือว่าภาพเจนกินส์ของคุณติดตั้งไคลเอนต์นักเทียบท่า ดู: https://getintodevops.com/blog/the-simple-way-to-run-docker-in-docker-for-ci


1

หากคุณอาจได้รับข้อผิดพลาดเช่นด้านล่าง

Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock

หรือ

level=error msg="failed to dial gRPC: cannot connect to the Docker daemon. Is 'docker daemon' running on this host?: dial unix /var/run/docker.sock: connect: permission denied"

เพียงลองใช้คำสั่งต่อไปนี้

$ sudo su - jenkins
$ sudo usermod -a -G docker $USER
$ sudo chown jenkins:docker /var/run/docker.sock

`sudo usermod -a -G docker $ USER 'จะขอรหัสผ่านของเจนกินส์ไม่แน่ใจว่ารหัสผ่านของผู้ใช้คืออะไร
3lokh

ฉันคิดว่าคุณควรให้สิทธิ์ sudo แก่ผู้ใช้ Jenkins หรือคุณสามารถลองใช้คำสั่งต่อไปนี้ในผู้ใช้รูทusermod -a -G docker jenkinsและchown jenkins:docker /var/run/docker.sock
lakshmikandan

คุณไม่ควรเปลี่ยนความเป็นเจ้าของซ็อกเก็ตเป็นเจนกินส์ และคุณควรเรียกใช้ sudo เหมือนที่ผู้ใช้ทั่วไปมีสิทธิ์เข้าถึง sudo ไม่ใช่ jenkins คำตอบนี้เพิ่มไปยังคำตอบที่ยอมรับ?
Jim Stewart

1

ฉันกำลังใช้อิมเมจเทียบท่า jenkins อย่างเป็นทางการ ( https://hub.docker.com/r/jenkins/jenkins ) แต่ฉันคิดว่าวิธีนี้ใช้ได้กับกรณีส่วนใหญ่ที่เราต้องการเรียกใช้ Docker ภายในคอนเทนเนอร์ Docker

วิธีที่แนะนำสำหรับการใช้ Docker ภายในคอนเทนเนอร์ Docker คือการใช้ Docker deamon ของระบบโฮสต์ บทความดีดีเกี่ยวกับว่าhttps://itnext.io/docker-in-docker-521958d34efd

ความลับในการจัดการกับปัญหาที่ได้รับอนุญาตซึ่งคำถามนี้เป็นเรื่องเกี่ยวกับคือการเพิ่มสิทธิ์สำหรับผู้ใช้ของภาชนะในภาชนะที่ไม่ได้ระบบโฮสต์ เฉพาะผู้ใช้รูทเท่านั้นที่ได้รับอนุญาตให้ทำเช่นนั้นตามค่าเริ่มต้น

docker exec -it -u root <container-name> bash
usermod -a -G docker <username>

จะทำมัน อย่าลืมรีสตาร์ทคอนเทนเนอร์

ฉันเดาวิธีที่ง่ายที่สุดในการบรรลุเป้าหมายนี้คือการสร้าง Dockerfile ที่กำหนดเอง:

# Official jenkins image
FROM jenkins/jenkins:lts
# Swith to root to be able to install Docker and modify permissions
USER root
RUN apt-get update
# Install docker
RUN curl -sSL https://get.docker.com/ | sh
# Add jenkins user to docker group
RUN usermod -a -G docker jenkins
# Switch back to default user
USER jenkins

# Bild the image:
# sudo docker build -t yourusername/imagename .
# Run the image and mount with the followin bind mount option:
# sudo docker run --name imagename -d -p8080:8080 -v /var/run/docker.sock:/var/run/docker.sock yourusername/imagename

ไม่จำเป็นต้องติดตั้งนักเทียบท่าทั้งตัวในภาพเจนกินส์ดูคำตอบของฉัน
deFreitas

1

หากใครบางคนยังคงประสบปัญหาในเครื่องของพวกเขา (Ubuntu) ให้ลองคำสั่งด้านล่าง:

sudo chmod 666 /var/run/docker.sock

1

ในกรณีของฉันนี้จะทำงานได้สำเร็จ นำทาง repo ท้องถิ่นของคุณและป้อนคำสั่งนี้

sudo chmod 666 /var/run/docker.sock

0

ฉันใช้เซิร์ฟเวอร์ที่เซิร์ฟเวอร์เจนกินส์ทำงานอยู่

sudo setfacl -m user:tomcat:rw /var/run/docker.sock

และจากนั้นเรียกใช้แต่ละภาชนะนักเทียบท่าด้วย

-v /var/run/docker.sock:/var/run/docker.sock

การใช้ setfacl นั้นเป็นตัวเลือกที่ดีกว่าและไม่จำเป็นต้องใช้ "-u user" จากนั้นคอนเทนเนอร์จะรันเป็นผู้ใช้เดียวกันกับที่ใช้งานเจนกินส์ แต่ฉันขอขอบคุณข้อเสนอแนะใด ๆ จากผู้เชี่ยวชาญด้านความปลอดภัย


0

ใช้ด้านล่าง dockerfile

FROM jenkins/jenkins

USER root

# Install Docker
RUN apt-get update && \
    apt-get -y install apt-transport-https \
    ca-certificates \
    curl \
    gnupg2 \
    software-properties-common && \
    curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg > /tmp/dkey; apt-key add /tmp/dkey && \
    add-apt-repository \
    "deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
    $(lsb_release -cs) \
    stable" && \
    apt-get update && \
    apt-get -y install docker-ce


# Compose
RUN curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose



RUN usermod -aG docker jenkins
RUN usermod -aG root jenkins

USER jenkins

0

ในกรณีของฉันมันเป็นเพียงการเริ่มบริการนักเทียบท่า:

sudo service docker start

0

มักต้องรีบูตเพื่อให้มีผลกับกลุ่มผู้ใช้และผู้ใช้ใหม่


0

หากคุณใช้งาน Jenkins ภายในคอนเทนเนอร์ของนักเทียบท่าและ Jenkins ของคุณกำลังเชื่อมโยงไปยังโฮสต์ docker คุณสามารถแก้ไขได้โดยใช้ Dockerfile ด้านล่าง:

FROM jenkins/jenkins:2.179
USER root
RUN groupadd docker && usermod -a -G docker jenkins
USER jenkins 

-6

บางทีคุณควรรันนักเทียบท่าด้วยตัวเลือก "-u root" ตั้งแต่ต้น

อย่างน้อยก็แก้ปัญหาของฉัน


1
rootจากนั้นคุณอาจได้รับไฟล์ที่ถูกสร้างขึ้นเป็นผู้ใช้ อย่างน้อยนี่คือสิ่งที่เกิดขึ้นกับฉันด้วย Docker 18.06.1
Ernst de Haan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.