Jenkinsではノードがオフラインなのに、SSHだけは接続できる。これは珍しい矛盾ではありません。
最短の解決策は、再インストールではなく、調査順を固定することです。 まずスケジューリング、次にJenkinsの接続経路、Java Agentプロセス、macOSの常駐状態、最後にXcode CIの実行環境を確認します。単発のプロセス停止なら原状復帰、繰り返し切断や環境の漂流があるならノードを隔離し、独立したリモートMacへの切り替えを検討してください。
このページは、JenkinsとリモートMacのビルドノードを運用するDevOpsエンジニア向けです。Xcodeの自動ビルド、テスト、署名を担当する人や、長期稼働するmacOS CIノードの受け入れ基準を作る人にも役立ちます。
01最初に保存する障害証拠
「Agentが落ちた」と判断する前に、障害の境界を固定します。ノードがオフラインなのか、ジョブがキューで待機しているだけなのか、オンラインでも作業ディレクトリやXcodeが壊れているのかで、修復箇所は異なります。
Jenkinsのノード画面では、接続状態、ラベル、実行器、Remote Root Directory、直近の切断理由を保存します。キュー画面では、待機理由と必要なラベルを記録してください。コントローラー側のログ、ノード側のログ、リモートMacで動作するJavaプロセスを同じ時刻で照合すると、単なる「オフライン表示」から原因を絞れます。
| 観察できる状態 | まず見る場所 | 可能性の高い境界 |
|---|---|---|
| ノードがオフライン、SSHは接続可能 | Jenkinsの接続ログとJavaプロセス | Jenkinsの転送経路、Agent停止 |
| ノードはオンライン、ジョブは待機 | ラベル、実行器、キュー理由 | スケジューリング設定 |
| ジョブ開始後に失敗 | Remote Root、権限、ディスク、環境 | 作業ディレクトリまたはユーザー環境 |
| Shellは成功、Xcode処理だけ失敗 | Xcodeの選択、初期化、署名情報 | macOS開発ツールチェーン |
保存対象は、最後に成功したジョブの時刻、最初の失敗時刻、エラーメッセージ、ノード状態、実行中だったジョブ、直前の再起動や設定変更です。Secret、ホスト名、ユーザー名、秘密鍵は記録に残さず、必ず伏せ字にします。
02スケジューリングと接続経路
オンライン表示とジョブ実行は別の判定
Jenkins Agentがオンラインでも、ラベルがジョブの要求と一致しなければ処理は始まりません。実行器が無効化されている場合や、管理者がノードを一時的にオフラインにしている場合も、接続障害と同じように見えます。
まずキューの待機理由を読み、ジョブが要求するラベルとノードのラベルを比較します。次に実行器が利用可能か、ノードのRemote Root Directoryへ実行ユーザーが書き込めるかを確認します。JenkinsのノードとAgent管理に関する公式資料でも、ノード、実行器、ラベルは別の管理対象として扱われています。
SSHとAgent転送を混同しない
なぜJenkinsではmacOS AgentがオフラインなのにSSH接続できるのでしょうか。
macOSのRemote Loginは、システムへ入るためのSSHサービスです。一方、JenkinsがSSH方式でAgentを起動する場合は、コントローラーからリモートMacへログインした後、Javaプロセスを起動し、JenkinsのAgent通信を確立します。入線方式やWebSocketを使う構成では、さらに別の経路になります。
したがって、macOSのSSHポートへ接続できたことだけでは、Jenkinsの通信が正常とは言えません。AppleのRemote Login説明でシステム側のSSH設定を確認し、Jenkins側はAgentの接続方式に関する公式ガイドに合わせて確認します。
確認順は次のとおりです。
- コントローラーから名前解決ができるか確認します。
- プロキシ、ファイアウォール、証明書の変更を調べます。
- Jenkinsの接続方式に必要な宛先と通信経路を確認します。
- コントローラーのアドレス変更が設定へ反映されているか確認します。
- 接続修復後、握手、心拍、コントローラー再起動後の再接続を確認します。
Jenkinsの公開サービスと通信条件は、Jenkins公式のサービスとポート資料にある構成を基準にしてください。SSHの疎通確認を、Agent通信の成功と読み替えないことが重要です。
03JavaプロセスとmacOS常駐状態
接続経路に問題がなければ、リモートMac上でAgentのプロセスを確認します。プロセスが存在しない場合は終了コード、標準エラー、起動時刻、親プロセスを調べます。agent.jarの不一致、起動引数の失効、Secretの更新、権限不足、OSによるプロセス終了を分けて記録してください。
Javaのバージョンを固定値で判断するのは危険です。JenkinsのLTS系列によって要件が変わるため、作業日時点のJenkins公式Javaサポートポリシーで、使用中のJenkins系列とJava実行環境を照合します。ダウンロードURLやSecretを記事やスクリプトへ直書きせず、管理画面で発行された値を安全な方法で渡します。
SSHではAgentが起動するのに、ログアウト後や再起動後に戻らない場合はどうしますか。
手動SSHで成功する起動は、ログインセッションに依存している可能性があります。Agentの所属ユーザー、ホームディレクトリ、PATH、証明書、ファイル権限を確認し、ログアウト、VNC切断、再起動の各状態で起動コンテキストが変わらないかを調べます。
macOSの自動起動は、実際の配置方式に合わせてlaunchdの設定とログを確認します。未検証のplistテンプレートをそのまま投入するのではなく、既存のユーザー単位またはシステム単位の登録状態、標準出力、標準エラー、終了理由を確認してください。再起動後に一度オンラインになっても、無人状態で連続して再接続できなければ復旧とは判定しません。
04注意: JenkinsのSecret、SSH鍵、署名証明書をログへ出力しないでください。障害調査用ログを共有する場合は、値だけでなく、ホスト名やユーザー名も置き換えてください。
Remote RootとXcode CIの実行環境
オンラインでも作業できないケース
Jenkins AgentがオンラインなのにXcode CIのジョブがキューで待ち続けるときは、何を確認すべきでしょうか。
最初にラベルと実行器を確認します。ジョブが特定ラベルを要求しているのにノード側のラベルが変わっていれば、Agentは正常でもスケジュールされません。キューから実行された後に失敗する場合は、Remote Root Directoryの存在、空き容量、所有者、ワークスペースへの書き込み権限を確認します。
次に、Agentを起動したユーザーの環境でXcodeの選択状態を確認します。対話的なシェルで見えるPATHやHOMEが、Jenkinsの非対話的なプロセスと一致するとは限りません。XcodeのCommand Line ToolsはApple公式の設定資料とインストール資料に沿って確認します。
| 検証ジョブ | 確認する内容 | 合格条件 |
|---|---|---|
| 基本Shell | ユーザー、PATH、作業ディレクトリ、権限 | Agentユーザーの値で安定して実行 |
| Xcodeビルド | Xcode選択、依存関係、DerivedData | 対象プロジェクトが再現可能にビルド |
| テスト | Simulatorまたは実機条件、ログ、結果 | テスト結果をJenkinsへ保存 |
| 署名・アーカイブ | 証明書、プロファイル、キーチェーン | 署名済み成果物を検証可能 |
単純なShellコマンドが成功しても、Xcode CIの本番復旧とは言えません。テスト結果の扱いはXcodeのテスト結果に関する公式資料を基準にし、署名やアーカイブはAppleの署名済みコード作成資料に合わせて検証します。
05復旧判定とノードの処置
原因を直した後は、表示が「オンライン」になった時点で作業を終えないでください。次のチェックを実行し、すべて確認できた場合だけ本番キューへ戻します。
- [ ] コントローラーのログに新しい接続エラーがない
- [ ] Agentプロセスの終了時刻と標準エラーを確認した
- [ ] ノードのラベルと実行器がジョブ条件に一致している
- [ ] Remote Root DirectoryへAgentユーザーが読み書きできる
- [ ] macOSを再起動してもAgentが復帰する
- [ ] ログアウトまたはVNC切断後も常駐する
- [ ] 基本Shell、Xcodeビルド、テストを別々に実行した
- [ ] 署名が必要なジョブでは証明書とプロファイルを確認した
- [ ] コントローラー再起動後に手動操作なしで再接続した
復旧、再構築、隔離はどう判断すべきでしょうか。
単発のJavaプロセス停止、設定ミス、権限変更で、原因と再発条件を説明できるなら原地修復で足ります。再起動後だけ失敗する、ネットワーク断から戻らない、ユーザー環境が毎回変わる、署名状態が消えるといった症状が続くなら、ノードを本番キューから隔離します。
| 判断 | 適した状態 | 次の行動 |
|---|---|---|
| 原地修復 | 原因が一つで再発条件を説明できる | 設定修正後に全検証を再実行 |
| ノード隔離 | 接続や環境の不安定さが継続 | 影響を止め、ログと成果物を保全 |
| ノード再構築 | 環境漂流や署名状態の破損が反復 | 新しいノードで受け入れ試験 |
| 独立ノード追加 | 単一ノード障害が公開作業を止める | Xcode CI用の予備経路を用意 |
長期的に自分で管理するMacが必要なら、VpsMeshのMacレンタル構成を候補に含め、root権限、再起動方法、接続方式、Xcodeの受け入れ試験を先に確認してください。既存のMac miniを購入する案と比べる場合も、初期費用だけでなく、交換、保守、常時稼働、障害時の復旧担当まで並べて判断します。実機購入の条件を整理したい場合は、Mac miniの選定ガイドも比較材料になります。
手元のWindowsやLinuxからSSHで入れるだけの構成は、JenkinsのAgent通信、macOSの常駐、Xcodeの署名環境を別々に管理しなければならず、原因の切り分けが長引きます。物理的な交換待ち、ログインセッション依存、環境の漂流も、継続的なXcode CIでは現実的な負担になります。自前のMacを常時稼働させる余裕がなく、独立して再起動できるmacOS環境を早く用意したいなら、VpsMeshのリモートMacを使って新しい構築ノードを検証する方が、修復不能な既存ノードへスクリプトを追加し続けるより合理的です。