在K8S中,Worker节点宕机,Pods驱逐流程有哪些?

在 Kubernetes 中,当 Worker 节点宕机时,集群会自动触发 Pod 的驱逐(Eviction)流程,确保应用的高可用性。以下是完整的驱逐流程及核心机制:


一、节点宕机检测机制

  1. Node Controller 监控
    kube-controller-manager 中的 Node Controller 负责监控节点状态:

    • 每隔 --node-monitor-period(默认 5s)检查节点状态。
    • 若节点连续超时 --node-monitor-grace-period(默认 40s),标记为 ConditionUnknown
    • 持续超时 --node-startup-grace-period(默认 1m)后,最终判定节点为 NotReady 状态。
  2. API Server 更新状态
    节点状态变化通过 API Server 更新到 Etcd。


二、Pod 驱逐流程

阶段 1:标记节点不可调度 & 添加污点

  1. 节点标记为不可调度
    kubectl get nodes
    # 输出:worker-node-1   NotReady   SchedulingDisabled
    
  2. 自动添加污点(Taint)
    Kubernetes 自动为宕机节点添加污点:
    kubectl describe node worker-node-1
    # 输出:Taints: node.kubernetes.io/unreachable:NoExecute
    
    • 效果(Effect)NoExecute(立即驱逐不容忍此污点的 Pod)。

阶段 2:Pod 驱逐决策

  1. 控制平面驱逐
    kube-controller-manager 中的 Pod Eviction Manager 负责决策:

    • 若节点持续不可达超过 --pod-eviction-timeout(默认 5 分钟),触发驱逐。
    • 例外:若集群启用了 TaintBasedEvictions(默认开启),则跳过超时等待,直接按污点规则驱逐。
  2. 污点容忍度检查
    Pod 需满足以下任一条件才可暂缓驱逐

    tolerations:
    - key: "node.kubernetes.io/unreachable"
      operator: "Exists"
      effect: "NoExecute"
      tolerationSeconds: 600  # 容忍 10 分钟(默认值)
    
    • 若 Pod 未显式定义容忍,Kubernetes 会自动添加默认容忍(tolerationSeconds=300)。

阶段 3:Pod 重新调度

  1. API Server 删除 Pod
    控制平面删除宕机节点上的 Pod 对象(此时 Pod 实际仍在宕机节点上,但状态变为 Terminating)。

    kubectl get pods --field-selector spec.nodeName=worker-node-1
    # 输出:web-pod-123   Terminating
    
  2. 新 Pod 创建

    • Deployment/StatefulSet 等控制器检测到 Pod 被删除,立即创建替代 Pod
    • 新 Pod 进入调度流程,分配到健康节点。
    kubectl get pods
    # 输出:web-pod-456   Running   10s   # 新 Pod
    
  3. 存储卷处理

    • 有状态应用(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 的时间(超过后驱逐)

五、特殊情况处理

  1. 有状态应用(StatefulSet)

    • 节点恢复后,原 Pod 可能仍处于 Terminating 状态(因 kubelet 无法上报删除)。
    • 强制删除kubectl delete pod <name> --grace-period=0 --force
  2. DaemonSet Pod

    • 节点恢复后自动重建,无需手动干预。
  3. 节点网络分区(脑裂)

    • 控制平面认为节点宕机并驱逐 Pod,但节点自身可能仍在运行 Pod(导致重复运行)。
    • 解决方案:使用 lease API(Kubernetes 1.14+)增强节点状态判断准确性。

六、最佳实践

  1. 调整驱逐超时
    # kube-controller-manager 启动参数
    --pod-eviction-timeout=2m  # 生产环境可缩短至 2 分钟
    
  2. 自定义容忍时间
    # 关键业务 Pod 延长容忍时间(如数据库)
    tolerations:
    - key: "node.kubernetes.io/unreachable"
      operator: "Exists"
      effect: "NoExecute"
      tolerationSeconds: 1800  # 30 分钟
    
  3. Pod 分散部署
    使用 podAntiAffinity 避免单节点运行多个副本:
    affinity:
      podAntiAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values: [my-app]
          topologyKey: kubernetes.io/hostname
    

总结

当 Worker 节点宕机时,Kubernetes 的驱逐流程如下:

  1. 检测:Node Controller 标记节点 NotReady + 添加 unreachable 污点。
  2. 驱逐:Pod Eviction Manager 等待超时后删除 Pod(或按污点容忍规则立即驱逐)。
  3. 重建:控制器创建新 Pod → 调度到健康节点 → kubelet 启动容器。
  4. 存储:有状态应用自动重用原存储卷。

核心目的

  • 最小化服务中断:5 分钟内完成 Pod 迁移(默认)。
  • 保障数据安全:StatefulSet 保留持久化存储。
  • 自动化恢复:无需人工介入。
posted @ 2025-08-13 20:27  天道酬勤zjh  阅读(28)  评论(0)    收藏  举报