4、集群节点生命周期:节点注册、节点状态机、NotReady/Cordon/Drain机制

在 Kubernetes 集群中,节点(Node)是承载 Pod 运行的基础单元。理解节点的生命周期管理,是掌握集群扩缩容、故障恢复与 Argo CD 驱动 CRI 接口同步的前提。本章深入剖析节点从注册到退出的完整状态变迁,重点解析 NotReady、Cordon、Drain 三大核心机制。

4.1 节点注册与自注册流程

节点加入集群有两种方式:自注册(kubelet 主动发起)和 管理员手动创建。生产环境绝大多数采用自注册模式。

阶段 操作 关键组件
1. 启动 kubelet 启动,读取配置(kubeconfig、节点名称、CRI 端点) kubelet、kubeconfig
2. 自注册 kubelet 向 API Server 发送 Node 资源创建请求 API Server、etcd
3. 节点验证 API Server 校验 TLS 证书或 Bootstrap kube-controller-manager
4. 状态上报 kubelet 定期上报心跳(NodeStatus),包含条件、容量、地址 kubelet、Node Controller
5. 就绪 Node Controller 将节点标记为 Ready,调度器可分配 Pod kube-scheduler
实践要点:自注册时,kubelet 的 --register-node 参数默认为 true。若需手动管理节点,可设置为 false,然后通过 kubectl create node 创建。

4.2 节点状态机与核心条件

每个节点维护一组 NodeCondition,反映节点当前健康状态。Node Controller 根据 kubelet 上报的心跳与监控数据,驱动状态机转换。

核心 NodeCondition 类型:
  • Ready:节点是否可接受 Pod。True=正常,False=异常,Unknown=心跳超时。
  • DiskPressure:磁盘空间是否不足。
  • MemoryPressure:内存是否紧张。
  • PIDPressure:PID 数量是否接近上限。
  • NetworkUnavailable:网络是否配置正确。

状态机转换规则(以 Ready 为例):

  • kubelet 每 --node-status-update-frequency(默认 10s)上报一次状态。
  • Node Controller 每 --node-monitor-period(默认 5s)检查一次。
  • 若超过 --node-monitor-grace-period(默认 40s)未收到心跳,条件变为 Unknown。
  • 若超过 --pod-eviction-timeout(默认 5m)仍为 Unknown,Node Controller 开始驱逐 Pod。
节点状态机转换图 节点状态机(Ready 条件) Ready (True) NotReady (False) Unknown 心跳异常 恢复心跳 超时未上报 重新上报 持续超时 状态转换触发条件 • Ready → NotReady:kubelet 上报条件为 False(如容器运行时故障) • Ready → Unknown:Node Controller 超过 40s 未收到心跳 • NotReady/Unknown → Ready:kubelet 恢复正常上报且条件为 True 时间线参数(默认值) kubelet 上报间隔 10s → 监控周期 5s → 宽限期 40s → Pod 驱逐超时 5min

4.3 NotReady 机制与故障处理

当节点进入 NotReady 状态,意味着 kubelet 无法正常与 API Server 通信,或容器运行时(CRI)出现故障。Node Controller 会执行以下动作:

  1. 标记节点:将 Node 对象的 status.conditions 中 Ready 条件置为 False。
  2. 停止调度:调度器自动将节点视为不可调度,新 Pod 不会分配至此节点。
  3. 驱逐 Pod:等待 --pod-eviction-timeout(默认 5 分钟)后,开始驱逐节点上的 Pod(由 kube-controller-manager 中的 NodeLifecycleController 执行)。
  4. 容忍度检查:若 Pod 设置了 tolerationSeconds,则驱逐时间可被延长。
注意:NotReady 不等于节点物理宕机。可能是 kubelet 进程挂起、CRI 响应超时、网络分区或磁盘 I/O 阻塞。排查时应先检查 kubelet 日志与 CRI 端点(如 containerd.sock)连通性。

4.4 Cordon 与 Drain:主动运维操作

与 NotReady 的被动故障不同,Cordon 和 Drain 是管理员主动执行的节点运维操作,常用于节点升级、硬件维护或缩容。

操作 命令 效果 对已有 Pod 的影响
Cordon kubectl cordon <node> 标记节点为 SchedulingDisabled,禁止新 Pod 调度 无影响,已有 Pod 继续运行
Drain kubectl drain <node> --ignore-daemonsets --delete-emptydir-data 先 Cordon,再驱逐节点上所有 Pod(优雅终止) Pod 被重新调度到其他可用节点
Uncordon kubectl uncordon <node> 恢复节点调度能力 无影响,新 Pod 可调度
Drain 执行流程:
  1. 自动执行 Cordon,防止新 Pod 调度。
  2. 逐一对节点上的 Pod 执行 DELETE 操作,触发 PreStop Hook 和优雅退出。
  3. DaemonSet 管理的 Pod 默认不会被驱逐(需 --ignore-daemonsets)。
  4. 使用 emptyDir 的 Pod 需显式添加 --delete-emptydir-data 才能驱逐。
  5. 等待所有 Pod 被驱逐或超时后,节点进入可维护状态。
Cordon / Drain / Uncordon 运维流程 节点主动运维流程 节点正常调度 Cordon Drain kubectl cordon kubectl drain kubectl uncordon 恢复调度 运维场景与注意事项 • 节点升级内核/CRI:先 Cordon 确保无新负载,再 Drain 迁移 Pod,最后升级。 • 集群缩容:Drain 后节点上无 Pod,再执行 kubectl delete node 移除。 • 避免 Drain 关键组件:etcd、kube-apiserver 等静态 Pod 需特殊处理。 • 超时控制:Drain 默认超时 60s,可通过 --timeout 调整。 • 与 Argo CD 联动:Drain 前确保 Application 的 syncPolicy 允许 Pod 重建。

4.5 节点生命周期与 Argo CD 同步的关联

在 Argo CD 驱动 CRI 接口进行集群节点扩容时,节点生命周期状态直接影响同步策略:

  • 节点注册阶段:新节点加入集群后,Argo CD 的 cluster 资源需更新 config 字段(如 API Server 地址、CA 证书),确保 Argo CD 能管理新节点上的工作负载。
  • NotReady 状态:Argo CD 的 Self-Healing 机制会检测到 Pod 被驱逐,自动在健康节点上重新同步 Application。
  • Cordon/Drain 操作:运维人员 Drain 节点前,应暂停 Argo CD 的自动同步(kubectl patch app <app> -p '{"spec":{"syncPolicy":{"automated":{"selfHeal":false}}}}'),避免同步冲突。
  • 节点恢复:Uncordon 后,Argo CD 可恢复自动同步,确保新 Pod 调度到恢复节点。
最佳实践:在集群节点扩缩容流程中,建议将 Argo CD 的 syncPolicy 与节点生命周期事件解耦。使用 Webhook 或 Event Listener 监听节点状态变化,触发条件性同步,而非全量自动同步。