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

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

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

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

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


当前回答

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

chmod 777 /var/run/docker.sock

也可以在命令的开头使用sudo。

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

其他回答

简单地添加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

这在Ubuntu 20.04中适用

sudo chmod 666 /var/run/docker.sock

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

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

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

错误消息

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/

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