在长时间运行的 GKE 集群的生命周期内,由于Cloud de Confiance by S3NS 导致的基础设施中断,工作负载会定期中断。这些自动事件可能会因调度决策(抢占事件)或节点更新(包括 GKE 节点自动升级 [维护事件] 或检测到的问题修复 [终止事件])而发生。
本文档可帮助您了解节点中断在 GKE 中的含义,监控 Compute Engine 维护通知,并最大限度地减少中断在 GKE 节点中的影响。
本文档适用于以下机器类型:
- 挂接了 GPU 或 TPU 的机器类型
- 挂接了超过 18 TiB Titanium SSD 的 Z3 机器类型
- H4D 机器类型
- C4A 机器系列中的裸金属实例。如需了解详情,请参阅“GKE 上的 Arm 工作负载”文档中的要求和限制部分。
- 使用不支持实时迁移的机器类型的机密 GKE 节点。
本文档适用于管理底层技术基础设施生命周期的平台管理员和运维人员。如需详细了解我们在 Cloud de Confiance by S3NS 内容中提及的常见角色和示例任务,请参阅常见的 GKE 用户角色和任务。
基础设施中断在 GKE 中意味着什么?
GKE 集群会管理 GKE 节点的生命周期。这些节点预配在 Compute Engine 虚拟机上,而 Compute Engine 虚拟机会定期遇到以下中断:
检测到的问题的补救措施 (
TerminationEvent):这些事件的发生是因为 Cloud de Confiance by S3NS 检测到问题并中断了集群基础架构。TerminationEvent事件不支持安全关停。 以下问题会触发TerminationEvent事件:维护或升级事件 (
MaintenanceEvent):当 Cloud de Confiance by S3NS 必须中断虚拟机以执行维护时,会发生这些事件。这些事件由以下维护任务触发:如需详细了解您和 GKE 如何在集群生命周期内管理更改,请参阅更改类型。
对调度决策的响应 (
PreemptionEvent):当 Cloud de Confiance by S3NS 必须抢占虚拟机以使容量可用于更高优先级的资源时,会发生这些事件。PreemptionEvent事件可以是以下任何一种:
在长时间运行的 GKE 集群的生命周期内,节点可能会遇到工作负载定期中断。当这些中断影响运行工作负载的 GKE 节点时,GKE 必须重启正在运行的工作负载和底层节点。
为何不支持实时迁移的节点需要中断管理
大多数 Compute Engine 虚拟机(但有一些例外情况)的主机维护政策设置为实时迁移,这意味着正在运行的工作负载通常不会中断,或者几乎不会中断。不过,某些类别的虚拟机不支持实时迁移,包括挂接了 GPU 和 TPU 的虚拟机、挂接了超过 18 TiB SSD 的 Z3 机器类型、H4D 机器类型和 c4a-highmem-96-metal 机器类型。例如,当 TPU 切片中的虚拟机发生主机事件时,整个切片会中断,然后重新计划,因为所有维护事件都是在切片级别协调的。因此,如果您创建的 TPU 切片包含数百个虚拟机,那么所有这些虚拟机都会收到相同的维护事件时间表。
发生主机事件时,GKE 会终止节点及其 Pod。如果 Pod 是作为更大的工作负载(例如作业或部署)的一部分部署的,GKE 会在受影响的节点上重启 Pod。
管理维护事件
本文档的其余部分将介绍如何管理MaintenanceEvent中断。
在主机维护事件期间管理节点中断遵循以下三阶段工作流程:
- 检测预定的主机维护:使用 GKE 节点标签、元数据端点或日志。
- 针对检测到的维护采取行动:如果已安排维护,请评估您的基础设施和工作负载,并确定最适合您使用情形的行动。采取适当的操作,例如让系统自动处理维护事件、手动启动主机维护或编排维护策略。
- 验证维护事件的结果:验证维护事件是否已正确启动,无论是在 Compute Engine 按计划启动维护事件时,还是在您手动启动维护事件时。
检测计划的宿主机维护
在虚拟机发生预定的维护事件之前,Compute Engine 会向其所有虚拟机推送通知。这些通知会报告 Compute Engine 维护窗口的开始时间。如果虚拟机已预定即将进行的维护,但该维护尚未开始,GKE 会向节点标签添加 scheduled-maintenance-time。
如需监控和检测即将到来的维护事件,您必须查看来自 GKE 和 Compute Engine 的通知:
查看 Compute Engine 上即将进行的维护:当已为节点及其底层虚拟机计划中断性主机事件时,以及当这些事件开始时,Compute Engine 会发出通知。通知包含计划的开始时间、事件类型以及其他详细信息。
查看 GKE 中即将进行的维护:在 GKE 1.31.1-gke.2008000 版本及更高版本中,您可以监控即将发生的维护事件。您可以监控以下机器类型和 GKE 版本的即将发生的事件:
- 对于挂接了 GPU 或 TPU 的机器类型,版本为 1.31.1-gke.2008000 或更高版本
- 对于 SSD 容量超过 18 TiB 的 Z3 机器类型,版本为 1.32.4-gke.1376000 或更高版本
- 对于 H4D 机器类型,版本为 1.32.6-gke.1060000 或更高版本
- 对于
c4a-highmem-96-metal,1.35.0-gke.2232000 或更高版本
如需在节点级别查询这些通知,请运行以下命令:
kubectl get nodes -l cloud.google.com/scheduled-maintenance-time \ -L cloud.google.com/scheduled-maintenance-time输出类似于以下内容:
NAME STATUS SCHEDULED-MAINTENANCE-TIME <gke-accelerator-node-name> Ready 1733083200 <gke-accelerator-node-name> Ready 1733083200 [...]SCHEDULED-MAINTENANCE-TIME列表示秒数,以 Unix 纪元时间格式显示。如需在节点元数据级别查询这些通知,请检查实例是否存在维护事件通知。
对于支持高级维护的加速器优化机器家族,您可以访问
upcoming-maintenance端点,该端点会提供有关已计划和已开始的维护事件的信息。
针对检测到的维护采取行动
如果您看到集群中一个或多个节点的计划内维护即将开始的通知,请使用以下决策树来确定处理中断的最佳方式:
自动维护:让 Compute Engine 按计划启动维护事件。您的虚拟机将在后台自动实时迁移,几乎不会中断或完全不会中断。
- 如果宿主机虚拟机支持实时迁移,建议您让维护事件自动发生。
- 如果您的工作负载在空闲灵活节点上运行,您可以配置机会性维护,以自动优化维护时间。这样一来,系统仅会在自然空闲时段触发必要的更新。
手动启动主机维护事件:请评估以下问题,以确定手动处理中断的最佳方式:
受影响的节点是单个虚拟机还是隔离的虚拟机?
- 是(我运行的是单个或隔离的虚拟机):
- 如果您不需要精确的时间控制,请让 Compute Engine 按计划启动维护事件(默认自动)。
- 如果您需要避免意外抢占,请在方便的时间(例如流量较少的时段)手动启动单个节点上的主机维护事件。
- 否(我正在运行加速器节点池):请选择下一步中的某个选项。
- 是(我运行的是单个或隔离的虚拟机):
根据您的使用情形,选择以下选项之一:
在单个虚拟机或隔离虚拟机上手动启动主机维护事件
您可以在适合您安排的时间(例如活动较少的时段)手动启动可重新安排的维护。为此,请在满足以下条件时应用 cloud.google.com/perform-maintenance=true 标签:
- Compute Engine 会针对计划维护事件发出通知。
- 底层 Compute Engine 维护事件是可重新安排的。如需检查事件是否可重新安排,请在事件元数据中查找
can_reschedule=TRUE通知。如果事件不可重新安排,则设置cloud.google.com/perform-maintenance=true标签没有任何效果,维护将按原定时间安排进行。
如果满足上述条件,请在节点池中的节点上,将节点标签 cloud.google.com/perform-maintenance 设置为 true。例如:
kubectl label nodes <node-name> cloud.google.com/perform-maintenance=true
如果您启动维护事件,GKE 会执行以下操作:
- 为节点添加污点。
- 正常逐出 Pod。
- 请求 Compute Engine 立即开始维护事件,而不是等待预定时间。
验证维护事件的结果
检测到即将进行的维护事件并确定最佳行动方案后,您可以验证维护事件的结果。
Compute Engine 按计划启动维护事件
维护事件开始后,节点可能会关机一次或多次,并在即将终止之前发出简短的通知。在这些情况下,GKE 会尽最大努力终止工作负载并正常逐出 Pod。
计划的维护开始
当计划的维护开始时,Compute Engine 会更新 http://metadata.google.internal/computeMetadata/v1/instance/attributes/ 目录中的元数据。Compute Engine 会按如下方式更新元数据标签:
- 将
maintenance-event设置为TERMINATE_ON_HOST_MAINTENANCE。 - 在
upcoming-maintenance中,将maintenance_status设置为ONGOING。
无论您是手动触发还是让 GKE 自动继续,GKE 都会检测并处理预定主机维护事件。
以下 GKE 系统指标会报告自上次采样以来 GKE 节点的中断次数(该指标每 60 秒采样一次):
kubernetes.io/node/interruption_count
interruption_type(例如 TerminationEvent、MaintenanceEvent 或 PreemptionEvent)和 interruption_reason(例如 HostError、Eviction 或 AutoRepair)字段有助于您了解节点中断的原因。
如需获取项目集群中 TPU 节点中断及其原因的细分信息,请使用以下 PromQL 查询:
sum by (interruption_type,interruption_reason)(
sum_over_time(
kubernetes_io:node_interruption_count{monitored_resource="k8s_node"}[${__interval}]))
如需仅查看主机维护事件,请更新查询以在 interruption_reason 中过滤出 HW/SW Maintenance 值。请使用以下 PromQL 查询:
sum by (interruption_type,interruption_reason)(
sum_over_time(
kubernetes_io:node_interruption_count{monitored_resource="k8s_node", interruption_reason="HW/SW Maintenance"}[${__interval}]))
如需查看按节点池汇总的中断次数,请使用以下 PromQL 查询:
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=NODE_POOL_NAME }[${__interval}]))
可最大限度减少中断的高级配置
本部分介绍了用于配置集群和工作负载以最大限度减少中断的其他工具。
启用中断处理
apiVersion: v1
kind: ConfigMap
metadata:
name: gke-disruption-handling
namespace: kube-system
data:
maintenance-experience.yaml: |
gracefulTermination: true
如需启用中断处理,请使用此 ConfigMap 创建一个名为 maintenance-config.yaml 的文件。使用以下命令将 ConfigMap 应用到集群:
kubectl apply -f my-configmap.yaml
配置 GKE 以正常终止工作负载
在本部分中,您将配置 GKE 以管理应用生命周期并最大限度地减少工作负载的中断。如果您未配置宽限期,则宽限期默认为 30 秒。
GKE 会尽最大努力正常终止这些 Pod 并执行您定义的终止操作,例如保存训练状态。GKE 会在宽限期开始时向 Pod 发送 SIGTERM 信号。如果 Pod 未在宽限期结束前退出,GKE 会向仍在 Pod 中的任何容器中运行的任何进程发送跟进 SIGKILL 信号。
如需配置正常终止期,请在 Pod 清单的 spec.terminationGracePeriodSeconds 字段中设置终止宽限期(秒)。例如,如需获得 10 分钟的通知时间,请将 Pod 清单中的 spec.terminationGracePeriodSeconds 字段设置为 600 秒,如下所示:
spec:
terminationGracePeriodSeconds: 600
我们建议您设置的终止宽限期足够长,以便任何正在进行的任务在通知时间范围内完成。
如果您的工作负载使用机器学习框架(例如 MaxText、Pax 或带有 Orbax 的 JAX),则工作负载可以捕获关停 SIGTERM 信号并启动检查点过程。如需了解详情,请参阅 TPU 自动检查点。
正常终止的过程
当手动启动的维护事件开始时,Compute Engine 会通过更新 maintenance-event 元数据键来发出即将关停机器的信号。GKE 开始正常终止。
以下工作流展示了 GKE 在即将关停节点时如何正常终止节点:
- 在 60 秒内会发生以下情况:
- 系统组件将应用设置为
ONGOING的cloud.google.com/active-node-maintenance节点标签,以指示工作负载正在停止过程中。 - GKE 会应用节点污点来防止在该节点上安排新的 Pod。污点具有
cloud.google.com/impending-node-termination:NoSchedule键。我们建议您不要修改工作负载,以容忍由于发生已知终止而导致的此污点。
- 系统组件将应用设置为
- maintenance-handler 组件会开始逐出 Pod,首先逐出工作负载 Pod,然后逐出系统 Pod(例如 kube-system)。
- GKE 会向节点上正在运行的工作负载 Pod 发送
SIGTERM关停信号,以提醒它们即将关停。Pod 可以使用此提醒来完成任何正在进行的任务。GKE 会尽最大努力正常终止这些 Pod。 - 驱逐完成后,GKE 会将
cloud.google.com/active-node-maintenance标签的值更新为terminating,以指示节点已准备好进行终止。
之后,系统会执行节点终止并分配替换节点。该过程完成后,GKE 会清除标签和污点。如需延长使用 GPU 或 TPU 的工作负载的终止时段,请完成手动启动主机维护事件部分中的步骤。
验证活跃正常终止的进度
您可以按以下正常终止事件过滤 GKE 日志:
- 当虚拟机检测到因即将发生的节点终止(例如 Compute Engine 主机维护事件)而导致中断时,GKE 会在工作负载正在停止时将
cloud.google.com/active-node-maintenance设置为ONGOING,并在工作负载完成且节点准备好进行终止时将其设置为terminating。 - 在限制安排新的工作负载时,GKE 会应用
cloud.google.com/impending-node-termination:NoSchedule污点。
通过机会性维护最大限度地减少对正在运行的工作负载的干扰
当 GKE 检测到具有 GPU 或 TPU 的节点处于空闲状态时,会自动触发维护,从而最大限度地减少对正在运行的工作负载的干扰。如需启用此功能,请创建新的节点池。您无法在现有节点池上启用机会性维护。
创建具有机会性维护的新节点池
以下命令演示了如何创建启用了抢占式维护的节点池:
gcloud beta container node-pools create NODE_POOL_NAME \
--cluster CLUSTER_NAME \
--accelerator ACCELERATOR_ARG \
--machine-type MACHINE_TYPE \
--num-nodes NODE_COUNT \
--zone ZONE \
--project=PROJECT_ID \
--opportunistic-maintenance=node-idle-time=NODE_IDLE_TIME,min-nodes=MIN_NODES,window=WINDOW
替换以下值:
NODE_POOL_NAME:GKE 节点池的名称。CLUSTER_NAME:GKE 集群的名称。NODE_IDLE_TIME:在触发维护之前,节点可以保持空闲(即没有运行消耗加速器的工作负载)的时间量。该值表示以秒为单位的时长,最多包含 9 位小数,并以s字符结尾,例如:80000s。MIN_NODES:节点池中必须可用的节点数下限。如果维护会导致运行的节点数低于此值(例如10),此选项会阻止维护。WINDOW:机会性维护可以运行的时间窗口(以秒为单位)。该值以s字符结尾。例如,14 天(即1209600s)的值表示机会性维护只能在预定维护日期之前的两周内运行。28 天(即2419200s)的值表示机会性维护可以在预定维护窗口期间的任何时间运行。Compute Engine 主机维护的此窗口与 GKE 维护窗口不同,后者用于确定 GKE 集群维护可以发生的时间,并且是单独配置的。
机会性维护的配置示例
请参考以下示例。您有一个包含 4 个节点的节点池,并且机会性维护配置已设置为 --opportunistic-maintenance=node-idle-time=600s,window=2419200s,min-nodes=3。在此场景中,会发生以下情况:
node1上运行着 GPU 工作负载。此节点不处于空闲状态,因此会被跳过。node2已空闲 60 秒。此节点空闲时间不足,因此被跳过。node3已空闲 600 秒。此节点满足空闲要求。node4已空闲 600 秒。此节点满足空闲要求。
node3 和 node4 都满足空闲要求。不过,只有其中一个节点会触发机会性维护,因为 min-nodes 选项的值设置为 3。
检查具有机会性维护的节点的配置和状态
运行以下命令,检查是否为节点配置了机会性维护:
kubectl describe node NODE_NAME | grep node.gke.io/opportunistic-config
将 NODE_NAME 替换为您要检查的节点的名称。
检查配置了机会性维护的节点是否正在进行维护:
kubectl describe node NODE_NAME | grep node.gke.io/maintenance-state
如果节点是由机会性维护触发的,则 maintenance-state 注解会显示 opportunistic-triggered 为 true。
限制
请注意机会性维护的以下限制:
- 此功能只能与 GPU 和 TPU 节点池搭配使用。
- 机会性维护与集群自动扩缩不兼容,因为集群自动扩缩器已缩减空闲节点。
- 对于多主机 TPU 节点池,
min-nodes-per-pool设置的值应为0,因为这些节点池是原子性的。 - 支持的最低 GKE 版本为 1.33.3-gke.1118000。
- 仅支持包含
can_reschedule=TRUE通知的计划内维护。 - 如需停用此功能,您必须重新创建不使用相应标志的节点池。或者,您可以使用
cloud.google.com/opportunistic-disable=true手动在特定节点上停用该功能。 - 在极少数情况下,节点上的维护可能需要更长时间才能完成。使用此功能的客户可能会在一段时间内遇到可用节点数量减少的情况,最少可降至
min-nodes-per-pool设置的值。