GKE GPU/TPU 节点维护中断排查与防护实战指南:基于 gke-ai-troubleshooting-handle-disruption-gpu-tpu
2026/9/14 1:27:50 网站建设 项目流程

GKE GPU/TPU 节点维护中断排查与防护实战指南:基于 gke-ai-troubleshooting-handle-disruption-gpu-tpu

【免费下载链接】skillsAgent Skills for Google products and technologies项目地址: https://gitcode.com/GitHub_Trending/skills29/skills

GPU 与 TPU 承载着大模型训练、推理等关键 AI 负载,而 Compute Engine 宿主机维护(host maintenance)造成的节点中断是这类负载最常见、也最难以排查的故障源之一。本文以开源仓库中的gke-ai-troubleshooting-handle-disruption-gpu-tpuSkill(定义见 SKILL.md)为核心,系统讲解一套从"上下文收集 → 调度维护标签检查 → PromQL 指标验证 → 日志与污点核查 → 结论与防护策略落地"的完整排查闭环,并深入解析优雅终止(Graceful Termination)、机会性维护(Opportunistic Maintenance)与 PodDisruptionBudget(PDB)三大防护手段的底层原理与配置细节,帮助你准确区分"宿主机维护导致的中断"与"应用自身故障",快速恢复 AI 训练负载。

Skill 定位:何时使用、何时不用

根据该 Skill 的元数据定义,它是一个面向CloudObservabilityAndMonitoring场景的 AI 排查助手,核心能力是:

在 Compute Engine 宿主机维护以及硬件/软件维护事件期间,对 GKE 上的 GPU/TPU 工作负载进行节点中断的诊断、预测与缓解。

它适用于以下场景:

  • 诊断 GPU/TPU 节点池(nodepool)的节点中断(node disruption);
  • 预测 GPU/TPU 节点池上的宿主机维护事件;
  • 检查节点中断相关的 PromQL 指标(kubernetes_io:node_interruption_count);
  • 审计节点污点(node taints);
  • 配置工作负载保护策略(优雅终止、机会性维护、PodDisruptionBudget)。

同时该 Skill 明确标注了反模式(Don't use):不要用它处理通用 GKE 集群创建、网络策略配置或非中断类的工作负载部署问题。这类问题应回到 gke-basics、gke-networking 等对应 Skill。这与仓库中其他 GPU/TPU 排查类 Skill 形成互补:例如 gke-ai-troubleshooting-jobset-interruption 侧重 JobSet 重启与抢占,gke-ai-troubleshooting-tpu-vbar-oom 侧重 TPU v6e 的 vBAR OOM,而本文聚焦"宿主机维护"这一特定中断原因。

前置条件与排查原则

前提条件

执行本排查流程前,确保满足以下条件:

  • 拥有 GKE 集群的kubectl访问权限(用于节点标签、污点检查);
  • 项目已启用 Cloud Logging 与 Cloud Monitoring(用于日志过滤与 PromQL 查询);
  • 集群节点已启用 GKE System Metrics(kubernetes_io:*前缀的指标由 GMS 导出到 Cloud Monitoring)。

两条强制规则

该 Skill 内置两条不可违反的强制规则,值得在排障前先内化:

  1. 上下文强制收集:当用户要求排查实际的工作负载中断、节点崩溃或非预期重启,却没有提供完整集群信息时,必须先停下来索要全部必需参数project_idlocationcluster_nametimestamp),再给出诊断理论或通用命令;只有用户明确要求一份可复用的通用 runbook、或提供了完整的静态遥测/日志转储用于离线分析时,才可以跳过上下文收集。
  2. PromQL 强制规则:凡是推荐进行后续监控或中断跟踪,必须显式给出基于kubernetes_io:node_interruption_count并过滤interruption_reason="HW/SW Maintenance"的 PromQL 表达式,不能只笼统建议"去 Cloud Monitoring 看板"或"用 Metrics Explorer"。

诊断工作流:四步闭环

整个排查流程分为 Step 0 上下文获取与 Step 1~4 四个风险递增的诊断步骤。下面按原文档骨架逐层展开,并结合仓库源码补充细节。

Step 0:上下文获取(Context Acquisition)

在动手查询之前,先收集并确认以下参数:

