こんにちは!日々のCI/CDパイプラインの運用、本当にお疲れ様です。
「朝に出社したら、なぜかJenkinsのエージェントノード(スレーブ)がオフラインになっていて、昨夜のビルドがすべて止まっていた……」
「テストの負荷でノードがフリーズし、手動で再接続ボタンを押すはめになった……」
そんな絶望的な朝を迎えた経験、ありませんか?これを読んでいるあなたも、毎日のようにJenkinsの管理画面と睨めっこしているかもしれませんね。
今回は、そんな「Jenkinsノードのフリーズや接続断」という運用上の悪夢を、GroovyスクリプトとREST APIの力で完全に自動化し、自己修復させる仕組みを解説します。
これをマスターすれば、深夜の障害対応や、朝一番の「手動ポチポチ再接続作業」から解放されますよ。さあ、一緒にJenkinsをちょっと賢くしてみましょう!
—
そもそも、なぜJenkinsノードは「お亡くなり」になるのか?
Jenkinsは、マスター(親)が指示を出し、エージェント(子)が実際にビルドやテストを実行するという分業体制をとっています。しかし、エージェント側で以下のような問題が発生すると、接続が切断されます。
- 重いテストを回しすぎてメモリ(OOM)を食い潰し、プロセスが死ぬ
- 一時的なネットワークの瞬断
- ディスク容量の圧迫によるフリーズ
標準のJenkinsにも「再接続の試行」機能はありますが、完全に固まってしまったプロセスや、OSレベルで応答しなくなったノードを自力で蘇らせることはできません。ここで必要になるのが、「外部から状態を監視し、ダメなら一度叩き起こして再登録する」という自己修復(セルフヒーリング)の仕組みです。
—
全体像:どうやって自己修復するのか?
今回のアーキテクチャは非常にシンプルです。
1. 監視(Cron / 外部監視): 定期的に(例えば5分おきに)スクリプトをキックする。
2. 診断(REST API): JenkinsのREST APIを叩いて、ノードが「オフライン」になっていないか確認する。
3. 治療(Groovyスクリプト): もしオフラインであれば、Jenkinsの内部API(Groovy)を操作して、エージェントを一度切断・削除し、再登録(または再接続トリガー)を実行する。
今回は、この心臓部となる「Jenkins上で動く、ノード自己修復Groovyスクリプト」を丁寧に作っていきます。
—
実装:自己修復Groovyスクリプトの全貌
Jenkinsの「スクリプトコンソール」(`http://
自分のプロジェクトに合わせて、対象のエージェント名などを書き換えて使ってください。
import jenkins.model.Jenkins
import hudson.model.Computer
// — 設定エリア —
// 自動復旧させたいエージェント名のリスト
def targetNodes = [“builder-node-01”, “docker-node-02”]
// Jenkinsのインスタンスを取得
def jenkins = Jenkins.getInstanceOrNull()
if (jenkins == null) {
println “ERROR: Jenkins instance is not available.”
return
}
println “=== Jenkins Node Self-Healing Script Started == ”
targetNodes.each { nodeName ->
// ノードのコンピュータオブジェクトを取得
Computer computer = jenkins.getComputer(nodeName)
if (computer == null) {
println “[WARN] Node ‘${nodeName}’ is not found in Jenkins configuration.”
return
}
// ノードがオンラインかどうか、または一時停止していないかチェック
// 完全にフリーズしている、あるいはオフラインの場合を検知
if (computer.isOffline() || computer.isTemporarilyOffline()) {
println “[ALERT] Node ‘${nodeName}’ is OFFLINE. Starting self-healing process…”
try {
// 1. もし一時オフライン状態なら、理由を取得してログ出力
if (computer.isTemporarilyOffline()) {
def cause = computer.getOfflineCauseReason()
println ” -> Offline cause: ${cause}”
}
// 2. 接続を切断して再接続を試みる(リコネクト実行)
// 接続が完全に死んでいる場合は、一度チャネルを閉じる
if (computer.getChannel() != null) {
println ” -> Closing dead channel for ‘${nodeName}’…”
computer.getChannel().close()
}
// 3. 再接続のトリガーを引く
println ” -> Triggering reconnection for ‘${nodeName}’…”
computer.connect(true) // force = true で強制再接続
println “SUCCESS: Reconnection command sent to ‘${nodeName}’.”
} catch (Exception e) {
println “ERROR: Failed to heal node ‘${nodeName}’. Exception: ${e.message}”
e.printStackTrace()
}
} else {
println “[OK] Node ‘${nodeName}’ is online and healthy.”
}
}
println “=== Jenkins Node Self-Healing Script Finished == ”
スクリプトのポイント
- 安全な対象指定: リスト形式(`targetNodes`)で監視するノードを明示しているため、マスターや触ってはいけない特殊なノードを巻き込む事故を防ぎます。
- 強制再接続(`computer.connect(true)`): ゾンビ状態になったコネクションを一度ちぎり、新しく接続し直すシグナルをJenkinsからエージェント側に送ります。
—
運用への組み込み:どうやって自動実行するか?
このスクリプトを手動で毎回叩くのでは意味がありません。これを完全自動化するための2つのアプローチを紹介します。
アプローチA: Jenkinsの「Job」として定期実行する(一番手軽)
1. Jenkinsで「フリースタイル・プロジェクト」または「パイプライン」を新規作成します(例: `infra-node-healer`)。
2. ビルド・トリガーの項目で 「定期的にビルド (Build periodically)」 を選択し、スケジュールに `H/5 `(5分おき)などを設定します。
3. ビルドステップに「Groovy スクリプトの実行」を追加し、先ほどのコードを貼り付けます。
アプローチB: 外部の監視サーバ(Cron + curl)から叩く(より堅牢)
Jenkins自体が完全にフリーズしている場合はアプローチAも動かないため、厳密にはJenkinsの外(監視専用のZabbix、Prometheus、あるいは別サーバのCronなど)から、JenkinsのREST API(Remote Access API)経由でスクリプトを実行するのがプロの技です。
外部サーバのCrontab等から、API経由でGroovyスクリプトを安全に叩く例
curl -X POST \
–user “admin:your-api-token” \
–data-urlencode “script=groovy.lang.GroovyShell.run(‘…’)” \
https://your-jenkins.example.com/scriptText
—
導入時の注意点(先輩からのアドバイス)
この仕組みを導入するにあたって、いくつか現場でハマりがちなポイントを共有しておきますね。
1. APIトークンの権限管理
自動実行用のユーザには「スクリプト実行(Overall/RunScripts)」の権限が必須です。セキュリティ権限は最小限に絞り、一般ユーザには絶対にこの権限を与えないようにしてください。
2. 無限ループ・バーストに注意
エージェント側の物理的な障害(ネットワークケーブルが抜けているなど)が原因の場合、自己修復スクリプトが無限に再接続を試みてログを埋め尽くすことがあります。Slackなどのチャット連携を組み込み、「3回リトライしてもダメなら人間のSlackに通知する」というエスカレーション構造を持たせておくと完璧です。
—
おわりに
今回は、Jenkinsノードの自己修復を実現するGroovyスクリプト運用術をご紹介しました。
「障害が起きないシステム」を作るのは理想ですが、現実にはマシンはフリーズし、ネットワークは切れます。だからこそ、「障害が起きても、システムが勝手に気づいて自分で治す(セルフヒーリング)」というレジリエンス(回復力)を持たせることが、モダンなDevOpsエンジニアの腕の見所です。
これを導入すれば、あなたの平穏な朝と、深夜の呼び出しがない安眠が戻ってきます。ぜひ、今日の業務に取り入れてみてくださいね!