在K8S中,Worker节点宕机,Pods驱逐流程有哪些?
在 Kubernetes 中,当 Worker 节点宕机时,集群会自动触发 Pod 的驱逐(Eviction)流程,确保应用的高可用性。以下是完整的驱逐流程及核心机制:
一、节点宕机检测机制
-
Node Controller 监控
kube-controller-manager
中的 Node Controller 负责监控节点状态:- 每隔
--node-monitor-period
(默认 5s)检查节点状态。 - 若节点连续超时
--node-monitor-grace-period
(默认 40s),标记为ConditionUnknown
。 - 持续超时
--node-startup-grace-period
(默认 1m)后,最终判定节点为NotReady
状态。
- 每隔
-
API Server 更新状态
节点状态变化通过 API Server 更新到 Etcd。
二、Pod 驱逐流程
阶段 1:标记节点不可调度 & 添加污点
- 节点标记为不可调度
kubectl get nodes # 输出:worker-node-1 NotReady SchedulingDisabled
- 自动添加污点(Taint)
Kubernetes 自动为宕机节点添加污点:kubectl describe node worker-node-1 # 输出:Taints: node.kubernetes.io/unreachable:NoExecute
- 效果(Effect):
NoExecute
(立即驱逐不容忍此污点的 Pod)。
- 效果(Effect):
阶段 2:Pod 驱逐决策
-
控制平面驱逐
kube-controller-manager
中的 Pod Eviction Manager 负责决策:- 若节点持续不可达超过
--pod-eviction-timeout
(默认 5 分钟),触发驱逐。 - 例外:若集群启用了
TaintBasedEvictions
(默认开启),则跳过超时等待,直接按污点规则驱逐。
- 若节点持续不可达超过
-
污点容忍度检查
Pod 需满足以下任一条件才可暂缓驱逐:tolerations: - key: "node.kubernetes.io/unreachable" operator: "Exists" effect: "NoExecute" tolerationSeconds: 600 # 容忍 10 分钟(默认值)
- 若 Pod 未显式定义容忍,Kubernetes 会自动添加默认容忍(
tolerationSeconds=300
)。
- 若 Pod 未显式定义容忍,Kubernetes 会自动添加默认容忍(
阶段 3:Pod 重新调度
-
API Server 删除 Pod
控制平面删除宕机节点上的 Pod 对象(此时 Pod 实际仍在宕机节点上,但状态变为Terminating
)。kubectl get pods --field-selector spec.nodeName=worker-node-1 # 输出:web-pod-123 Terminating
-
新 Pod 创建
- Deployment/StatefulSet 等控制器检测到 Pod 被删除,立即创建替代 Pod。
- 新 Pod 进入调度流程,分配到健康节点。
kubectl get pods # 输出:web-pod-456 Running 10s # 新 Pod
-
存储卷处理
- 有状态应用(StatefulSet):新 Pod 自动绑定原 PVC,确保数据持久化。
- 临时存储:数据丢失(符合预期)。
三、核心组件协作流程
sequenceDiagram
participant N as Node (宕机)
participant C as kube-controller-manager
participant A as API Server
participant S as Scheduler
participant K as kubelet (健康节点)
N-->>C: 心跳超时
C->>A: 标记节点 NotReady + 添加污点
A->>C: 更新状态
C->>C: 等待 pod-eviction-timeout (5min)
C->>A: 删除宕机节点上的 Pod
A->>S: 触发控制器创建新 Pod
S->>K: 调度新 Pod 到健康节点
K->>A: 报告新 Pod Running
四、关键配置参数
参数 | 默认值 | 作用 |
---|---|---|
--node-monitor-period |
5s | 节点状态检查间隔 |
--node-monitor-grace-period |
40s | 节点无响应后标记为 Unknown 的等待时间 |
--pod-eviction-timeout |
5m | 节点持续 NotReady 后驱逐 Pod 的等待时间 |
tolerationSeconds (默认污点容忍) |
300s | 容忍 node.kubernetes.io/unreachable 的时间(超过后驱逐) |
五、特殊情况处理
-
有状态应用(StatefulSet)
- 节点恢复后,原 Pod 可能仍处于
Terminating
状态(因 kubelet 无法上报删除)。 - 强制删除:
kubectl delete pod <name> --grace-period=0 --force
。
- 节点恢复后,原 Pod 可能仍处于
-
DaemonSet Pod
- 节点恢复后自动重建,无需手动干预。
-
节点网络分区(脑裂)
- 控制平面认为节点宕机并驱逐 Pod,但节点自身可能仍在运行 Pod(导致重复运行)。
- 解决方案:使用
lease
API(Kubernetes 1.14+)增强节点状态判断准确性。
六、最佳实践
- 调整驱逐超时:
# kube-controller-manager 启动参数 --pod-eviction-timeout=2m # 生产环境可缩短至 2 分钟
- 自定义容忍时间:
# 关键业务 Pod 延长容忍时间(如数据库) tolerations: - key: "node.kubernetes.io/unreachable" operator: "Exists" effect: "NoExecute" tolerationSeconds: 1800 # 30 分钟
- Pod 分散部署:
使用podAntiAffinity
避免单节点运行多个副本:affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: [my-app] topologyKey: kubernetes.io/hostname
总结
当 Worker 节点宕机时,Kubernetes 的驱逐流程如下:
- 检测:Node Controller 标记节点
NotReady
+ 添加unreachable
污点。 - 驱逐:Pod Eviction Manager 等待超时后删除 Pod(或按污点容忍规则立即驱逐)。
- 重建:控制器创建新 Pod → 调度到健康节点 → kubelet 启动容器。
- 存储:有状态应用自动重用原存储卷。
核心目的:
- 最小化服务中断:5 分钟内完成 Pod 迁移(默认)。
- 保障数据安全:StatefulSet 保留持久化存储。
- 自动化恢复:无需人工介入。