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. 02检查 JobSet 重启指标
  3. 03排查节点池中断事件
  4. 04关联节点与物理主机
  5. 05检查 Pod 状态及工作容器日志
  6. 06提供分级处置建议

适用场景

  1. 01分析 JobSet 重启循环
  2. 02定位 Spot 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 查询 - 重启
  • 方法:通过 shell 命令执行(需要 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 查询 - 中断
  • 方法:通过 shell 命令执行(需要 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 关联起来,查看是否有单台故障主机反复导致协调器 Pod 失败。

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 查询 - 节点状态
  • 方法:通过 shell 命令执行(需要 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 状态阶段,并获取协调器 Worker 日志,以识别应用级崩溃或网络死锁。

A. 指标查询(Pod 生命周期阶段)
选项 A:可视化图表(MQL)- Pod 阶段
  • 使用工具: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 阶段
  • 方法:通过 Shell 命令执行(需要 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:隔离故障 Host VM [高风险]

如果步骤 3 确认某个特定主机 ID(gce-topology-host)在多次尝试中持续发生故障或触发重启:

  • 操作:起草建议,隔离并排空 GKE 节点、删除底层 GCE VM 实例以触发实例重建,并向 Google Cloud Support 提交支持工单,注明物理主机 ID。
  • 理由:GKE 自动修复会在健康的物理硬件上重建 VM 实例,避免无限重启循环。
  • 自动化:在隔离或排空任何节点之前停止操作,并请求用户明确确认。

📋 复制粘贴检查清单

  • 获取上下文并计算 [T - 30m, T + 30m] 时间窗口。
  • 查询 JobSet 重启尝试次数。
  • 检查 Nodepool 中断(Spot 抢占与硬件终止)。
  • 查询节点到主机的映射,并检查节点日志中的物理主机错误。
  • 检查 Pod 时间线状态和协调器 Worker 容器日志。
  • 建议合适的调度策略(On-demand 或 Spot),或隔离 Host VM。

评论

支持 Markdown