EatSmartシステム部ブログ

ウェブサイトの開発や運営に関する情報です。

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を利用するための設定となります。

qiita.com qiita.com

この設定を行うことで、最大5GB程度あったスワップが200MB程度に収まるようになりました。

-v /etc/localtime:/etc/localtime:ro \

ホストサーバと同じタイムゾーンで稼働させるための設定です。

-v /root/.ssh:/root/.ssh:ro \

デプロイsshを利用する際に、ホストのものを利用します。

アプリケーションのビルド

Antを利用するプロジェクトは、Dockerコンテナ内でビルドすることができるようになりました。 これ以外のMavenGolang等のプロジェクトは、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年近く経ちますが、ジョブの数・実行時間も増え、キューにジョブが溜まることも増えました。そのため、バッチの実行に関しては、別のツールへの移行を検討しているところです。