mcpField
G
gke-ai-troubleshooting-jobset-interruption

gke-ai-troubleshooting-jobset-interruption

github.com/googlecloudplatformクラウド・DevOps16945 回インストール3 日前に更新
リポジトリ

gke-ai-troubleshooting-jobset-interruption について

大規模なAI/MLワークロードを実行するGKEクラスター向けに、JobSetの中断を調査する手順を示すスキルです。運用担当者がメトリクス、ログ、ノード、コンテナを順に確認でき、高リスク操作は確認を求める構成です。

主な機能

  1. 01クラスターと障害時刻の情報収集
  2. 02JobSetの再起動メトリクス確認
  3. 03ノードプール中断の調査
  4. 04ノードと物理ホストの関連付け
  5. 05Pod状態とワーカーログの確認
  6. 06リスク別の対処案提示

活用シーン

  1. 01JobSetの再起動ループの分析
  2. 02Spot VMのプリエンプションや保守イベントの特定
  3. 03ノードやホストの障害調査
  4. 04ワーカーPodの未スケジュールやコンテナ異常の診断

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/googlecloudplatform/gke-mcp --skill gke-ai-troubleshooting-jobset-interruption

インストール後、Claude Code で/gke-ai-troubleshooting-jobset-interruptionを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

BUILD
EVAL.yaml
README.md
TEST.md
evals/faulty_physical_host_detected/
task.yaml
evals/missing_context/
task.yaml
evals/no_active_nodes_fallback_or_clean_telemetry/
task.yaml
evals/no_jobset_restarts_detected/
task.yaml
evals/single_node_unready_no_host_correlation/
task.yaml
evals/spot_preemption_detected/
task.yaml
evals/unschedulable_pods_resource_exhaustion/
task.yaml
references/
failure_signatures.md
scripts/
validate_queries.sh

詳細

GKE JobSet の中断に関するトラブルシューティング

大規模な AI/ML ワークロードを実行する GKE クラスターで発生する JobSet の中断、再起動、プリエンプションを体系的に診断し、解決するには、このスキルを使用します。

⚠️ 前提条件

  • クラスターで kube-state-metrics の JobSet メトリクスパッケージが有効になっている必要があります(KSM JobSet Metrics を参照)。
  • Google Cloud プロジェクトで Cloud Logging と Cloud Monitoring が有効になっている必要があります。

🔍 診断ワークフロー

ステップ 0:コンテキストの取得と時間範囲の定義

トラブルシューティングを開始するには、ユーザーから次の情報を取得します。

  • プロジェクト ID(例:customer-ai-project-123)
  • クラスター名(例:tpu-cluster-prod)
  • ワークロード名(JobSet 名)(例:llama3-70b-training)
  • ワークロードの名前空間(例:default)
  • 問題が発生した時刻(例:2026-05-20T08:15:00Z)
時刻の取り扱いルール
  1. 相対時刻は受け付けない:「X 分前」や「たった今」とユーザーが伝えた場合は、処理を中断し、正確なタイムスタンプまたは具体的な時間範囲を尋ねます。
  2. 時間範囲の計算:ユーザーが単一のタイムスタンプ T を指定した場合、クエリの時間範囲を [T - 30m] から [T + 30m] として計算します。
    • Start_Time = T - 30m
    • End_Time = T + 30m

ステップ 1:JobSet の再起動と試行回数を特定する[低リスク]

JobSet で再起動ループが発生しているかを確認し、再起動頻度を特定します。

オプション A:可視化チャート(MQL)— 再起動
  • 使用するツール:monitoring_time_series_chart
  • MQL クエリ:
    fetch prometheus_target
    | metric 'prometheus.googleapis.com/kube_jobset_restarts/gauge'
    | filter resource.cluster_name == '<cluster_name>' && metric.jobset_name == '<workload_name>'
    | align next_older(1m)
    | every 1m
    | group_by [metric.jobset_name], [val: max(value)]
    
オプション B:PromQL クエリ — 再起動
  • 方法:シェルコマンドで実行します(BypassSandbox: true が必要です)。
  • コマンドテンプレート:
    curl -sSf -H "Authorization: Bearer \$(gcloud auth print-access-token)" \
      "https://monitoring.googleapis.com/v1/projects/<project_id>/location/global/prometheus/api/v1/query?query=kube_jobset_restarts%7Bjobset_name%3D%22<workload_name>%22%2Ccluster%3D%22<cluster_name>%22%7D"
    
  • 判定方法:再起動数がゼロ以外、または増加している場合、ワーカーの障害や中断が原因でコントローラーが JobSet を継続的に再起動していることを示します。
  • 自動化:調査結果を報告した後、自動的にステップ 2 に進みます。

ステップ 2:ノードプールの中断を調査する[低リスク]

