操作定位
cordon 把节点标记为不可调度(spec.unschedulable=true),kubectl get nodes 的 STATUS 会显示 SchedulingDisabled;uncordon 恢复调度。适用平台是 Kubernetes。两者都不会驱逐已有 Pod——这是最容易被误解的一点:未完成的 Pod 会继续在原节点上跑,想让负载真正搬走必须配合 drain。典型使用位置是维护流程的第一步与最后一步。
基本信息
| 适用平台 | Kubernetes,作用于 Node 对象 |
|---|---|
| 命令 | kubectl cordon <节点>;kubectl uncordon <节点> |
| 状态显示 | cordon 后节点 STATUS 为 Ready,SchedulingDisabled |
| 对已有 Pod 的影响 | 不驱逐、不中断,仅阻止新 Pod 调度上来 |
典型使用场景
- 节点维护前先封盘:阻止新 Pod 调度进来,再逐步迁移存量负载
- 发布资源预留:为即将上线的专用节点提前封盘,避免被其他工作负载占用
- 故障节点隔离:节点疑似硬件故障时先 cordon,避免调度器继续往上面放 Pod
- 缩容前准备:确认节点上的负载已迁移,再执行下线步骤
- 扩容预热:新节点标签未打全时先 cordon,配好标签后再 uncordon
基本操作
基本操作
kubectl cordon node1 # 标记不可调度
kubectl get nodes # STATUS 显示 SchedulingDisabled
kubectl get pods -A -o wide --field-selector spec.nodeName=node1 # 看还有哪些负载
kubectl drain node1 --ignore-daemonsets --delete-emptydir-data # 需要真正清空时配合 drain
kubectl uncordon node1 # 维护结束后恢复调度
kubectl get nodes -o widecordon 与 drain 对照
| 动作 | 对已有 Pod | 对新 Pod | 使用时机 |
|---|---|---|---|
| cordon | 无影响,继续运行 | 不再调度上来 | 维护第一步或临时隔离 |
| drain | 按 PDB 优雅驱逐 | 同样不再调度 | 真正需要清空节点时 |
| uncordon | 无影响 | 恢复调度 | 维护完成后 |
DaemonSet 的 Pod 自带对 unschedulable 的容忍,cordon 后仍会留在节点上,属于预期行为。
cordon 不影响已经在运行的 Pod,所以「封盘了就安全了」是错误判断:本地存储的工作负载仍在这台机器上读写。
封盘期间要盯的事
- 确认新 Pod 不再落到目标节点:观察一段时间内该节点的 Pod 列表是否稳定
- 确认其他节点容量足够:cordon 后调度空间变小,容量紧张时会出现 Pending
- 确认 PDB 不阻塞:真正的搬迁动作是 drain,PDB 设得过严会让排水长时间无法完成
- 确认监控与日志代理仍在运行:DaemonSet 不会因 cordon 撤离,这是排查链路可用的前提