参数必填/可选说明
project_id必填Google Cloud 项目 ID
location必填集群所在区域或可用区
cluster_name必填GKE 集群名称
timestamp必填故障发生时间点,用于界定查询时间窗
node_name可选疑似故障节点名
workload_name可选受影响的负载名
workload_namespace可选负载所在命名空间
nodepool_name可选节点池名称

时间窗的处理经验可以参考仓库中同类排查 Skill 的做法:在 gke-ai-troubleshooting-jobset-interruption/SKILL.md 中,当拿到故障时间T后,取start_time = T - 30mend_time = T + 30m作为指标与日志的查询窗口。本文场景同样建议以故障时间为中心外扩 30 分钟,确保不会漏掉维护事件前后的信号。

Step 1(低风险):检查即将到来的计划内维护

动作:通过kubectl检查节点上是否存在"计划内维护"标签,该标签预示着即将到来的中断。

示例命令

kubectl get nodes -l cloud.google.com/scheduled-maintenance-time -L cloud.google.com/scheduled-maintenance-time

结果解读

  • 输出中的SCHEDULED-MAINTENANCE-TIME列显示该 VM 被安排进行维护的Unix epoch 时间戳
  • 只要该标签存在,中断就一定会发生(disruption is guaranteed to occur),后续应立即进入防护策略评估,而不是继续怀疑其他原因。

这条命令的用法与仓库中 gke-ai-troubleshooting-tpu-metrics-monitoring 中"基于 GKE 系统指标监控中断"的思路一致:标签与指标是同一事实(维护事件)在两个数据平面上的投影,先看标签成本最低。

Step 2(低风险):通过 Cloud Monitoring(PromQL)调查

动作:调用任何可用的监控工具执行 PromQL,或把查询交给用户手工验证。

核心指标kubernetes_io:node_interruption_countkubernetes_io:node_pool_interruption_count,均来自 Cloud Monitoring 的 GKE System Metrics 指标集(在仓库的 gke-ai-troubleshooting-tpu-metrics-monitoring/SKILL.md 中同样以monitored_resource="k8s_node"/"k8s_node_pool"形式出现)。

节点级查询——抓取节点宿主机维护事件:

# Fetch host maintenance events for nodes sum by (interruption_type,interruption_reason)( sum_over_time( kubernetes_io:node_interruption_count{monitored_resource="k8s_node", interruption_reason="HW/SW Maintenance"}[${__interval}]))

节点池级查询——按节点池聚合中断计数:

# See the interruption count aggregated by node pool sum by (node_pool_name,interruption_type,interruption_reason)( sum_over_time( kubernetes_io:node_pool_interruption_count{monitored_resource="k8s_node_pool", interruption_reason="HW/SW Maintenance", node_pool_name="{nodepool_name}" }[${__interval}]))

其中${__interval}是 Grafana 类仪表盘的自适应区间变量;手工执行时替换为具体的时间窗口(如5m10m)。

结果解读

  • kubernetes_io:node_interruption_countinterruption_reason="HW/SW Maintenance"下取值 > 0,说明底层 Compute Engine VM确实因计划内宿主机维护而被中断
  • 此时interruption_type通常为MaintenanceEvent。作为对照,仓库 gke-ai-troubleshooting-tpu-metrics-monitoring 的故障签名表还给出了其他中断类型的判别:PreemptionEvent(Spot 抢占)、TerminationEvent + HostError(物理宿主机硬件错误,GKE 应触发 AutoRepair)——这些原因不属于宿主机维护范畴,走另一条排查路径。

Step 3(低风险):通过 Cloud Logging 与节点污点调查

动作:调用query_logs(或指导用户在 GKE 日志中过滤),查找活跃的宿主机维护事件,同时检查节点污点。

日志过滤要点:在 Cloud Logging 中查找cloud.google.com/active-node-maintenance被设置为ONGOING的日志条目。

污点检查要点:确认终止中的节点是否已被 GKE 打上cloud.google.com/impending-node-termination:NoSchedule污点——既可以从 GKE 事件日志中看到,也可以直接执行:

kubectl describe node <node_name>

