Jenkins
Docker

Jenkins with DockerをDockerコンテナとして配布する

More than 3 years have passed since last update.


Jenkins with Docker in Docker

この記事ではDockerでJenkins with Dockerを動かす方法について記載します。

今回利用したイメージはこちらです。


はじめに

JenkinsでDockerを使うことでDrone.ioのようにジョブ毎の環境分離ができとても便利です。

その辺りの詳細は「第8回Jenkins勉強会で「Jenkins with Docker」というLTをしました」に記載されています。。

ただ、Jenkins with Dockerでジョブ毎の環境分離が出来るのは良いのですが、どうせなら、CI環境自体もコンテナとしては配布したいですよね?

環境のポータビリティこそがDockerのポイントなので。

というわけで、以下にその方法を記載していきます。


Docker in Docker

そもそも、DockerコンテナでJenkinsを配布して、そのJenkinsがDockerを実行するということは、Dockerの中でDockerを実行する必要があります。そんなこと出来るんでしょうか?

実はで出来ます。特権モード (privileged)を使うことで、Dockerコンテナ内からDockerコンテナを操作することが出来るようになります。

詳細はこちらを参照。

使い方は簡単で、

docker run --privileged -it jpetazzo/dind

とすることで、dockerコンテナの利用出来るコンテナに入れるので、通常どおり

docker run -it koduki/centos7 /bin/bash

とかすれば、Dockerコンテナが起動します。これは仮想マシンのようにDockerの上にDockerを作ってるのではなく、Dockerから別のDockerを操作する形になるので、ホストOSからもプロセスの起動を確認できます。

% ps aux|grep docker|grep centos

root 26726 0.0 0.3 264076 11480 pts/4 Sl+ 22:39 0:00 docker run -it koduki/centos7 /bin/bash


Jenkinsのインストール

jpetazzo/dindはubuntuベースなのでapt-getを使ってJenkinsをインストールすることが出来ます。以下のようなDokcerfileになります。

FROM jpetazzo/dind

MAINTAINER koduki

# Install Jenkins
WORKDIR /tmp
RUN wget -q -O - http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key | apt-key add -
RUN echo 'deb http://pkg.jenkins-ci.org/debian binary/' >> /etc/apt/sources.list
RUN apt-get -y update
RUN apt-get -y install jenkins
RUN apt-get clean

# Add Jenkins jobs
ADD resources/simple-test01/ /var/lib/jenkins/jobs/simple-test01/

# Run
WORKDIR /var/lib/jenkins
ENTRYPOINT java -DJENKINS_HOME=/var/lib/jenkins -jar /usr/share/jenkins/jenkins.war --webroot=/var/cache/jenkins/war --httpPort=8000

ただ、この方法だとDockerデーモンを起動できないので、Jenkinsと同時にwrapdockerを起動する必要があります。

そのため、下記のようなrun.shを作り

#!/bin/bash

/usr/local/bin/wrapdocker &
java -DJENKINS_HOME=/var/lib/jenkins -jar /usr/share/jenkins/jenkins.war --webroot=/var/cache/jenkins/war --httpPort=8000

この形で実行します。

# Run

ADD resources/run.sh /tmp/run.sh
ENTRYPOINT /tmp/run.sh

実行はポート8000番をforwardしたいので

docker run --privileged -p "8000:8000" -it koduki/jenkins-with-docker

でprivileged を付けての実行となります。


Jenkins with Dockerの設定

Jenkins with Dockerの設定です。とはいえ、設定と言っても、今回はプラグイン等を作るわけではないので、ジョブの中でDockerを呼ぶだけです。

上のDockerfileにも記載していますが、/var/lib/jenkins/jobs/ 以下にジョブ用のディレクトリを作成し、config.xmlを作成します。

1から手で作るのは大変はのでJenkinsでGUIで作成したものを docker exec -it ${container_id} bash とかでcat等で取得してコピーするのがらくだと思います。

サンプルで作ったコンテナでは下記のようなファイルになりました。

<?xml version='1.0' encoding='UTF-8'?>

<project>
<actions/>
<description></description>
<keepDependencies>false</keepDependencies>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<canRoam>true</canRoam>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers/>
<concurrentBuild>false</concurrentBuild>
<builders>
<hudson.tasks.Shell>
<command>WORKDIR=`pwd`
echo &apos;Hello Docker.&apos;

# Run Docker Container.
docker run koduki/centos7 &apos;\

cat /etc/redhat-release ;\
ls -l \
&apos;
</command>
</hudson.tasks.Shell>
</builders>
<publishers>
</publishers>
<buildWrappers/>
</project>

これでJOBを実行したさいにcatとlsがコンテナ内で走ります。


まとめ

Dockerコンテナを利用するJenkinsをDockerコンテナで配布する方法について記載しました。

Dockerコンテナの管理層を含んだ環境を配布したいときには非常に便利だと思います。

通常は、そういったレイヤーはk8sとかが賄うのであまり気にすることはないかもしれませんが、ちょっとした検証用の環境をまるごと配布するとかには向いてる気がします。

それではHappy Hacking!


参考