DockerコンテナでJenkinsを稼働させる
今回は、イートスマートのサービスのビルド・デプロイに利用しているJenkinsについて書きます。 DockerコンテナでJenkinsを稼働させるための手順をまとめました。 現在はJenkins以外にも同様のツール・サービスが多数ありますが、手元のサーバ上で手軽に利用できるのがお大きな利点ではないかと思います。
Jenkinsについて
Jenkinsは、継続的インテグレーションを行うため に利用するツールです。 主な用途は以下となります。
アプリケーションのビルド
Javaやその他の言語で造られたアプリケーションのビルドを行います。 ビルドを行う手順はJenkins上に直接記述することもできますが、バージョン管理を行うためスクリプトにまとめておき、Jenkinsではそのスクリプトを実行するのみとしています。
バッチの実行
定期的に実行したいバッチを「ビルド・トリガ」の「定期的に実行」を利用して処理しています。 以前はCronを利用していましたが、Jenkinsへ移行することで
- スケジュールの管理
- 状況の把握
- 結果の把握
が容易になりました。 アプリケーションのビルドも同様ですが、「ビルド後の処理」へ失敗時にシステム部メンバーへメールで通知する設定を行っています。 また、手順もスクリプトにまとめてバージョン管理を行っています。
サービスの監視
インフラ・サービスの監視はZabbixを利用していますが、補助的にJenkinsでも行っています。 サービスごとに監視用のスクリプトを用意して、バッチと同様に失敗時に通知を行っています。
Dockerコンテナで稼働させる
今年の3月にインフラをデータセンターからさくらインターネットのクラウド・専用サーバへ移行しました。 この時、Jenkinsをはじめ上記のZabbixやタスク管理に利用するRedmine、バージョン管理に利用するsvn/gitbucket等も同様に移行しましたが、すべてDockerコンテナにしています。
Dockerイメージを作成する
以前の環境ではJava6を利用してビルドを行っていました。移行のタイミングでバージョンアップすると問題が発生した場合に切り分けが難しいので、Dockerコンテナも同じバージョンにしました。 公式のイメージもありますが、上記の理由で以前の環境を再現することにりました。
FROM java:6
Java6のイメージをベースにしました。
ADD jenkins.war /var/ ADD apache-ant-1.7.0-bin.tar.gz /var/ ENV PATH $PATH:/var/apache-ant-1.7.0/bin
JenkinsのwarとJavaアプリケーションのビルドに利用するAntのjarをコピーし、パスを通します。
RUN apt-get update \ && apt-get install -y zip \ && apt-get install -y rsync
デプロイに利用するコマンド(zip,rsync)をインストールします。
ENTRYPOINT ["java", "-Duser.timezone='Asia/Tokyo' -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 -Xmx1024m", "-jar", "/var/jenkins.war"]
Jenkinsを起動します。タイムゾーンやエンコードを指定してます。 また、大きめのアプリケーションのビルドとテストを行うので、メモリの指定も追加しています。
実際はサービスごとの細かな設定も追加していますが、これらの内容でイメージを作成しました。
Dockerコンテナを起動する
Dockerイメージができたら起動します。起動には、以下のようなオプションを指定しています。
--env="JENKINS_HOME=/var/jenkins/jenkins_home/" \ -v /var/jenkins/jenkins_home:/var/jenkins/jenkins_home \
Jenkinsのジョブやワークスペースの保存先をしています。 保存先をホストサーバとすると、バックアップ等扱いやすくなります。
--env="TMPDIR=/dev/shm" \
長期間かどうさせるとサーバのメモリが不足し、Jenkinsの動作が不安定になることがありました。 Zabbixで確認すると、アプリケーション自体が利用するメモリが増加するのではなく、「cached」や「slab_cache」とよばれるメモリが増加していました。 以下の記事を参考に、tmpfsを利用するための設定となります。
この設定を行うことで、最大5GB程度あったスワップが200MB程度に収まるようになりました。
-v /etc/localtime:/etc/localtime:ro \
ホストサーバと同じタイムゾーンで稼働させるための設定です。
-v /root/.ssh:/root/.ssh:ro \
デプロイsshを利用する際に、ホストのものを利用します。
アプリケーションのビルド
Antを利用するプロジェクトは、Dockerコンテナ内でビルドすることができるようになりました。 これ以外のMavenやGolang等のプロジェクトは、Jenkinsとは別のコンテナを利用しています。
- Mavenを利用するプロジェクト
Mavenコンテナを利用してビルドします。 /root/.m2ディレクトリの保存先をホストサーバすることで、ダウンロードにかかる時間を短縮できます。
docker run -i --rm --name maven -v <プロジェクトのルート>:/target -v /root/.m2:/root/.m2 -w /target maven:3.3.3-jdk-8 mvn package
- Golanのプロジェクト
プロジェクトのルート用意したビルド用のスクリプト(build.sh)を利用します。 ビルド用のスクリプトではgo get/go buildを行います。
docker run -v <プロジェクトのルート>:/go/src/project/ golang:latest \ sh /go/src/project/build.sh
まとめ
以上、イートスマートでのJenkinsの利用方法を書きました。 利用を開始してから6年近く経ちますが、ジョブの数・実行時間も増え、キューにジョブが溜まることも増えました。そのため、バッチの実行に関しては、別のツールへの移行を検討しているところです。