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

Pon*_*rai 111 jenkins docker jenkins-pipeline

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

我使用下面的管道脚本配置了一个新作业.

node {
    stage('Build') {
      docker.image('maven:3.3.3').inside {
        sh 'mvn --version'
      }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

小智 182

用户jenkins需要添加到组中docker:

sudo usermod -a -G docker jenkins
Run Code Online (Sandbox Code Playgroud)

然后重新启动Jenkins.

  • 并重新登录用户 (56认同)
  • 无需再次登录,只需在同一终端会话中使用`newgrp docker`即可。 (11认同)
  • 我必须重新启动服务器才能实际运行。 (6认同)
  • 好的答案,但更笼统地说,我们可以这样做:`sudo usermod -a -G docker $ USER`并注销或重启。[link](https://techoverflow.net/2017/03/01/solving-docker-permission-denied-while-trying-to-connect-to-the-docker-daemon-socket/) (4认同)
  • 我必须断开/重新连接我的节点才能正常工作(它们通过ssh连接) (3认同)
  • ```service jenkins restart``` 解决了我的 docker socket 问题,而从浏览器重启没有。 (2认同)

小智 41

我的第一个解决方案是

usermod -aG docker jenkins
usermod -aG root jenkins
chmod 664 /var/run/docker.sock
Run Code Online (Sandbox Code Playgroud)

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

chmod 777 /var/run/docker.sock
Run Code Online (Sandbox Code Playgroud)

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

  • 永远不要执行“chmod 777 /var/run/docker.sock”。绝不。这是授予任何人在机器中使用 Docker 的权限,完全不鼓励。 (7认同)
  • 最好尝试:`chmod 666 /var/run/docker.sock` (7认同)
  • 它失败的原因可能是因为您必须重新打开终端。做完664后它失败了,但是后来我打开了一个新的外壳,它起作用了。 (4认同)
  • 我尝试重新打开,但它仅在最后一次 chmod 777 之后才开始工作 (4认同)
  • 尽管这对作者乃至我来说都是可行的,但给予docker.sock文件更多的访问权限不是最佳解决方案,您只需要执行usermod ...指令,然后重新启动系统即可,否则无效 (3认同)
  • 在 Prod 中您可能希望避免向 Docker 套接字授予非常开放的权限,例如 777,通过这样做,您将授予任何进程或用户完全访问 Docker 的权限。您只需将 Jenkins 用户添加到 Docker 组,然后重新启动服务器,这几乎就是您需要做的所有事情。HTH。 (2认同)

Sha*_*mad 31

这在Ubuntu 20.04中对我有用

sudo chmod 666 /var/run/docker.sock
Run Code Online (Sandbox Code Playgroud)

虽然不知道具体是做什么的,但是可以解决问题。

  • 这将 socker 设置为*每个人*可读可写。请记住 - 666 是野兽的标记,在安全至关重要的“任何事情”中都应避免使用 666。它肯定会解决这个问题,但可能会给你带来一堆更大的问题。:) (3认同)

she*_*hub 27

我的成功

sudo usermod -a -G docker $USER
reboot
Run Code Online (Sandbox Code Playgroud)

  • 授予权限后重启是诀窍 (12认同)
  • 或者运行 su ${USER} 而不是注销 (4认同)
  • 无需重启。只需注销然后再次登录。我说的是usermod (2认同)
  • 在 Ubuntu 18.04 上,我必须重新启动才能使设置生效。 (2认同)
  • 在 Ubuntu 20.04 上我需要重新启动。关闭会话还不够。 (2认同)
  • Ubuntu 22.10:重新启动并工作......! (2认同)

USM*_*ZIL 24

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

chmod 777 /var/run/docker.sock
Run Code Online (Sandbox Code Playgroud)

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

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

  • 这是最佳实践吗? (3认同)
  • 由于安全原因,这绝对不是最好的选择,但对我有用。 (3认同)

Dee*_*hta 16

这是一个非常常见的权限问题,这是简单的解决方案:

检查docker有哪些读写权限:

ls -l /var/run/docker.sock
Run Code Online (Sandbox Code Playgroud)

如果上面的命令说:srw-rw---- 1 root docker 0 Feb 17 12:48 /var/run/docker.sock

然后我们需要更改权限:

sudo chmod 666 /var/run/docker.sock
Run Code Online (Sandbox Code Playgroud)

现在,如果您检查权限,它会显示: srw-rw-rw- 1 root docker 0 Feb 17 12:48 /var/run/docker.sock

如果您好奇 666 是什么?

读取、写入和执行的权限 [第一个数字表示所有者,第二个数字表示组,第三个数字表示用户],666 比 777 更安全。

  • 我对此投了赞成票,因为你解释得很简单。现在我已经证明这是我的根本问题,我可以继续实施更安全的方式来获得许可。谢谢。 (2认同)

Uro*_* T. 14

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的权限

希望这可以帮助

  • 组 ID 问题救了我的命。谢谢! (3认同)
  • 谢谢 - 请注意,对于当前的 Jenkins Docker 映像,docker 命令已经安装(而 apt-get 尚未安装。)您的其他要点 - 将 Jenkins 添加到正确的组并确保 GID 与来自 Docker 主机的 GID 匹配,保留发现。 (2认同)
  • 这应该是对一个单独问题的单独答案,该问题询问相同的问题,但在容器内运行 Jenkins 时。`groupmod` 命令可以/应该位于 Dockerfile 中。 (2认同)

Pra*_*hoo 14

我使用了下面的命令,它对我有用。

sudo chmod 777 /var/run/docker.sock
Run Code Online (Sandbox Code Playgroud)


Pon*_*rai 13

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

sudo usermod -a -G root jenkins
sudo service jenkins restart
Run Code Online (Sandbox Code Playgroud)

  • 这是一种糟糕的安全措施.首选方法是[此答案](/sf/answers/3391520611/). (13认同)

Ami*_*aei 12

第 1 步:将您的用户名添加到docker组中:

sudo usermod -a -G docker $USER
Run Code Online (Sandbox Code Playgroud)

然后注销并再次登录。

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

newgrp docker
Run Code Online (Sandbox Code Playgroud)

奖励:检查您的新组:

id -g
Run Code Online (Sandbox Code Playgroud)

PS如果你有兴趣,参考这里

  • 注销并不总是有效。重新启动对我有用。 (2认同)

ahm*_*ira 12

我使用以下命令修复了此问题:

sudo chmod 777 /var/run/docker.sock
sudo chown ${USER}:docker /var/run/docker.sock
Run Code Online (Sandbox Code Playgroud)


Pro*_*ton 11

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

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

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

首先,检查您是否已经创建了一个 docker 组:

cat /etc/group
Run Code Online (Sandbox Code Playgroud)

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

sudo groupadd docker
Run Code Online (Sandbox Code Playgroud)

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

cat /etc/group
Run Code Online (Sandbox Code Playgroud)

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

docker:x:140:promisepreston
Run Code Online (Sandbox Code Playgroud)

哪里docker是我的grouppromisepreston是我的user

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

还将您的用户添加到“docker”组,如果您想以非 root 用户身份使用 Docker:

复制并在您的终端中准确地运行下面的命令,而无需以任何方式对其进行修改,无论您要运行或正在尝试运行的 docker 映像/容器/命令是什么,还是导致权限问题:

sudo usermod -aG docker $USER
Run Code Online (Sandbox Code Playgroud)

运行上述命令后,您需要注销并重新登录,以便重新评估您的组成员身份。但是,在 Linux 上,您还可以运行以下命令来激活对组的更改(在终端中复制并运行以下命令,无需以任何方式对其进行修改,无论 docker image/container/command您想要运行或正在尝试运行或导致权限问题):

newgrp docker
Run Code Online (Sandbox Code Playgroud)

或者

sudo systemctl restart docker
Run Code Online (Sandbox Code Playgroud)

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

docker run my-command
Run Code Online (Sandbox Code Playgroud)

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

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

sudo?? ? chown?? ? your_user:your_group?? ? -R?? my-app-directory/
Run Code Online (Sandbox Code Playgroud)

所以就我而言,它将是:

sudo chown promisepreston:docker -R my-app-directory/
Run Code Online (Sandbox Code Playgroud)

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

就这样。

我希望这有帮助


Cha*_*nka 10

方法 01 :- 更安全的方法

sudo usermod -aG docker ${USER}
Run Code Online (Sandbox Code Playgroud)

要应用新的组成员身份,请退出服务器并重新登录,或键入以下内容:

su - ${USER}
Run Code Online (Sandbox Code Playgroud)

系统将提示您输入用户密码以继续。通过键入以下内容确认您的用户现在已添加到 docker 组:

id -nG
Run Code Online (Sandbox Code Playgroud)

方法 02 :- 不推荐用于公共部署(不安全)

chmod 777 /var/run/docker.sock
Run Code Online (Sandbox Code Playgroud)

  • 这个解决方案将使docker不安全! (3认同)

her*_*oin 6

我有詹金斯在多克尔运行并连接詹金斯经由体积使用泊坞插座从主机Ubuntu的16.04到/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
Run Code Online (Sandbox Code Playgroud)

2)在主机上:

sudo service docker restart
Run Code Online (Sandbox Code Playgroud)

664 表示 - 为组中的所有者和用户读取和写入(但不执行).


Rae*_*ald 6

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

sudo usermod -a -G docker jenkins
Run Code Online (Sandbox Code Playgroud)

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

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

Run Code Online (Sandbox Code Playgroud)

这是因为詹金斯执行了一条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

...
Run Code Online (Sandbox Code Playgroud)

共享Docker守护进程套接字

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

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

Run Code Online (Sandbox Code Playgroud)

设置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'
Run Code Online (Sandbox Code Playgroud)

因为告诉泊坞窗使用的是被命名为用户和组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'
        }
    }
Run Code Online (Sandbox Code Playgroud)

id命令使用命令获取用户的UIDGIDjenkins并使用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
Run Code Online (Sandbox Code Playgroud)

  • 传递参数时,最好更改以下行: `args '-v /var/run/docker.sock:/var/run/docker.sock -u jenkins:docker'` by `args '-v / var/run/docker.sock:/var/run/docker.sock -u jenkins:jenkins --group-add docker'` 当传递 -u jenkins:docker 时,你改变了主用户组,这意味着当用户写入一个文件,假设在工作区中,它会将文件用户设置为 jenkins,将组设置为 docker。这可能不是我们想要的。 (2认同)