结果解读

  • cloud.google.com/active-node-maintenanceONGOING:说明 GKE正在因宿主机维护而主动停止该节点上的工作负载
  • 出现cloud.google.com/impending-node-termination:NoSchedule污点:说明 GKE 已封锁(cordon)该节点,阻止新 Pod 调度到即将终止的节点上;
  • 重要禁令:不要(DO NOT)建议工作负载通过容忍(tolerate)该污点来强行调度——那会违背 GKE 的保护意图,反而把 Pod 送进正在维护的节点。

关于"封锁"这一动作在 GKE 生态中的意义,可以参考 gke-upgrades/references/troubleshooting.md 等仓库文档中对节点 drain/cordon 流程的描述:维护节点上的 Pod 会被驱逐并迁移到健康节点,PDB 在此过程中约束可中断副本数。

Step 4:结论与处置

动作:向用户汇总排查结论;若宿主机维护事件被确认或已被计划,给出对应的缓解策略。

汇报规则:只报高信号信息

只汇报"中断由 Compute Engine 宿主机维护导致、且具体影响了底层 GPU/TPU 节点"这一高信号结论,不要倾倒原始日志(Signal Only,DO NOT dump raw logs)。

负向结论排除规则

如果以下三个信号全部为空/为负

  1. 节点上不存在 scheduled-maintenance 标签;
  2. PromQL 中断计数为 0;
  3. 活跃维护日志无命中;

果断下结论:该中断不是由 Compute Engine 宿主机维护引起的。此时应引导用户转向应用层原因排查,例如:

  • OOMKill 事件(容器被 cgroup 内存限制杀死);
  • CUDA 运行时错误;
  • 资源限制(limits)配置问题。

并且不要把宿主机维护缓解措施当作首要解决方案。这条"负向排除"逻辑与仓库中 gke-ai-troubleshooting-tpu-vbar-oom 的"cgroup OOM / checksum 损坏"类应用层排查形成衔接:基础设施信号干净时,就应该下沉到应用与设备层。

强制防护三件套(Mandatory Workload Protection Triad)

只要宿主机维护在 GPU/TPU 节点上被识别或预期发生,就必须同时推荐下面三项互补的缓解措施,缺一不可:

  1. 配置优雅终止(Graceful Termination):对需要时间保存状态的工作负载(例如基于 Orbax 的 ML 框架 checkpoint),通过设置spec.terminationGracePeriodSeconds最长可到 60 分钟)来在节点关停前从容处理SIGTERM信号;
  2. 启用机会性维护(Opportunistic Maintenance):当 GKE 检测到 GPU/TPU 节点处于空闲时,自动触发维护,把"随机的强拆"变成"空闲期定点维护";
  3. 配置 PodDisruptionBudget(PDB):确保工作负载使用 PDB 在驱逐与中断期间维持minAvailable副本数。

这三者的关系可以这样理解:机会性维护减少中断次数,优雅终止降低单次中断的损失,PDB 保证中断期间的可用性下限——它们分别从"频率、代价、底线"三个维度形成完整防护。

深入理解三大防护机制

1. 优雅终止:terminationGracePeriodSeconds

GKE 在维护节点时会向节点上的 Pod 发送SIGTERM,等待宽限期结束后再发送SIGKILL。默认宽限期为 30 秒,对需要落盘大 checkpoint(如 Orbax、PyTorch 的 save/load)的分布式训练任务远远不够。

配置要点

  • 在 Pod 或工作负载的spec.terminationGracePeriodSeconds中设置宽限期,GPU/TPU 场景下官方支持的上限为60 分钟
  • 应用必须实现SIGTERM处理器:捕获信号 → 冻结训练步 → 触发 checkpoint 保存 → 优雅退出;
  • 宽限期不是越长越好,应结合 checkpoint 耗时与成本权衡,避免故障转移链路过长。

2. 机会性维护:把中断挪到空闲窗口

机会性维护让 GKE 在检测到节点上无活跃工作负载(或负载空闲)时主动执行宿主机维护,从而:

  • 避免在训练高峰期被强行中断;
  • 让维护事件可预期、可安排。

适用前提

  • 工作负载对维护时间窗口有容忍度(允许 GKE 选择空闲时机);
  • 需要配合"能够被安全中断"的负载设计(可恢复的训练、幂等的保存点)。

3. PodDisruptionBudget:可用性下限