JobSet の再起動が、物理ノードプールレベルのイベント(Spot のプリエンプション、メンテナンス、ホストの終了など)によって引き起こされたかを確認します。

A. メトリクスクエリ(ノードプールの中断回数)
オプション A:可視化チャート(MQL)— 中断
  • 使用するツール:monitoring_time_series_chart
  • MQL クエリ:
    fetch k8s_node_pool
    | metric 'kubernetes.io/node_pool/interruption_count'
    | filter cluster_name == '<cluster_name>'
    | align next_older(10m)
    | every 10m
    | group_by [metric.interruption_type, metric.interruption_reason, metadata.system.node_pool_name], [val: sum(value)]
    
オプション B:PromQL クエリ — 中断
  • 方法:シェルコマンドで実行します(BypassSandbox: true が必要です)。
  • コマンドテンプレート:
    curl -sSf -H "Authorization: Bearer \$(gcloud auth print-access-token)" \
      "https://monitoring.googleapis.com/v1/projects/<project_id>/location/global/prometheus/api/v1/query?query=sum%20by%20%28interruption_type%2C%20interruption_reason%2C%20node_pool_name%2C%20cluster_name%29%20%28avg_over_time%28%7B__name__%3D%22kubernetes.io%2Fnode_pool%2Finterruption_count%22%2C%20monitored_resource%3D%22k8s_node_pool%22%2C%20cluster_name%3D%22<cluster_name>%22%7D%5B10m%5D%29%29"
    
B. ログクエリ(ノードプールのライフイベント)
  • 使用するツール:query_logs
  • LQL ログフィルターテンプレート:
    resource.type="gke_nodepool"
    AND resource.labels.cluster_name="<cluster_name>"
    AND timestamp >= "<Start_Time>"
    AND timestamp <= "<End_Time>"
    
  • 判定方法:
    • PreemptionEvent:Spot VM がプリエンプトされたか、ノードがスケールダウンされています。
    • MaintenanceEvent:ノードプールが更新されたか、Google によってメンテナンスが予定されていました。
    • TerminationEvent:深刻なホスト障害です。interruption_reason またはログでホストの問題を確認します。
  • 自動化:自動的にステップ 3 に進みます。

ステップ 3:ノードと基盤となるホスト VM を調査する[低リスク]

ノードのレディ状態の障害と物理ホスト VM を関連付け、単一の障害ホストがコーディネーターポッドの障害を繰り返し引き起こしていないか確認します。

A. メトリクスクエリ(ノードの Ready 状態チェック)
オプション A:可視化チャート(MQL)— ノードの状態
  • 使用するツール:monitoring_time_series_chart
  • MQL クエリ:
    fetch k8s_node
    | metric 'kubernetes.io/node/status_condition'
    | filter cluster_name == '<cluster_name>' && metric.condition == 'Ready' && metric.status == 'False'
    | align next_older(1m)
    | every 1m
    | group_by [node_name, metadata.user.gke_nodepool], [val: max(value)]
    
オプション B:PromQL クエリ — ノードの状態
  • 方法:シェルコマンドで実行します(BypassSandbox: true が必要です)。
  • コマンドテンプレート:
    curl -sSf -H "Authorization: Bearer \$(gcloud auth print-access-token)" \
      "https://monitoring.googleapis.com/v1/projects/<project_id>/location/global/prometheus/api/v1/query?query=sum%20by%20%28status%2C%20condition%2C%20node_pool_name%29%20%28%7B__name__%3D%22kubernetes.io%2Fnode%2Fstatus_condition%22%2C%20monitored_resource%3D%22k8s_node%22%2C%20cluster_name%3D%22<cluster_name>%22%2C%20condition%3D%22Ready%22%2C%20status%3D%22False%22%7D%29"
    
B. メトリクスクエリ(ノードとホストのメタデータトポロジーの相関)
  • 使用するツール:monitoring_time_series_chart
  • MQL クエリ:
    fetch k8s_node
    | metric 'kubernetes.io/node/cpu/total_cores'
    | filter cluster_name == '<cluster_name>'
    | align next_older(1m)
    | every 1m
    | group_by [node_name, metadata.user.gce_topology_host, metadata.user.gke_nodepool], [val: max(value)]
    
C. ログクエリ(ノード障害ログ)
  • 使用するツール:query_logs
  • LQL ログフィルターテンプレート:
    resource.type="k8s_node"
    AND resource.labels.cluster_name="<cluster_name>"
    AND (textPayload:"host error" OR textPayload:"kernel panic" OR textPayload:"hardware failure" OR textPayload:"NodeNotReady")
    AND timestamp >= "<Start_Time>"
    AND timestamp <= "<End_Time>"
    
  • 判定方法:特定のノードが不健全(Ready=False または Unknown)かを特定し、metadata.user.gce_topology_host を使って対応する GCE 物理ホスト ID と関連付けます。同じホストで障害が繰り返し発生していないか確認します。
  • 自動化:自動的にステップ 4 に進みます。

