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

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

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

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

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


当前回答

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)尊重他人的隐私。 #2)三思而后行。 #3)能力越大,责任越大。 [sudo] jenkins密码:

我不知道密码。

没有sudo部分的命令,在docker容器中我收到:

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

解决方案: 我从docker主机输入以下命令进入正在运行的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

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

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

其他回答

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

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

我的成功

sudo usermod -a -G docker $USER
reboot

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

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

sudo service docker start

这在Ubuntu 20.04中适用

sudo chmod 666 /var/run/docker.sock

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