PDB 通过policy/v1资源声明"自愿性中断(voluntary disruptions)"期间最少可用的 Pod 数。宿主机维护导致的驱逐属于自愿性中断,因此 PDB 能有效约束驱逐节奏。

仓库中 gke-reliability/SKILL.md 给出了可直接落地的 PDB 示例:

apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: my-app-pdb namespace: default spec: minAvailable: 2 # Or use maxUnavailable: 1 selector: matchLabels: app: my-app

配置要点

  • minAvailable(最少可用数)或maxUnavailable(最多不可用数)之一声明预算,二者选一;
  • selector.matchLabels必须与工作负载 Pod 的标签匹配;
  • 经验法则(来自 gke-reliability/SKILL.md):每个 2+ 副本的生产级 Deployment 都应配置 PDB
  • 检查现有 PDB:kubectl get pdb --all-namespaces(或通过 MCP 工具get_k8s_resource(resourceType="poddisruptionbudget"))。

注意:PDB 约束的是"驱逐"而不是"节点故障"——节点直接宕机(非自愿中断)不受 PDB 约束,这正是需要把优雅终止、机会性维护一起用上的原因。

与仓库生态的关联与验证路径

指标语义的交叉验证

本 Skill 使用的kubernetes_io:node_interruption_count/kubernetes_io:node_pool_interruption_count指标,在 gke-ai-troubleshooting-tpu-metrics-monitoring/SKILL.md 中有更完整的语义说明:

  • interruption_type取值:TerminationEventMaintenanceEventPreemptionEvent
  • interruption_reason取值:HostErrorEvictionAutoRepair以及本文核心的HW/SW Maintenance

MaintenanceEvent + HW/SW Maintenance命中时,即可确认"宿主机维护"这一根因,与本 Skill Step 2/3 的判读完全一致。

兄弟 Skill 的分工

仓库中围绕 GPU/TPU 中断还有两个高度相关的 Skill,本文场景下可作为后续深化入口:

  • gke-ai-troubleshooting-jobset-interruption:当 JobSet 重启循环、Spot 抢占、宿主 VM 故障或协调器崩溃时使用,其故障签名文档 references/failure_signatures.md 提供了TerminationEvent: ... Host Error、NCCL 超时等可检索日志模式;
  • gke-ai-troubleshooting-tpu-vbar-oom:排查 TPU v6e 的vbar_control_agentOOM 与tpu-device-pluginchecksum 损坏,其脚本 scripts/validate_queries.sh 演示了如何用gcloud logging read对日志过滤表达式做 dry-run 校验。

可复制的验证模式

仓库同类 Skill 提供了一种"脚本化验证查询"的工程实践:在 gke-ai-troubleshooting-jobset-interruption/scripts/validate_queries.sh 中,通过gcloud logging read --limit=1对 LQL 过滤器做干跑校验、通过 GMS Prometheus API(monitoring.googleapis.com/v1/projects/{project}/location/global/prometheus/api/v1/query)对 PromQL 做编译验证。你可以用同样方式,把本文的 PromQL 表达式代入 GMS Prometheus API 做离线校验,把"人工排查"沉淀为"可回归的查询资产"。

排障速查清单

按本 Skill 的排查顺序整理为可勾选清单,便于实际排障时逐项执行:

  • 收集project_idlocationcluster_nametimestamp(故障时间前后各外扩 30 分钟作为查询窗)
  • 检查 scheduled-maintenance 标签:kubectl get nodes -l cloud.google.com/scheduled-maintenance-time -L cloud.google.com/scheduled-maintenance-time
  • 执行 PromQL:节点级kubernetes_io:node_interruption_countinterruption_reason="HW/SW Maintenance")与节点池级kubernetes_io:node_pool_interruption_count
  • 在 Cloud Logging 中过滤cloud.google.com/active-node-maintenance=ONGOING,并检查cloud.google.com/impending-node-termination:NoSchedule污点
  • 三信号全空 → 排除宿主机维护,转向应用层(OOMKill、CUDA 错误、资源限制)
  • 确认/预期维护 → 同时落地:优雅终止(terminationGracePeriodSeconds≤ 60 分钟)+ 机会性维护 + PDB(minAvailablemaxUnavailable

【免费下载链接】skillsAgent Skills for Google products and technologies项目地址: https://gitcode.com/GitHub_Trending/skills29/skills

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询