なぜJenkinsの設定が勝手に変わる?並列実行の罠と変更履歴の残し方
「誰が変更したか分からない」——運用中のJenkinsで設定が意図せず書き換えられ、ビルドが謎の失敗を繰り返す。変更履歴が残らないCI/CDツールは、属人化と設定事故の温床になります。
何が起きたか
先週、Jenkinsジョブの同時実行数を1に制限したはずでした。しかし数日後、設定が3に戻っていることが発覚します。変更者を問い合わせても返事はなく、誰が何のために変更したのかを特定する手段がありませんでした。
同時実行数が増えたことで、同じジョブを異なるパラメータで並行起動した際に処理が互いに干渉し、ビルドが失敗を繰り返す状態に陥りました。変更の目的が分からなかったことで、どう対処すべきかの判断ができず、再発防止策も立てられない状況が続きました。
変更者の特定ができず、再発防止策も立てられない。こうした状況を根本から解決するため、監査ログの導入と実行数制御の見直しに着手しました。
前提:Jenkinsの実行スロットとジョブ干渉の仕組み
Jenkinsでは、ビルドを実行する単位をExecutor(実行スロット)と呼びます。各ノードには複数のExecutorを設定でき、その数だけジョブを並行実行できます。
設定には2つの視点があります。1つ目はノード全体の並列数で、これはノードに割り当てられたExecutor数です。2つ目は個別ジョブの並列実行制御で、同じジョブを複数のパラメータで同時に起動するかどうかを制御します。
同じジョブを異なるパラメータで並行起動すると、デフォルトでは同一のワークスペースディレクトリが使われます。この状態で複数のビルドが同時に走ると、ファイルの読み書きが競合し、ビルドが中断される可能性があります。Jenkinsの公式issueでも、この挙動は「予期しないビルド結果を引き起こす」として指摘されています。
なぜ並列実行が問題になったか
今回の問題は、何を目的とした並列実行の変更だったのかが分からなかったことにあります。誰が何のために設定を変えたのかが追跡できず、変更の意図を確認できなかったため、適切な対処方針を立てることができませんでした。
現在のサーバー環境では、複数のジョブが同時に走ることでCPUやディスクI/Oを奪い合い、個々の処理が遅延します。並列化によって全体のスループットが向上するどころか、むしろ低下する結果となりました。
さらに深刻だったのが、異なるパラメータで起動したジョブ同士の干渉です。同一のワークスペースで複数のビルドが同時に実行されると、ファイルの上書きや読み込みタイミングのずれが発生し、ビルドが中断されます。変更の目的が不明だったため、この問題への対処も後手に回りました。
変更履歴プラグインの導入
設定変更を追跡できない状態を解消するため、Job Configuration Historyプラグインを導入しました。このプラグインは、誰がいつどのジョブの設定を変更したかを記録し、各ジョブの設定画面から過去の変更履歴を閲覧できるようにします。
導入後は、設定画面に「Job Config History」のリンクが追加され、変更日時・変更者・変更内容の差分を確認できるようになりました。設定事故が発生した際に責任の所在を明確化でき、再発防止の起点となる仕組みが整いました。
ただし、プラグインは導入後から記録を開始するため、今回の変更者は推測にとどまりました。タイミングから判断すると、環境構築の関連作業に伴う変更だった可能性が高いと考えられています。
導入時の判断:
設定変更を追跡できるよう、変更履歴ログプラグインを導入しました。各ジョブの設定画面から個別に参照できます。プラグイン導入後から記録が開始されるため、過去の履歴は残っていませんが、今後の設定管理と追跡のための基盤として活用していきます。
並列実行の適切な制御設計
並列実行数の制御には2つの方式があります。
| 制御方式 | 対象範囲 | メリット | デメリット |
|---|---|---|---|
| ノード全体の並列数を絞る | 全ジョブ | 設定が簡単。全体のリソース競合を確実に防げる | 軽量なジョブも実行待ちになり、他ジョブの実行機会を奪う |
| 特定ジョブだけ「並行実行しない」設定 | 選択したジョブのみ | 重いジョブだけを制御し、他ジョブは並行実行できる | 個別設定が必要。設定漏れのリスクがある |
今回は、全体の並列数を1に戻す方式を採用しました。理由は、現状のサーバー環境では並列実行によるメリットがなく、確実にリソース競合を防ぐことが最優先だったためです。
ただし、将来的に真に並行実行したいジョブが出てきた場合は、個別ジョブに「Do not allow concurrent builds」オプションを設定する方式への移行を検討する余地があります。Jenkinsのthrottle-concurrent-builds-pluginを使えば、特定のジョブやカテゴリ単位で同時実行数を制限できます。
検証結果と現場の判断
同時実行数を1へ戻した結果、ビルドの成功率が安定しました。キューに滞留する時間は増えたものの、失敗を繰り返して何度もやり直す状況は解消されました。
プラグイン導入後は、設定変更の履歴が記録され、誰がいつ何を変えたかを追跡できるようになりました。変更者が不明で再発防止策を立てられない、という事態を避ける土台が整ったのです。
運用担当者の判断:
ビルドの安定化とエラー防止のため、Jenkinsジョブの同時実行数を1(単一実行)に戻す方針としました。以前は1に制限していましたが、設定が3に増えていたことで、同じジョブを異なるパラメータで同時に実行した際に、処理が互いに干渉してビルドが失敗する問題が発生していました。現在のサーバー環境では、並列実行してもリソースを奪い合うだけで処理速度は向上せず、むしろ遅延する可能性があるため、設定を1に戻すことで安定性を優先します。
現状の制約
Job Configuration Historyプラグインは導入後から記録を開始するため、導入以前の変更履歴は残っていません。今回の設定変更者は推測にとどまり、完全な特定には至りませんでした。
また、ノード全体の並列数を1に固定したことで、軽量なジョブも含めて順番待ちが発生します。今後、真に並行実行したいジョブが出てきた場合は、個別ジョブ単位の制御への移行が必要になります。この点は、運用の中で支障が出た際に再検討する方針です。
まとめ
最終的に特定した原因は、変更履歴が記録されない仕組みの不在と、並列実行数の無計画な変更による干渉でした。解決策として、Job Configuration Historyプラグインで変更追跡を可能にし、同時実行数を1に戻すことでリソース競合とワークスペース干渉を防ぎました。
並列実行は万能ではありません。リソース競合が起きる環境では、むしろスループットが低下します。監査ログと実行制御の両輪で、CI/CD基盤の安定化を図る取り組みを紹介しました。
同じ境界でつまずく現場が減れば幸いです。



























