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。
4.3 NotReady 机制与故障处理
当节点进入 NotReady 状态,意味着 kubelet 无法正常与 API Server 通信,或容器运行时(CRI)出现故障。Node Controller 会执行以下动作:
- 标记节点:将 Node 对象的
status.conditions中 Ready 条件置为 False。 - 停止调度:调度器自动将节点视为不可调度,新 Pod 不会分配至此节点。
- 驱逐 Pod:等待
--pod-eviction-timeout(默认 5 分钟)后,开始驱逐节点上的 Pod(由kube-controller-manager中的 NodeLifecycleController 执行)。 - 容忍度检查:若 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 执行流程:
- 自动执行 Cordon,防止新 Pod 调度。
- 逐一对节点上的 Pod 执行
DELETE操作,触发 PreStop Hook 和优雅退出。 - DaemonSet 管理的 Pod 默认不会被驱逐(需
--ignore-daemonsets)。 - 使用
emptyDir的 Pod 需显式添加--delete-emptydir-data才能驱逐。 - 等待所有 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 监听节点状态变化,触发条件性同步,而非全量自动同步。