Docker:尝试连接到unix:///var/run/docker.sock上的Docker守护进程套接字时获得的权限被拒绝


175

我是Docker的新手。我只是尝试在Jenkins的本地计算机(Ubuntu 16.04)中使用docker。

我使用以下管道脚本配置了新作业。

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

但是它失败并出现以下错误。

在此处输入图片说明


1
它是单片Jenkins还是具有主从设置?检查与哪个用户一起执行docker inspect命令。查看/var/run/docker.sock是否具有对组的RW访问权限。
拉玛·卡玛特


Answers:


293

jenkins需要将该用户添加到组中docker

sudo usermod -a -G docker jenkins

然后重新启动詹金斯。

编辑

如果由于从Docker收到此消息而遇到堆栈溢出的问题,但您没有使用jenkins,则错误很可能是相同的:您的非特权用户不属于docker组。

你可以做:

sudo usermod -a -G docker alice

或您的用户名是什么。

您可以在最后检查它,grep docker /etc/group然后看到类似以下内容的内容:

docker:x:998:alice

在其中一行中。

然后将您的用户组ID更改为docker

newgrp docker

88
并重新登录用户
Ilya Kolesnikov

8
好的答案,但更笼统地说,我们可以这样做: sudo usermod -a -G docker $USER然后注销或重新启动。链接
Julien Nyambal '18

10
我必须重新启动服务器才能使其正常工作。
etagwerker

3
我必须断开/重新连接我的节点才能正常工作(它们通过ssh连接)
GaspardP

28
无需再次登录,只需newgrp docker在同一终端会话中使用即可。
C14L

69

我的第一个解决方案是:

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用户jenkins”。
具有讽刺意味的

我知道它已被重置,但没有将docker.sock权限设置为777。这使您系统上的任何人都成为root。他们能够与Docker对话并创建不受限制的特权容器。
Lance Hudson

3
尽管这对于作者乃至我来说都是可行的,但授予docker.sock文件访问权限并不是最佳的解决方案,您只需要执行usermod...指令,然后重新启动系统,否则就不会生效
Mariano Ruiz

32

对我来说成功

sudo usermod -a -G docker $USER
reboot

4
无需重启。只需注销然后再次登录。我说的是usermod
Abdennour TOUMI,

1
在Ubuntu 18.04上,我必须重新启动才能使设置起作用。
Nikhil

1
在Ubuntu 20.04上,我需要重启。关闭会话不够。
framontb

或者运行su $ {USER}而不是注销
goonerify

19

2018-08-19

我已经在这个问题上待了好几天了,因为我还没有找到关于原因和方式的完整答案,因此我将为其他偶然发现相同问题并且上面的答案无效的人发布一个答案。

这些是在docker中运行Jenkins的3个关键步骤:

  1. 您可以将套接字安装/var/run/docker.sock到jenkins容器,以便能够从主机使用docker。
  2. 您必须在容器内安装docker才能使用它。是一篇关于如何执行操作的出色而简单的文章。请注意,较新的版本可能已经安装了docker
  3. 您运行sudo usermod -a -G docker jenkins为了添加詹金斯到码头工人小组。但是,如果主机泊坞窗和容器泊坞窗不具有相同的组ID,可能会遇到权限问题,因此将容器泊坞窗的GID调整为与主机泊坞窗GID相同是非常重要的

您可以将其作为启动脚本的一部分,也可以直接使用exec并手动进行:groupmod -g <YOUR_HOST_DOCKER_GID> docker

另外,请勿/var/run/docker.sock将777或类似内容的权限更改为安全隐患,因为这实际上是在向所有人授予在计算机上使用docker的权限

希望这可以帮助


1
谢谢-请注意,对于当前的Jenkins Docker映像,已经安装了docker命令(而apt-get尚未安装。)其他要点-将Jenkins添加到正确的组,并确保GID与Docker主机中的GID匹配,请保留发现。
史蒂夫·邦兹

1
通过组ID问题挽救了我的性命。谢谢!
lenkovi

13

我将jenkins用户添加到根组,然后重新启动jenkins,它开始工作。

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

16
这是一种不良的安全做法。首选方法是此答案
kevindaub

10

更改docker.sock文件的访问权限

chmod 777 /var/run/docker.sock

或者您可以sudo在命令开头使用。

