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

时间:2017-12-17 11:08:23

标签: docker jenkins jenkins-pipeline

我是码头工人的新手。我只是尝试在我的本地机器(Ubuntu 16.04)中使用Docker和Jenkins。

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

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

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

enter image description here

30 个答案:

答案 0 :(得分:121)

用户jenkins需要添加到论坛docker

sudo usermod -a -G docker jenkins

然后重新启动Jenkins。

修改

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

你可以这样做:

sudo usermod -a -G docker alice

或您的用户名。

你可以在cat /etc/group结束时查看它并看到这样的东西:

docker:x:998:alice

在其中一行中。

正如Ilya Kolesnikov在评论中所说,重新登录!

答案 1 :(得分:22)

我的第一个解决方案是:

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

但是他们都没有为我工作,我试过了:

chmod 777 /var/run/docker.sock

这有效,但我不知道这是不是正确的电话。

答案 2 :(得分:16)

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

chmod 777 /var/run/docker.sock

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

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

答案 3 :(得分:12)

对我来说成功

COLOR_FormatYUV420SemiPlanar

答案 4 :(得分:11)

我将jenkins用户添加到root组并重新启动jenkins并开始工作。

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

答案 5 :(得分:9)

2018-08-19

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

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

  1. 您可以将套接字/var/run/docker.sock安装到jenkins容器上,以便能够从主机使用docker。
  2. 您必须在容器内安装docker才能使用它。 This是一篇很棒的简单文章。请注意,较新的版本可能已经安装了Docker
  3. 您运行sudo usermod -a -G docker jenkins以便将詹金斯添加到docker组。但是,如果主机docker和容器docker没有相同的组ID,则可能会遇到权限问题,因此调整容器docker的gid与主机docker gid相同非常重要。 / strong>

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

此外,请勿将/var/run/docker.sock的权限更改为777或类似的东西,因为这会带来很大的安全风险。

希望这会有所帮助

答案 6 :(得分:6)

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

对我而言,解决方案是:

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表示 - 对组中的所有者和用户进行读写(但不执行)。

答案 7 :(得分:2)

步骤1 :将用户名添加到docker组中:

sudo usermod -a -G docker $USER

然后注销并再次登录。

步骤2 :然后更改docker组ID:

newgrp docker

答案 8 :(得分:2)

Simplydocker用户添加jenkins作为supplementary group

sudo usermod -a -G docker jenkins
将Docker映像用作Jenkins Agent时,

