Kubernetes下线节点
- 2025-05-15 18:23:00
- 丁国栋
- 原创 6
kubectl cordon
详解及使用场景
什么是 kubectl cordon
?
kubectl cordon
是 Kubernetes 中的一个命令,用于将节点标记为不可调度(Unschedulable)。执行后:
• 新创建的 Pod 将不会被调度到该节点
• 已存在的 Pod 不受影响,会继续运行
• 系统守护进程 Pod(如 DaemonSet 管理的 Pod)不受影响
主要使用场景
- 节点维护 当需要对节点进行维护(如升级内核、更换硬件)时:
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
处理。
- 隔离问题节点 当节点出现异常但不需要立即驱逐Pod时:
kubectl cordon <node-name>
# 观察节点问题,决定后续操作
- 资源预留 需要保留节点资源给特定Pod时:
kubectl cordon <node-name>
# 然后手动调度特定Pod到该节点
- 灰度发布/测试 测试新节点稳定性时,可以先允许部分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
注意事项
- 权限要求:需要对节点有
update
权限 - API对象:实际上是修改节点的
spec.unschedulable
字段 - 系统Pod:kube-system 命名空间中的某些关键Pod可能仍会被调度
- 结合标签使用:可与节点标签配合实现更复杂的调度策略
cordon
是 Kubernetes 节点管理中的基础操作,合理使用可以确保集群运维过程平稳有序。
标记节点不允许Pod调度的几种方法
在Kubernetes中,有几种方法可以标记节点不允许新的Pod调度到该节点上:
- 将节点标记为不可调度(Cordon)
这是最简单的方法,会阻止新的Pod被调度到该节点,但不会影响已运行的Pod:
kubectl cordon <node-name>
验证状态:
kubectl get node <node-name>
在输出中会看到SchedulingDisabled
状态
- 添加污点(Taint)
污点可以更精细地控制Pod调度,常用的污点效果:
• NoSchedule
: 不允许新Pod调度
• PreferNoSchedule
: 尽量避免调度
• NoExecute
: 不允许新Pod调度并驱逐现有Pod
kubectl taint nodes <node-name> key=value:NoSchedule
示例(常用维护模式污点):
kubectl taint nodes <node-name> dedicated=maintenance:NoSchedule
- 移除节点标签(如果调度依赖特定标签)
如果Pod调度依赖于特定节点标签,可以移除这些标签:
kubectl label nodes <node-name> <label-key>-
例如:
kubectl label nodes node1 dedicated-
- 结合使用(推荐生产环境使用)
生产环境中推荐同时使用cordon和taint:
kubectl cordon <node-name>
kubectl taint nodes <node-name> maintenance=true:NoSchedule
恢复节点为可调度状态
- 取消不可调度标记:
kubectl uncordon <node-name>
- 移除污点:
kubectl taint nodes <node-name> key:NoSchedule-
注意事项
- DaemonSet Pods:不受cordon影响,但受NoExecute污点影响
- 系统关键Pod:kube-system命名空间中的某些系统Pod可能仍会运行
- 已有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
发表评论