Docker:在unix:///var/run/ Docker .sock试图连接到Docker守护进程套接字时被拒绝权限

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

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

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

但是它失败了,错误如下:

在unix:///var/run/ Docker .sock试图连接到Docker守护进程套接字时被拒绝

enter image description here

465469 次浏览

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

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

如果使用jenkins

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

sudo usermod -a -G docker jenkins

然后重启詹金斯。

否则

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

你可以:

sudo usermod -a -G docker [user]

[user]所在的位置插入用户名。

你可以通过执行grep docker /etc/group来检查它是否成功,并看到如下内容:

docker:x:998:[user]

在其中一行。

然后将用户组ID更改为docker(以避免不得不退出并再次登录):

newgrp docker

我有Jenkins在Docker中运行,并连接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表示-为组中的所有者和用户读写(但不执行)。

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

至少这解决了我的问题

我的第一个解决方案是:

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

但没有一个对我有用,我试过了:

chmod 777 /var/run/docker.sock

这是可行的,但我不知道这是否正确。

2018-08-19

我已经被这个问题困了好几天了,因为我还没有找到一个完整的答案,关于为什么和如何,我将为其他偶然发现同样问题的人发布一个答案,上面的答案不起作用。

以下是在docker中运行Jenkins时的3个关键步骤:

  1. 将套接字/var/run/docker.sock挂载到jenkins容器,以便能够从主机使用docker。
  2. 你必须在容器中安装docker才能使用它。是一篇关于如何做到这一点的伟大而简单的文章。注意,更新的版本可能已经安装了docker
  3. 运行sudo usermod -a -G docker jenkins将jenkins添加到docker组中。然而,如果主机docker和容器docker没有相同的组id,那么在这里你可能会遇到权限问题

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

另外,/var/run/docker.sock到777的不要更改权限或类似的东西,因为这是一个很大的安全风险,你基本上是在给每一个人在你的机器上使用docker的权限

希望这能有所帮助

我的成功

sudo usermod -a -G docker $USER
reboot

在我的例子中,不仅需要将jenkins用户添加到docker组,而且需要将该组作为jenkins用户的主组。

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

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

2019-02-16

对我来说,大多数步骤都和其他人写的一样。 但是,我无法使用usermod使用上述解决方案将jenkins添加到组docker中

我从码头工人主机运行docker容器中尝试了以下命令:

sudo usermod -a -G docker jenkins

(我从码头工人主机输入以下命令到运行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] jenkins密码:

我不知道密码。

没有sudo部分的命令,在集装箱码头工人中我收到:

usermod:权限被拒绝。Usermod:无法锁定/etc/passwd;试一试 稍后再. < / p >

<强>解决方案: 我用以下命令从码头工人主机输入到运行docker容器

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

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

usermod -a -G docker jenkins

然后,从码头工人主机中,我用以下命令重新启动了我的运行docker容器:

docker restart my_container_id_or_name

在那之后,我开始了jenkins的工作,它成功地完成了。

我只使用用户为用户jenkins发出usermod命令。

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

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

sudo usermod -a -G docker jenkins

