使用在Docker中运行的Jenkins来操作其他容器(Docker外部的Docker)

以下是关于配置Docker外部容器(Docker outside of Docker,DooD)所需的笔记,其原始来源是在运行在Docker容器中的Jenkins上使用主机端的Docker来运行其他Docker容器。

前提 (Qian ti)

    • JenkinsもDockerコンテナで動く

 

    • Jenkinsコンテナのユーザーはjenkins(root以外)とする

 

    • 各Dockerコンテナは同一ホスト内で動く

 

    複数のDockerコンテナが動くためdocker-composeを利用する

环境

    • ホストOS:Oracle Linux 7.7(Red Hat 7.7)

 

    • docker 18.09.1

 

    • docker-compose 1.24.1

 

    Jenkins(Dockerイメージ)2.60.3

主机端的SELinux已关闭。

文件结构

由于使用Docker Compose,因此将采用这样的配置。

docker
├─ .env
├─ docker-compose.yml
├─ jenkins
|   ├─ Dockerfile
……

文件定义

Jenkins的Dockerfile

以下是Jenkins的Dockerfile。

FROM jenkins/jenkins:lts

USER root

# add jenkins user
RUN mkdir /home/jenkins && chown jenkins:jenkins /home/jenkins && usermod -d /home/jenkins jenkins

# add docker group
ARG DOCKER_GROUP_ID
RUN groupadd -g ${DOCKER_GROUP_ID} docker && usermod -aG ${DOCKER_GROUP_ID} jenkins

# install docker, docker-compose
ENV DOCKER_VERSION 18.09.1
RUN curl -fL -o docker.tgz "https://download.docker.com/linux/static/test/x86_64/docker-$DOCKER_VERSION.tgz" && \
    tar --strip-component=1 -xvaf docker.tgz -C /usr/bin

RUN curl -L https://github.com/docker/compose/releases/download/1.24.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose

USER jenkins

重点在于将容器用户定义为jenkins,并且为了在容器内无需使用sudo,我们添加了主机端的docker组ID(DOCKER_GROUP_ID)。 DOCKER_GROUP_ID会通过.env→docker-compose.yml的流程传递给Jenkins的Dockerfile。

Docker-compose -> Docker组合

以下是docker-compose.yml文件中的Jenkins部分摘录。

version: '2'
services:
  jenkins:
    build:
        context: ./jenkins
        args:
           - DOCKER_GROUP_ID=${DOCKER_GROUP_ID}
    ports:
        - 8080:8080
    volumes:
        - /var/jenkins:/var/jenkins_home
        - /var/run/docker.sock:/var/run/docker.sock

将DOCKER_GROUP_ID作为`build`的参数传递。这是主机上的docker组ID,并在后面的.env文件中进行定义。

通过在volumes中指定/var/run/docker.socket:/var/run/docker.sock,将主机上的docker套接字挂载到Jenkins容器内。这样,就可以使用Jenkins容器内的docker命令操作在同一主机上运行的其他容器。

.env文件

将.env文件放置在与docker-compose.yml相同的层级,可以将其作为外部参数传递值。

DOCKER_GROUP_ID=992

请在DOCKER_GROUP_ID中指定主机侧的docker组ID。

确认

只要能够进入 Jenkins 的 Docker 容器并执行 docker 命令,就算完成了。

[docker@host]$ sudo docker exec -it docker_jenkins_1 /bin/bash
jenkins@6a642404e172:/$ docker version
Client: Docker Engine - Community
 Version:           18.09.1
 API version:       1.39
 Go version:        go1.10.6
 Git commit:        4c52b90
 Built:             Wed Jan  9 19:33:22 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
 Version:          18.09.1-ol
 API version:      1.39 (minimum version 1.12)
 Go version:       go1.10.8
 Git commit:       e32a1bd
 Built:            Thu Jun  6 14:47:41 2019
 OS/Arch:          linux/amd64
 Experimental:     false

无论是使用单个容器运行还是使用docker-compose.yml构建,配置应该都不会有太大的变化。

请参考

在docker中使用jenkins运行docker
当在docker中挂载volume时会遇到文件所有者的问题
Dockerfile ARG简介
使用jenkins的docker镜像来使主机的docker可用的Dockerfile(docker中的docker)
关于Docker Volume访问权限的问题