chmod 777将允许所有用户执行所有操作,同时chmod 666将允许所有用户读取和写入但无法执行文件。


这就是我需要的,谢谢!
crazynx

9

简单地添加docker作为补充组jenkins用户

sudo usermod -a -G docker jenkins

当使用Docker映像作为Jenkins Agent时,并不总是足够的。也就是说,如果您Jenkinsfilepipeline{agent{dockerfile或开头pipeline{agent{image

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

这是因为詹金斯执行了一条docker run命令,这导致了三个问题。

  • 该代理将(可能)未安装Docker程序。
  • 代理将无权访问Docker守护程序套接字,因此将尝试运行Docker-in-Docker,不建议这样做
  • Jenkins给出了代理应使用的数字用户ID和数字组ID。代理将没有任何补充组,因为docker run它不会登录到容器(更像是sudo)。

为代理安装Docker

要使Docker程序在Docker映像中可用,仅需要在Dockerfile中运行Docker安装步骤

# 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守护进程套接字

正如以前所说,定影所以这股与泊坞守护进程是多克尔守护插座运行詹金斯多克尔容器的第二个问题的装置的容器。因此,您需要告诉Jenkins使用该共享来运行Docker容器,因此:

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

设置UID和GID

解决第三个问题的理想方法是为代理设置补充组。这似乎不可能。我知道的唯一解决方法是使用Jenkins UID和Docker GID运行代理(套接字具有组写许可权,并由拥有root.docker)。但是总的来说,您不知道这些ID是什么(当在主机上安装Jenkins和Docker 时,它们是在useradd ... jenkinsgroupadd ... docker时分配的)。而且您不能简单地将詹金斯告诉用户user jenkins和groupdocker

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

因为告诉泊坞窗使用的是被命名为用户和组jenkins,并docker 在图像中,和你的多克尔图像可能不具备jenkins用户和组,即使它就没有保证,将有相同的UID和GID为主机,并且同样无法保证dockerGID相同

幸运的是,Jenkins docker build在脚本中运行Dockerfile 的命令,因此您可以做一些shell脚本魔术来作为Docker构建参数传递这些信息:

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命令来获取UIDGID的的jenkins用户和stat命令获取有关Docker套接字的信息。

您Dockerfile可以使用这些信息来建立一个jenkins用户和docker组的代理,使用groupaddgroupmod以及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与Docker共享给docker的docker socket时唯一对我有用的解决方案。它应该是自己的博客文章。谢谢你!
格雷格·奥尔姆斯特德

好像你可以通过-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时,您更改主要用户组,这意味着当用户写入文件时(例如在工作空间中),它将设置文件用户使用jenkins,组使用docker。这可能不是我们想要的。
Nicolas Forney

8

我有在Docker中运行的Jenkins,并且已连接Jenkins正在使用从主机Ubuntu 16.04通过卷到/var/run/docker.sock的Docker套接字。

对我来说解决方案是:

1)在Jenkins的Docker容器内部(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 手段-读取和写入(但不执行)组中的所有者和用户。


这是唯一不需要登录/登录的解决方案,即,尝试在Shell脚本中运行该解决方案时可以使用。
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

根据您的情况,不要忘记重新连接jenkins从节点或重新启动jenkins服务器。


2

2019-02-16

对我来说,大多数步骤与其他步骤相同。 但是,我无法通过提到的解决方案使用usermod将jenkins添加到组docker。

我从docker主机正在运行的docker容器中尝试了以下命令:

sudo usermod -a -G docker jenkins

(我从docker主机使用以下命令输入了正在运行的docker容器

docker exec -t -i my_container_id_or_name /bin/bash

Docker主机收到:

usermod:用户'jenkins'不存在

码头集装箱收到:

我们相信您已经从本地系统管理员那里获得了常规讲座。通常可以归结为以下三点:

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

jenkins的[sudo]密码:

我不知道密码。

没有sudo命令的一部分,我在docker容器中收到了:

usermod:权限被拒绝。usermod:无法锁定/ etc / passwd;稍后再试。

解决方案: 我使用以下命令从Docker主机输入了正在运行的Docker容器

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

现在,我以root身份输入,并发出以下命令:

usermod -a -G docker jenkins

然后,从docker主机,使用以下命令重新启动正在运行的docker容器

docker restart my_container_id_or_name

之后,我开始了詹金斯的工作,并成功地完成了工作。

我仅使用root用户为该用户发出usermod命令jenkins


2

2019-05-26

这个对我有用!

docker-compose示例:

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守护进程/服务器始终以root用户身份运行,并且希望您始终以docker命令开头sudo

Docker守护程序绑定到Unix套接字而不是TCP端口。默认情况下,Unix套接字归用户所有root,其他用户只能使用sudo

为了解决这个问题,这对我有用:

首先,检查您是否已经创建了一个码头工人组:

cat /etc/group

如果docker在显示的列表中找不到,则需要创建一个:

sudo groupadd docker

接下来,使用以下命令确认您user和您group的:

cat /etc/group

滚动查看docker组。应该是这种格式

docker:x:140:promisepreston

docker我的group和在哪里promiseprestonuser

现在我们可以将您的用户添加到docker组中

仅适用于Docker容器文件:

无论您要运行的,正在尝试运行的docker映像/容器/命令是什么,还是正在引起权限问题,无论在终端中准确地按照以下说明复制并运行以下命令,无论如何都无需对其进行修改:

sudo usermod -aG docker $USER

运行上面的命令后,您需要注销并重新登录,以便重新评估您的组成员身份。但是,在Linux上,您也可以在下面运行以下命令来激活对组的更改(无论如何,无论您使用的是什么docker image / container / command,都可以按照以下说明精确复制并在终端中运行以下命令,而无需对其进行修改:您要运行或正在尝试运行或正在引起权限问题):

newgrp docker 

现在,您可以通过再次运行导致权限问题的命令来验证是否可以在没有sudo权限的情况下运行docker命令,例如(my-command图像/容器/命令的名称替换):

docker run my-command

对于Docker和本地文件系统文件:

如果在本地文件系统上有文件的副本,则可以使用以下格式更改存储应用程序文件的应用程序目录的所有权:

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

所以对于我来说,它将是:

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

注意:请在包含应用程序目录的父目录中运行此命令。

就这样。

我希望这有帮助


1
sudo usermod -a -G docker jenkins
sudo service jenkins restart

1

我在Docker容器中运行Jenkins。对我来说,最简单的解决方案是制作一个可动态设置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

或者,您可以使用以下选项启动jenkins:

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

假设您的jenkins映像已安装docker客户端。参见: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将询问jenkins的密码,不确定用户密码是什么。
3lokh

我认为您应该为Jenkins用户授予sudo权限。或者您可以在root用户中尝试使用以下命令,usermod -a -G docker jenkins以及chown jenkins:docker /var/run/docker.sock
lakshmikandan19年

您不应该将套接字的所有权更改为jenkins。而且您应该以普通用户具有sudo访问权限的身份运行sudo,而不是以jenkins身份运行。这个答案对接受的答案有什么作用?
吉姆·斯图尔特

1

我正在使用官方的詹金斯码头工人镜像(https://hub.docker.com/r/jenkins/jenkins),但我认为该解决方案适用于我们要在Docker容器中运行Docker的大多数用例。

在Docker容器内使用Docker的推荐方法是使用主机系统的Docker守护进程。关于此的好文章:https : //itnext.io/docker-in-docker-521958d34efd

解决此问题所涉及的权限问题的秘诀是在容器内而不是主机系统内为容器的用户添加权限。默认情况下,只有root用户有权执行此操作,因此

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

无需在Jenkins映像上安装整个
docker


1

就我而言,这将成功进行。浏览您的本地仓库,然后输入此命令。

sudo chmod 666 /var/run/docker.sock

0

在运行Jenkins的服务器上,我使用了

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

然后使用以下命令运行每个docker容器

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

使用setfacl似乎是一个更好的选择,并且不需要“ -u用户”。然后,这些容器将以运行Jenkins的同一用户身份运行。但是,我将不胜感激安全专家的任何反馈。


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

通常需要重新启动才能对新用户组和用户生效。


0

如果您在Docker容器中运行Jenkins,并且您的Jenkins链接到主机docker,则可以通过以下Dockerfile修复此问题:

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

-6

也许您应该从一开始就使用选项-u root运行docker

至少那解决了我的问题


1
然后,您可能会获得以user身份创建的文件root。至少这就是我使用Docker 18.06.1发生的事情。
恩斯特·德·哈恩
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.