Kubernetes 集群的稳定性很大程度上依赖于节点心跳机制。每个节点上的 kubelet 会定期向 API Server 上报节点状态,controller-manager 中的 node lifecycle controller 则持续监控这些心跳,一旦超过宽限期仍未收到上报,节点就会被置为 NotReady 状态,进而触发 Pod 驱逐等连锁反应。理解心跳延迟的判定阈值,以及延迟背后的网络问题排查思路,对集群运维来说是一项基本功。

一、心跳机制的核心参数与默认阈值
Kubernetes 的心跳判定由三个核心参数共同决定,它们分布在 kubelet 和 kube-controller-manager 两端,理解三者的关系是掌握阈值的第一步。
第一个参数是 kubelet 侧的 --node-status-update-frequency,默认值为 10s,表示 kubelet 每隔 10 秒向 API Server 上报一次节点状态。这个上报动作就是所谓的心跳,注意它并不单纯是 ping 包,而是包含节点资源使用、地址、条件等完整信息的 Status 更新请求。
第二个参数是 controller-manager 侧的 --node-monitor-grace-period,默认值为 40s(1.18 之前部分版本为 50s)。这是判定节点 NotReady 的核心宽限期:如果 controller-manager 在连续 40 秒内没有收到某节点的心跳,就会将该节点的 Ready Condition 置为 Unknown,随后标记节点为 NotReady。
第三个参数是 --pod-eviction-timeout(默认 5 分钟,已在较新版本中废弃,改由 taint-based eviction 机制替代),表示节点 NotReady 后多久开始驱逐其上的 Pod。三个参数满足这样的经验公式:宽限期应大于等于心跳间隔的数倍,官方建议 node-monitor-grace-period 至少为 node-status-update-frequency 的 5 到 10 倍,以容忍偶发的网络抖动和 API Server 延迟。
二、心跳延迟的分层判断标准
明确了参数含义后,可以给出一套分层的延迟判断标准,便于在实际运维中快速定位异常级别。
第一层是正常范围。心跳间隔 10 秒加上 API Server 处理和 etcd 写入的耗时,心跳在几秒内完成都属于健康状态。可以通过 kubectl get nodes -o wide 观察节点的 AGE 与 STATUS,配合事件流确认无异常。
第二层是轻微抖动。延迟在 10 到 40 秒之间,尚未触发宽限期,节点仍为 Ready,但事件中可能出现 NodeNotReady 前兆或者 kubelet 日志中的重试记录。此时通常是网络偶发丢包或 API Server 短时负载过高,建议持续观察并采集监控数据,暂时不需要人工干预。
第三层是超过宽限期。心跳中断超过 40 秒,节点进入 NotReady 或 Ready=Unknown 状态,这就是明确的异常信号。此时需要立即排查,因为驱逐计时已经启动。可以通过下面命令快速确认节点的条件详情:
kubectl describe node worker-01 | grep -A 5 Conditions # 观察Heartbeat相关的Event kubectl get events --field-selector involvedObject.name=worker-01 --sort-by=.lastTimestamp
第四层是长时间无心跳。如果节点 NotReady 持续超过 5 分钟(或 taint 机制配置的容忍时间),Pod 开始被驱逐,业务受影响已经从风险变成事实,排查优先级最高。
三、心跳延迟的常见根因与排查方法
心跳中断的原因并不一定在网络本身,需要按层次逐一排除。以下按照实际排查中的出现频率排序。
第一种是 API Server 过载。kubelet 心跳要经过 API Server 写入 etcd,当 API Server 响应缓慢或 etcd 出现磁盘 IO 瓶颈时,所有节点的心跳会同时变慢,表现为多个节点批量 NotReady。判断方法是查看 apiserver 的指标,如果 apiserver_request_latencies_summary 明显升高,或者 etcd 的 wal fsync 延迟超过 50ms,根因就在控制面而不是节点网络。可以查看:
# 查看apiserver请求延迟分布 kubectl get --raw /metrics | grep apiserver_request_duration_seconds # 检查etcd健康与磁盘性能 etcdctl endpoint status --write-out=table
第二种是节点网络问题。物理网络丢包、MTU 不匹配、交换机故障、跨机房专线抖动都会导致心跳超时。这类问题的特征是少数节点异常且伴随 TCP 重传。可以在节点上执行 ping 和 mtr 检测到 API Server 的链路质量,用 ss -ti 观察 TCP 重传统计。kube-proxy 或 CNI 插件异常也可能只影响 Pod 网络而不影响心跳,需要区分心跳走的是节点网络而非 Pod 网络。
第三种是 kubelet 本身卡顿。kubelet 的 PLEG(Pod Lifecycle Event Generator)在容器运行时响应缓慢时会阻塞状态更新,历史上著名的 PLEG not healthy 问题就是典型代表。判断方法是查看 kubelet 日志中的 PLEG is not healthy 字样,并在节点上观察容器运行时(containerd 或 docker)的响应情况。如果日志中出现:
kubectl logs -n kube-system kubelet-worker-01 | grep -i pleg # 典型输出:PLEG is not healthy: pleg was last seen active 3m12s ago
那么问题在节点侧的容器运行时,可能是镜像仓库阻塞、磁盘 IO 高或者容器数量过多导致。
第四种是时钟漂移。节点系统时间偏差虽然不直接阻断心跳,但会影响证书校验和事件排序,大规模集群中曾出现因 NTP 不同步引发的批量异常。定期校验各节点时间同步状态是必要的巡检项。
四、参数调优与实践建议
默认参数在大多数场景下够用,但在网络质量一般的跨机房集群或超大规模集群中,合理调整参数能显著减少误判。
如果集群规模超过数百节点,API Server 负载偏高导致心跳批量延迟,可以适当调大 --node-status-update-frequency 到 15s 或 20s,同时同步调大宽限期,保持比例关系。反过来,如果业务对故障切换速度要求极高,希望尽快发现节点故障,可以下调到 5s,但必须确保控制面有足够容量承载翻倍的上报流量,否则适得其反。
# kubelet侧配置示例(kubeadm部署) # /var/lib/kubelet/config.yaml nodeStatusUpdateFrequency: 10s # controller-manager侧 --node-monitor-grace-period=40s --node-monitor-period=5s
另外,1.19 及以上版本引入了 Node Lease 机制,节点心跳从全量 Status 更新改为更轻量的 Lease 对象更新,大幅降低了控制面压力。确认集群已启用该特性(kubelet 默认开启),可以有效改善大规模集群的心跳效率。
最后,建议为心跳延迟建立分级告警:延迟超过 20 秒告警提示,超过 40 秒触发严重告警并自动执行诊断脚本采集节点网络、kubelet 日志和 API Server 指标。这样一旦真实故障发生,排查所需的第一手数据已经就位,能大幅缩短定位时间。心跳延迟看似只是一个小指标,背后牵涉 kubelet、API Server、etcd、网络链路四个环节,掌握分层判断思路,才能在故障发生时从容应对。
Kubernetes心跳网络延迟集群排查修改时间:2026-09-07 11:42:53