ステップ 4:Pod と Worker/コンテナの障害を調査する[低リスク]

Pod のステータスフェーズを分析し、コーディネーターワーカーのログを取得して、アプリケーションレベルのクラッシュやネットワークのデッドロックを特定します。

A. メトリクスクエリ(Pod のライフサイクルフェーズ)
オプション A:ビジュアルチャート(MQL)- pod phase
  • 使用するツール:monitoring_time_series_chart
  • MQL クエリ:
    fetch k8s_pod
    | metric 'kubernetes.io/pod/status/phase'
    | filter cluster_name == '<cluster_name>' && pod_name ==~ '<workload_name>.*'
    | align next_older(10m)
    | every 10m
    | group_by [metric.phase], [val: count()]
    
オプション B:PromQL クエリ - pod phase
  • 方法:シェルコマンドを実行します(BypassSandbox: true が必要です)。
  • コマンドテンプレート:
    curl -sSf -H "Authorization: Bearer \$(gcloud auth print-access-token)" \
      "https://monitoring.googleapis.com/v1/projects/<project_id>/location/global/prometheus/api/v1/query?query=sum%20by%20%28phase%29%20%28avg_over_time%28%7B__name__%3D%22kube_pod_status_phase%22%2C%20cluster%3D%22<cluster_name>%22%2C%20pod%3D~%22<workload_name>.*%22%7D%5B10m%5D%29%29"
    
B. メトリクスクエリ(スケジュール不能な Pod の数)
  • 使用するツール:monitoring_time_series_chart
  • MQL クエリ:
    fetch k8s_pod
    | metric 'kubernetes.io/pod/status/unschedulable'
    | filter cluster_name == '<cluster_name>' && pod_name ==~ '<workload_name>.*'
    | align next_older(10m)
    | every 10m
    | group_by [pod_name], [val: max(value)]
    
C. ログクエリ(Worker コンテナログ)
  • 使用するツール:query_logs
  • LQL ログフィルターテンプレート:
    resource.type="k8s_container"
    AND resource.labels.cluster_name="<cluster_name>"
    AND labels."k8s-pod/jobset_sigs_k8s_io/jobset-name"="<workload_name>"
    AND timestamp >= "<Start_Time>"
    AND timestamp <= "<End_Time>"
    
  • ロジック:
    1. Pod のタイムラインを確認し、保留中またはスケジュール不能な Pod を特定します。
    2. Worker コンテナログを使用して、スライス 0 の worker 0(コーディネーター)を分析し、NCCL のタイムアウト、集合通信の問題、MegaScale のハングを調べます。
  • 自動化:解決に進みます。

🛠️ 解決ワークフロー

解決策 1:プリエンプションとオートスケーリングの最適化[低リスク]

ステップ 2 で Spot VM のプリエンプション数が多いことが判明した場合:

  • アクション:重要な長時間実行のトレーニングワークロードを GKE Reserved/On-Demand VM に切り替えるか、Compact Placement Policies を使用して、デフラグによる中断を最小限に抑えることを提案します。
  • 根拠:Spot 市場でのプリエンプションをなくし、トレーニングの再起動を減らします。
解決策 2:障害のあるホスト VM を隔離する[高リスク]

ステップ 3 で、複数回の試行にわたって一貫して障害や再起動を引き起こす特定のホスト ID(gce-topology-host)が特定された場合:

  • アクション:GKE ノードをコルドン/ドレインし、インスタンスの再作成を促すために基盤となる GCE VM インスタンスを削除し、物理ホスト ID を明記して Google Cloud Support にサポートチケットを起票することを推奨する案を作成します。
  • 根拠:GKE の自動修復によって、健全な物理ハードウェア上に VM インスタンスが再作成され、再起動の無限ループを防げます。
  • 自動化:ノードのコルドン/ドレインを行う前に停止し、ユーザーの明示的な確認を求めます。

📋 コピー用チェックリスト

  • コンテキストを取得し、[T - 30m, T + 30m] の時間枠を算出します。
  • JobSet の再起動試行をクエリします。
  • Nodepool の中断を確認します(Spot のプリエンプションとハードウェアの終了を比較)。
  • ノードとホストのマッピングをクエリし、物理ホストのエラーがないかノードログを確認します。
  • Pod のタイムラインステータスとコーディネーターの Worker コンテナログを調査します。
  • 適切なスケジューリング戦略(On-demand と Spot のどちらか)またはホスト VM の隔離を推奨します。

コメント