Kubernetes下线节点

2025-05-15 18:23:00
丁国栋
原创 6
摘要:本文记录如何从Kubernetes中移除/下线一个节点。

kubectl cordon 详解及使用场景

什么是 kubectl cordon

kubectl cordon 是 Kubernetes 中的一个命令,用于将节点标记为不可调度(Unschedulable)。执行后: • 新创建的 Pod 将不会被调度到该节点

• 已存在的 Pod 不受影响,会继续运行

• 系统守护进程 Pod(如 DaemonSet 管理的 Pod)不受影响

主要使用场景

  1. 节点维护 当需要对节点进行维护(如升级内核、更换硬件)时:
kubectl cordon <node-name>  # 先标记为不可调度,标记后节点状态会从 Ready 变为 Ready,SchedulingDisabled
kubectl drain <node-name>   # 然后排空现有Pod,如果是想一个个的驱逐pod就逐个删除pod,让pod调度到其他节点
# 进行维护操作...
kubectl uncordon <node-name> # 恢复后重新启用

在删除一个要维护的节点上的Pod时,先不要删除 kube-system 里的 Pod,最后用 kubectl drain 处理。

  1. 隔离问题节点 当节点出现异常但不需要立即驱逐Pod时:
kubectl cordon <node-name>
# 观察节点问题,决定后续操作
  1. 资源预留 需要保留节点资源给特定Pod时:
kubectl cordon <node-name>
# 然后手动调度特定Pod到该节点
  1. 灰度发布/测试 测试新节点稳定性时,可以先允许部分Pod运行:
kubectl cordon <node-name>
kubectl apply -f test-pod.yaml  # 明确指定nodeName的测试Pod

与相关命令的区别

命令 影响新Pod调度 影响现有Pod 影响DaemonSet 典型用途
cordon ❌ 阻止 ✔️ 保留 ❌ 不影响 准备维护
taint NoSchedule ❌ 阻止 ✔️ 保留 ❌ 不影响 专用节点
taint NoExecute ❌ 阻止 ❌ 驱逐 ❌ 不影响 紧急隔离
drain ❌ 阻止 ❌ 驱逐 ✔️ 可配置 立即维护

实际工作流示例

# 1. 首先标记节点不可调度
kubectl cordon node-01
# 2. 检查节点状态(应显示 SchedulingDisabled)
kubectl get nodes
# 3. 确认没有新Pod被调度到该节点
kubectl describe node node-01 | grep -A 10 "Non-terminated Pods"
# 4. 如需完全清空节点
kubectl drain node-01 --ignore-daemonsets --delete-emptydir-data
# 5. 维护完成后恢复
kubectl uncordon node-01

注意事项

  1. 权限要求:需要对节点有 update 权限
  2. API对象:实际上是修改节点的 spec.unschedulable 字段
  3. 系统Pod:kube-system 命名空间中的某些关键Pod可能仍会被调度
  4. 结合标签使用:可与节点标签配合实现更复杂的调度策略

cordon 是 Kubernetes 节点管理中的基础操作,合理使用可以确保集群运维过程平稳有序。

标记节点不允许Pod调度的几种方法

在Kubernetes中,有几种方法可以标记节点不允许新的Pod调度到该节点上:

  1. 将节点标记为不可调度(Cordon)

这是最简单的方法,会阻止新的Pod被调度到该节点,但不会影响已运行的Pod:

kubectl cordon <node-name>

验证状态:

kubectl get node <node-name>

在输出中会看到SchedulingDisabled状态

  1. 添加污点(Taint)

污点可以更精细地控制Pod调度,常用的污点效果: • NoSchedule: 不允许新Pod调度

PreferNoSchedule: 尽量避免调度

NoExecute: 不允许新Pod调度并驱逐现有Pod

kubectl taint nodes <node-name> key=value:NoSchedule

示例(常用维护模式污点):

kubectl taint nodes <node-name> dedicated=maintenance:NoSchedule
  1. 移除节点标签(如果调度依赖特定标签)

如果Pod调度依赖于特定节点标签,可以移除这些标签:

kubectl label nodes <node-name> <label-key>-

例如:

kubectl label nodes node1 dedicated-
  1. 结合使用(推荐生产环境使用)

生产环境中推荐同时使用cordon和taint:

kubectl cordon <node-name>
kubectl taint nodes <node-name> maintenance=true:NoSchedule

恢复节点为可调度状态

  1. 取消不可调度标记:
kubectl uncordon <node-name>
  1. 移除污点:
kubectl taint nodes <node-name> key:NoSchedule-

注意事项

  1. DaemonSet Pods:不受cordon影响,但受NoExecute污点影响
  2. 系统关键Pod:kube-system命名空间中的某些系统Pod可能仍会运行
  3. 已有Pod:仅使用cordon或NoSchedule不会驱逐已有Pod,如需驱逐需使用NoExecute或drain命令

通过以上方法,你可以有效地控制Pod不被调度到特定节点上。

如果使用了像 longhorn 这样的分布式存储,那么在移除节点前还有其他步骤

kubectl get volumes.longhorn.io -A | grep <node-name>
kubectl get StatefulSet -A

通过查看某个volume的描述,可以获取这个volume的副本数量

kubectl describe volumes.longhorn.io pvc-e5b5e779-0f3c-4fda-9c6b-e72248756bd1 -n quickon-storage
发表评论
博客分类