当使用Docker映像作为詹金斯代理时,并不总是足够的。也就是说,如果你的Jenkinsfilepipeline{agent{dockerfilepipeline{agent{image开头:

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


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

  • 代理将(可能)没有安装Docker程序。
  • Agent将无法访问Docker守护进程套接字,因此将尝试运行Docker-in-Docker,即不推荐
  • Jenkins给出代理应该使用的数字用户ID和数字组ID。Agent不会有任何补充组,因为docker run不会登录容器(它更像sudo)。

安装Agent的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守护进程socket

作为之前说过,修复第二个问题意味着运行Jenkins Docker容器,以便它与容器的Docker守护进程共享Docker守护进程套接字。所以你需要告诉Jenkins使用共享运行Docker容器,如下所示:

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是什么(它们是在主机上安装Jenkins和Docker时运行useradd ... jenkinsgroupadd ... 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可以使用该信息为Agent设置jenkins用户和docker组,使用groupaddgroupmoduseradd:

# 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

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"

在詹金斯运行的服务器上,我用了

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

然后运行每个docker容器

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

使用setfacl似乎是更好的选择,并且不需要“-u user”。然后,容器以运行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

在做生产配置时,我得到了权限问题。我尝试下面的解决方案来解决这个问题。

错误消息

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中socket的解决方案:权限:

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/

我遇到过类似的问题,这是一个权限的问题,这个问题的原因是因为Docker守护进程/服务器总是以root用户运行,并希望你总是以sudo作为Docker命令的序言。

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

为了解决这个问题,以下是对我有效的方法:

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

cat /etc/group

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

sudo groupadd docker

接下来,使用下面的命令确认你的usergroup:

cat /etc/group

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

docker:x:140:promisepreston

其中docker是我的grouppromisepreston是我的user

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

将你的用户加入docker组,如果你想以非root用户的身份使用docker:

在你的终端上复制并运行下面的命令,而不需要以任何方式修改它,不管你想要运行或试图运行的docker image/container/命令是什么,或者是导致权限问题的:

sudo usermod -aG docker $USER

运行上面的命令后,您将需要注销并重新登录,以便重新评估您的组成员资格。然而,在Linux上,你也可以运行下面的命令来激活对组(在您的终端中复制并运行下面的命令,而不需要以任何方式修改它,不管您想要运行或试图运行的docker image/container/命令是什么,或者是它导致了权限问题)的更改:

newgrp docker

sudo systemctl restart docker

你现在可以验证你可以在没有sudo权限的情况下运行docker命令,通过再次运行导致权限问题的命令,例如(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/

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

这是所有。

我希望这对你们有帮助

如果你可能会得到如下错误,

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

使用下面的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

我使用的是官方 jenkins docker映像(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

在我的例子中,它只是启动docker服务:

sudo service docker start

如果有人在他们的本地机器(Ubuntu)上仍然面临这个问题,那么尝试下面的命令:

sudo chmod 666 /var/run/docker.sock

修改docker的访问权限。袜子文件

chmod 777 /var/run/docker.sock

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

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

在我的情况下,这将成功工作。

.在你的本地repo中输入这个命令
sudo chmod 666 /var/run/docker.sock

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

如果你在docker容器中运行Jenkins,而你的Jenkins链接到主docker,那么你可以通过下面的Dockerfile来修复这个问题:

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

sudo setfacl——modify user:(用户名或ID):rw /var/run/docker.sock

我试着执行了几次命令

Sudo chmod 777 /var/run/docker.sock

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

我希望它能帮助你解决这个问题。

如果你想保持简单,在Dockerfile上使用fixdockergid

方法01:—更安全的方法

sudo usermod -aG docker ${USER}

若要应用新的组成员资格,请从服务器注销并返回,或键入以下内容:

su - ${USER}

系统将提示您输入用户密码才能继续。 通过输入

确认您的用户现在已添加到docker组
id -nG

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

chmod 777 /var/run/docker.sock

或使用

sudo chown root:docker /var/run/docker.sock

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

sudo usermod -a -G docker $USER

然后注销并重新登录。

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

newgrp docker

检查你的新组:

id -g

附:如果你感兴趣,引用是在这里

除了将用户添加到docker组并尝试本线程中提到的所有方法之外,我花了一段时间才意识到我必须重新启动我的终端,然后重新登录到ec2实例。从那以后,它起作用了。

我可以在不更改本地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重新启动守护进程

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

导航到Jenkins ->管理Jenkins >管理云和节点->某些配置-> 节点属性->环境变量< / p > 然后添加DOCKER_HOST环境变量。 enter image description here < / p >

注意:我使用启动代理通过ssh使这个工作。

这适用于我在Ubuntu 20.04

sudo chmod 666 /var/run/docker.sock

不知道它到底能做什么,但能解决问题。

检查docker是否正在运行 Sudo systemctl status docker

检查错误 Docker ps -a

< >强给许可 sudo usermod -aG docker ${USER} 下一个命令 su - ${USER}

再次检查是否给出错误 Docker ps -a

我们有两种方法来解决这个问题

< >强方法1 应用新的组成员

sudo usermod -aG docker ${USER}
su - ${USER}

< >强方法2 修改文件权限和组权限

chmod 777 /var/run/docker.sock
sudo chown root:docker /var/run/docker.sock

方法1为安全方法。

我遇到的问题是,重新启动ubuntu服务器后,如果我通过sudo chmod 666 /var/run/docker.sock给予权限,docker将失去访问权限

因此,我需要通过:sudo usermod -aG docker ubuntu将我的用户名(ubuntu)添加到docker组

似乎没有人提到,根据官方来源:https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user -你可以"pre"你的命令sudo,它将在不创建用户或其他操作的情况下工作。例如sudo docker pull mongo -这是可行的。

更改下面的“your_user”;给真正的用户

echo "your_user ALL=(ALL) NOPASSWD: /usr/local/bin/docker, /usr/local/sbin/docker, /usr/bin/docker, /usr/sbin/docker, /bin/docker, /sbin/docker" > /etc/sudoers.d/sudo_docker


usermod -aG docker your_user


chmod 0660 /var/run/docker.sock


chown root:docker /var/run/docker.sock

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

sudo chmod 777 /var/run/docker.sock
sudo chown ${USER}:docker /var/run/docker.sock