Simply 为jenkins 用户添加docker 作为supplementary group
sudo usermod -a -G docker jenkins
在使用 Docker 映像作为 Jenkins Agent 时并不总是足够的。也就是说,如果您的Jenkinsfile 以pipeline{agent{dockerfile 或pipeline{agent{image 开头:
pipeline {
agent {
dockerfile {
filename 'Dockerfile.jenkinsAgent'
}
}
stages {
这是因为Jenkins执行了docker run命令,导致了三个问题。
- 代理将(可能)未安装 Docker 程序。
- 代理将无法访问 Docker 守护程序套接字,因此将尝试运行 Docker-in-Docker,即not recommended。
- Jenkins 给出了代理应该使用的数字用户 ID 和数字组 ID。 Agent 不会有任何补充组,因为
docker run 不会登录到容器(更像是sudo)。
为代理安装 Docker
使 Docker 程序在 Docker 映像中可用只需要在 Dockerfile 中运行 Docker installation steps:
# 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 守护进程套接字
作为has been said before,解决第二个问题意味着运行 Jenkins Docker 容器,以便它与容器外部的 Docker 守护程序共享 Docker 守护程序套接字。因此,您需要告诉 Jenkins 使用该共享运行 Docker 容器,因此:
pipeline {
agent {
dockerfile {
filename 'Dockerfile.jenkinsAgent'
args '-v /var/run/docker.sock:/var/run/docker.sock'
}
}
设置 UID 和 GID
解决第三个问题的理想方法是为代理设置补充组。这似乎是不可能的。我知道的唯一解决方法是使用 Jenkins UID 和 Docker GID 运行代理(套接字具有组写入权限,并且归 root.docker 所有)。但总的来说,您不知道这些 ID 是什么(它们是在主机上安装 Jenkins 和 Docker 时运行 useradd ... jenkins 和 groupadd ... docker 时分配的)。而且你不能简单地告诉 Jenkins 用户用户 jenkins 和组 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 构建参数传递:
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 可以使用该信息为代理设置 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