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

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

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

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

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


当前回答

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

错误消息

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/

其他回答

2018-08-19

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

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

You mount the socket /var/run/docker.sock to the jenkins container in order to be able to use the docker from the host. You have to install docker inside the container in order to use it. This is a great and simple article on how to do that. Note that newer versions might already have docker installed You run sudo usermod -a -G docker jenkins in order to add jenkins to the docker group. However, here you might run into a permission problem if the host docker and the container docker don't have the same group id so it is very important to adjust the container docker's gid to be the same as the host docker gid

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

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

希望这能有所帮助

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

错误消息

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是否正在运行 Sudo systemctl status docker

检查错误 Docker ps a

准许 sudo usermod -aG docker ${USER} 下一个命令 su - ${USER}

如果出现错误,请再次检查 Docker ps a

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

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

sudo usermod -a -G docker jenkins

在使用Docker映像作为Jenkins代理时并不总是足够的。也就是说,如果你的Jenkinsfile以pipeline{agent{dockerfile或pipeline{agent{image开头:

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

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

代理将(可能)没有安装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

The ideal fix to the third problem would be set up supplementary groups for the Agent. That does not seem possible. The only fix I'm aware of is to run the Agent with the Jenkins UID and the Docker GID (the socket has group write permission and is owned by root.docker). But in general, you do not know what those IDs are (they were allocated when the useradd ... jenkins and groupadd ... docker ran when Jenkins and Docker were installed on the host). And you can not simply tell Jenkins to user user jenkins and group docker

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

因为这告诉Docker在镜像中使用名为jenkins和Docker的用户和组,而你的Docker镜像可能没有jenkins用户和组,即使它有,也不能保证它与主机有相同的UID和GID,同样也不能保证Docker的GID是相同的

幸运的是,Jenkins在脚本中为Dockerfile运行docker build命令,所以你可以使用一些shell脚本魔法来将这些信息作为docker build参数传递:

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用户的UID和GID,并使用stat命令获取关于Docker套接字的信息。

你的Dockerfile可以使用这些信息为Agent设置一个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