12
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

Organization

Dockerで動くJenkinsから他のコンテナを操作する(Docker outside of Docker)

Dockerコンテナ内で動くJenkinsから、ホスト側のDockerを使って他のDockerコンテナを動かす、いわゆるDocker outside of Docker(DooD)に必要な設定のメモです。

前提

  • 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です。

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は後述する.envdocker-compose.ymlという流れでJenkinsのDockerfileに渡されます。

docker-compose

docker-compose.yml(Jenkins部分抜粋)です。

docker-compose.yml
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

buildの引数としてDOCKER_GROUP_IDを渡します。これはホスト側のdockerグループIDで、後述の.envファイル内に定義します。

volumes/var/run/docker.socket:/var/run/docker.sockを指定することにより、ホスト側のdockerソケットをJenkinsコンテナ内にマウントします。これでJenkinsコンテナ内のdockerコマンドで同じホストで動く他のコンテナを操作できます。

.env

docker-compose.ymlと同じ階層に.envを置くことで外部パラメーターとして値を渡すことができます。

.env
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をマウントしたときのファイルのowner問題
Dockerfile ARG入門
jenkinsのdockerイメージからホストのdockerが使えるようにするDockerfile(docker in docker)
DockerのVolumeのアクセス権限の問題について

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
12
Help us understand the problem. What are the problem?