基于本文回答
0
评论

如何将一个节点设置为不可调度(Cordon)?如何驱逐节点上的 Pod(Drain)?

知识点图片

在 Kubernetes 中,对节点进行维护(如升级内核、硬件维修)时,通常需要两个步骤:首先停止向该节点调度新 Pod(Cordon),然后安全地将现有 Pod 迁移走(Drain)。

以下是具体的操作命令和详细说明:

1. 将节点设置为不可调度 (Cordon)

作用:标记该节点为 Unschedulable。Kubernetes 调度器将不再把新的 Pod 分配到该节点上,但节点上现有的 Pod 不受影响,继续正常运行。

命令

bash
kubectl cordon <节点名称>

验证
执行 kubectl get nodes,你会看到该节点的状态包含 SchedulingDisabled

bash
NAME       STATUS                     ROLES    AGE   VERSION
node-01    Ready,SchedulingDisabled   <none>   30d   v1.26.0

2. 驱逐节点上的 Pod (Drain)

作用:安全地驱逐节点上的 Pod。

  • 它会自动先执行 cordon 命令。
  • 它会删除节点上的 Pod(静态 Pod 和 DaemonSet 除外),并让控制器(如 Deployment)在集群中的其他可用节点上重新创建这些 Pod。
  • 它会遵守 PodDisruptionBudget (PDB) 策略,确保服务高可用。

基本命令

bash
kubectl drain <节点名称>

常用参数(重要)
在实际生产环境中,直接运行 drain 通常会报错,因为节点上可能包含 DaemonSet 或使用本地存储的 Pod。通常需要加上以下参数:

  • --ignore-daemonsets:忽略 DaemonSet 管理的 Pod(如 kube-proxy, CNI 插件)。如果不加此参数,drain 会失败,因为 DaemonSet 会立即在同节点重建 Pod。
  • --delete-emptydir-data:如果 Pod 使用了 emptyDir(本地临时存储),驱逐会导致数据丢失。必须显式添加此参数确认你接受删除本地数据。
  • --force:强制驱逐不由控制器(Deployment, ReplicaSet, Job 等)管理的“裸 Pod”。

推荐的生产环境组合命令

bash
kubectl drain <节点名称> --ignore-daemonsets --delete-emptydir-data

3. 恢复节点 (Uncordon)

作用:当维护结束,节点重新上线后,需要解除不可调度状态,允许新的 Pod 调度上来。

命令

bash
kubectl uncordon <节点名称>

总结与对比

操作 命令 (kubectl) 对新 Pod 的影响 对现有 Pod 的影响 适用场景
Cordon cordon <node> 禁止调度 无影响 (继续运行) 排查问题,准备下线但暂不迁移业务
Drain drain <node> 禁止调度 驱逐/删除 (在别处重建) 节点维护、升级、下架节点
Uncordon uncordon <node> 允许调度 无影响 维护结束,节点恢复正常

典型维护流程

  1. kubectl cordon node-1 (可选,drain 会自动做,但先 cordon 更稳妥)
  2. kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data
  3. [进行物理维护/重启/升级]
  4. kubectl uncordon node-1
右滑查看面试常问