こんにちは!現場のインフラやCI/CDパイプラインを預かるエンジニアなら、一度はこんな悪夢を見たことがあるはずです。
「夜中に突然アラートが鳴り響き、見てみたらJenkinsのマスター(コントローラー)が飛んでいた……。今日中にリリースしなきゃいけないプロダクトのビルドが、すべて止まっている!」
そう、単一のJenkinsコントローラーは、組織にとって最大の単一障害点(SPOF: Single Point of Failure)です。ここが沈黙すると、開発チーム全体の動きが完全に止まります。
今回は、そんな恐怖から解放され、夜もぐっすり眠れるようになるための「Jenkinsコントローラーの二重化と高可用性(HA)構成」について、現場の泥臭い知見を交えながら優しく、そして徹底的に解説していきます。
これをマスターすれば、あなたのチームのCI/CD基盤は「落ちない要塞」へと生まれ変わりますよ。
—
1. JenkinsのHA(高可用性)とは何か?基本思想を理解する
まず最初に、Jenkinsにおける「高可用性」の基本概念を整理しておきましょう。
一般的なWebアプリケーションであれば、複数台のサーバーを並べてロードバランサーで振り分け、セッションはRedis等の外部ストアに逃がす「ステートレスな水平スケーリング」が常道です。
しかし、Jenkinsは生粋のステートフル(状態保持型)アプリケーションです。
ジョブの定義(`config.xml`)、ビルドの履歴、プラグインの設定、そして秘密情報(セキュアなクレデンシャル)など、すべてがコントローラーのローカルファイルシステム(通常は `/var/jenkins_home`)に依存しています。
そのため、JenkinsのHA構成における最大の肝は、「複数台のコントローラーで、いかにして同じJenkins Homeの状態を安全に共有・同期するか」という一点に尽きます。
—
2. 共有ストレージ戦略:NFS vs EFSの選定基準
二重化の基本アプローチは、「アクティブ・スタンバイ構成」です。2台のJenkinsコントローラーを用意し、常に片方(アクティブ)だけが動く状態にします。そして、2台のコントローラーから同じストレージ(Jenkins Home)を参照させます。
ここで頭を悩ませるのが、共有ストレージの選定です。主な選択肢は以下の2つ。
1. NFS(Network File System)
2. AWS EFS(Elastic File System)などのマネージドNFS
先輩エンジニアの痛い教訓:ファイルロックの罠
「単なるNFS共有なら簡単じゃん」と思って実装すると、必ず痛い目を見ます。
Jenkinsは起動時に、他のプロセスがすでに同じ `/var/jenkins_home` を掴んでいないかをチェックし、排他制御のためにロックファイルを生成します。
もし、フェイルオーバー(障害検知による切り替わり)の際に、古いアクティブ機が完全に停止する前に、新しいスタンバイ機が起動して同じストレージにアクセスしてしまうと、データが盛大に破壊(Corrupt)されます。
- 選定の極意:
- オンプレミスやK8s外なら、適切なファイルロック(POSIX準拠のロック)をサポートするNFSv4チューニングが必須です。
- クラウド(AWS)環境であれば、暗黙的に堅牢なロック機構とマルチAZ同期を担保してくれる Amazon EFS を強く推奨します。ただし、EFSはネットワークレイテンシがローカルディスクより劣るため、大量のビルド成果物をコントローラー上に保存せず、速やかにアーティファクトリポジトリ(NexusやArtifactory、S3など)へ逃がす設計が前提となります。
—
3. フェイルオーバーの仕組みと「ブレイン・スプリット(脳割れ)」を防ぐ
HA構成で最も恐ろしいのが「ブレイン・スプリット(Split-Brain)」です。
ネットワークの分断などにより、アクティブ機が死んだとスタンバイ機が勘違いして勝手に昇格した結果、「生きていた元アクティブ機」と「新しく昇格したスタンバイ機」の2台が同時に同じJenkins Homeを書き換え始め、データが修復不可能になる現象です。
これを防ぐためには、以下の仕組みが不可欠です。
1. 確実な死活監視(Heartbeat)
- Kubernetes環境であれば、`ReadWriteMany (RWX)` なボリュームと、リーダー選定(Leader Election)を行うコントローラーの仕組みを使います。
2. フェンス(Fencing / 射殺)
- 「古いアクティブ機が確実に停止したこと(あるいはネットワークから隔離されたこと)」を担保してからでないと、新しいアクティブ機を起動させない強固なオーケストレーションを組みます。
—
4. 【実践】最小構成で体験するJenkinsのデータ永続化とHelloWorld
「高可用性の理屈はわかったけれど、まずは基本のデータ永続化と動作確認から始めたい!」という方のために、Dockerを使ってローカルに堅牢なJenkins環境を構築する手順を見ていきましょう。
これをマスターすれば、コンテナが消えても設定が消えない安心感が手に入ります。
ステップ1: Docker Composeで永続化ディレクトリを切る
まずは、設定やビルド履歴が消えないように、ホスト側のディレクトリをコンテナの `/var/jenkins_home` にマウントします。
`docker-compose.yml` を作成してください。
version: ‘3.8’
services:
jenkins:
image: jenkins/jenkins:lts-jdk17
container_name: jenkins-master
restart: always
user: root # 権限トラブルを防ぐため一時的にroot(本番では適切なUID/GIDを推奨)
ports:
- “8080:8080”
- “50000:50000”
volumes:
# ここが命綱:Jenkins Homeをホストのディレクトリに永続化
- jenkins_home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock # Docker-in-Docker用(必要に応じて)
environment:
- JAVA_OPTS=”-Djenkins.install.runSetupWizard=false” # 初回ウィザードをスキップして爆速起動
volumes:
jenkins_home:
driver: local
ステップ2: 起動とログの確認
ターミナルで以下のコマンドを叩きます。
docker compose up -d
数秒後、コンテナが無事に立ち上がります。ログを確認してみましょう。
docker compose logs -f jenkins
コンソールに `Jenkins is fully up and running` と表示されたら準備完了です!
ステップ3: 精度高いHelloWorld(パイプライン)の実行
ブラウザで `http://localhost:8080` にアクセスしてください。(セットアップウィザードをスキップしているため、すぐにダッシュボードが開きます)
1. 左メニューの 「新規ジョブ作成 (New Item)」 をクリック。
2. アイテム名に `hello-world-pipeline` と入力し、「パイプライン (Pipeline)」 を選択して「OK」。
3. 下スクロールして「Pipeline」セクションのスクリプト欄に、以下の宣言的パイプライン(Declarative Pipeline)を貼り付けます。
pipeline {
agent any // 実行エージェント(今回はマスター自身、または利用可能なエージェント)
stages {
// ステージ1: 挨拶
stage(‘Greeting’) {
steps {
echo ‘=========================================’
echo ‘こんにちは、Jenkinsマスターへの第一歩へようこそ!’
echo ‘=========================================’
}
}
// ステージ2: 環境確認と動作テスト
stage(‘Environment Check’) {
steps {
sh ‘echo “現在実行中のOS・カーネル情報:”‘
sh ‘uname -a’
sh ‘echo “Javaのバージョン:”‘
sh ‘java -version’
}
}
}
post {
always {
echo ‘🎉 ビルドプロセスが正常に完了しました!’
}
}
}
4. 「保存 (Save)」 を押し、左メニューの 「ビルド実行 (Build Now)」 をクリックします。
左下の「ビルド履歴」に現れたビルド番号をクリックし、「コンソール出力 (Console Output)」を覗いてみてください。
きれいにログが出力され、最後に「🎉 ビルドプロセスが正常に完了しました!」と表示されたはずです。
これが、あなたのCI/CD自動化の心臓部となるJenkinsの、記念すべき最初の鼓動です。
—
まとめ:真の「落ちないCI/CD基盤」を目指して
今回は、JenkinsマスターのSPOF問題を解決するための共有ストレージ戦略、フェイルオーバーの思想、そしてローカルでの堅牢なデータ永続化とHelloWorldまでを駆け足で解説しました。
- コントローラーはステートフルであると心得よ。
- ストレージ選定(EFSや適切なNFS)とファイルロックの考慮が命運を分ける。
- データさえ安全にマウントされていれば、コンテナやサーバーが落ちてもJenkinsは何度でも蘇る。
これをベースに、Kubernetes上の StatefulSet と組み合わせた本格的なHA構成へとステップアップしていけば、もう夜間障害に怯える必要はありません。
「これをマスターすれば、毎日の作業が劇的に楽になりますよ」。
あなたの構築するパイプラインが、チームの最も信頼できる相棒になることを応援しています!