并不总是足够的。也就是说,如果您的Jenkinsfilepipeline{agent{dockerfilepipeline{agent{image开头:

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

这是因为Jenkins执行了docker run命令,这导致了三个问题。

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

为代理安装Docker

要使Docker映像中的Docker程序可用,只需要在Dockerfile中运行Docker installation steps

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

has been said before一样,解决第二个问题意味着运行Jenkins Docker容器,以便它与容器 之外的Docker守护程序共享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是什么(当useradd ... jenkinsgroupadd ... docker在主机上安装Jenkins和Docker时运行时,它们会被分配)。而且,您不能简单地将Jenkins告知用户用户jenkins和组docker

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

因为告诉Docker在镜像中使用名为jenkinsdocker 的用户和组 ,并且您的Docker镜像可能没有jenkins用户和组,并且即使拥有该用户和组,也无法保证它具有与主机相同的UID和GID,并且同样不能保证docker GID相同

幸运的是,Jenkins在脚本中为Dockerfile运行了docker build命令,因此您可以做一些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命令获取jenkins用户的UIDGID,并使用stat命令获取有关Docker套接字的信息。

您的Dockerfile可以使用该信息,通过groupaddgroupmoduseradd来为代理设置jenkins用户和docker组:

# 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

答案 9 :(得分:2)

在进行生产配置时,出现权限问题。我尝试了以下解决方案来解决该问题。

错误消息

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/

答案 10 :(得分:1)

我遇到了类似的问题,这是一个权限问题,该问题的原因是因为Docker守护程序/服务器始终以root用户身份运行,并且希望您始终在docker命令前加上sudo

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

要解决此问题,这对我有用:

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

cat /etc/group

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

sudo groupadd docker

接下来,使用以下命令确认您的usergroup

cat /etc/group

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

docker:x:140:promisepreston

其中docker是我的group,而promisepreston是我的user

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

仅适用于Docker容器文件:

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

sudo usermod -aG docker $USER

运行上述命令后,您需要注销并重新登录,以便重新评估组成员身份。但是,在Linux上,您也可以在下面运行以下命令来激活对组的更改(在终端中复制并运行下面的命令以确切地声明该命令,而无论如何都无需对其进行修改,无论docker映像/容器如何/您要运行或正尝试运行或正在引起权限问题的命令):

newgrp docker 

您现在可以通过运行再次引起权限问题的命令来验证是否可以在没有sudo权限的情况下运行docker命令,例如,({strong>用图像/容器/命令的名称替换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/

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

仅此而已。

我希望这会有所帮助

答案 11 :(得分:1)

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

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

答案 12 :(得分: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

答案 13 :(得分:1)

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

答案 14 :(得分:1)

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'不存在

docker容器接收:

  

我们相信您已收到本地系统的常规讲座   管理员。通常可以归结为以下三点:

#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 host 输入了正在运行的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命令。

答案 15 :(得分:1)

在我的情况下,不仅需要将jenkins用户添加到docker组中,而且还应将该组设置为jenkins用户的主要组。

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

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

答案 16 :(得分:0)

就我而言,这将成功运行。 浏览您的本地存储库并输入此命令。

sudo chmod 666 /var/run/docker.sock

答案 17 :(得分:0)

我无需更改本地 unix 套接字 /var/run/docker.sock 上的权限即可完成这项工作。我要做的是在构建代理节点上启用 tcp 连接,然后在 Jenkins 云配置中指定 docker 主机。

假设您使用的是 aws 映像,ssh 到您的构建代理节点并使用 /etc/sysconfig/docker 文件启用 tcp 端口

添加 -H tcp://0.0.0.0:2376 选项。

# Additional startup options for the Docker daemon, for example:
# OPTIONS="--ip-forward=true --iptables=true"
# By default we limit the number of open files per container
OPTIONS="-H tcp://0.0.0.0:2376 --default-ulimit nofile=1024:4096"

确保使用 sudo service docker restart

重新启动守护进程

最后需要通过云节点配置中配置的DOCKER_HOST环境变量告诉Jenkins默认使用tcp。请注意,这不是 Jenkins 管道环境中的配置。

导航到 Jenkins -> 管理 Jenkins -> 管理云和节点 -> 一些配置 -> 节点属性 -> 环境变量

然后添加您的 DOCKER_HOST 环境变量。 enter image description here

注意:我正在通过 ssh 使用 Launch 代理来完成这项工作。

答案 18 :(得分:0)

除了将用户添加到docker组并尝试该线程中提到的所有内容外,我还花了一段时间才意识到我必须重新启动终端,然后重新登录到ec2实例。在那之后工作了。

答案 19 :(得分:0)

chmod 777 /var/run/docker.sock

这就像一种魅力

答案 20 :(得分:0)

如果要保持简单,请在Dockerfile上使用fixdockergid

答案 21 :(得分:0)

sudo setfacl-修改用户:(用户名或ID):rw /var/run/docker.sock

几次尝试执行命令

sudo chmod 777 /var/run/docker.sock

但是不幸的是,每次我登录ubuntu系统时都必须这样做。 它不需要重新启动,并且比usermod或chown更安全。 当用户名仅存在于容器内部而不是主机上时,则需要用户ID。

我希望它能帮助您解决问题。

答案 22 :(得分: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的同一用户身份运行。但是,我非常感谢安全专家的任何反馈。

答案 23 :(得分:0)

如果某人仍在其本地计算机(Ubuntu)上遇到问题,请尝试使用以下命令:

context.imageSmoothingEnabled = false;

答案 24 :(得分:0)

我正在使用官方 jenkins码头工人镜像(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

答案 25 :(得分: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

答案 26 :(得分:0)

如果您可能会遇到类似以下的错误,

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

答案 27 :(得分:0)

2019-05-26

This为我工作!

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"

答案 28 :(得分:-1)

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

答案 29 :(得分:-3)

也许你应该从头开始用“-u root”选项运行docker

至少解决了我的问题