Kubernetes节点执行cordon成功但仍处于Ready状态,该排查何处?
首先明确:kubectl cordon的作用是将节点标记为不可调度(unschedulable),并不会改变节点的Ready状态(Ready仅表示节点本身健康、可正常运行Pod)。如果你的预期是节点变为NotReady,那是误解了cordon的功能——要让节点变为NotReady需要执行kubectl drain配合节点停机,或者节点本身出现故障。
如果确认是节点的unschedulable标记未生效(即kubectl get nodes中节点的STATUS列没有SchedulingDisabled标识),按以下步骤排查:
1. 检查节点资源的实际配置
先直接查看节点的spec配置,确认unschedulable字段是否已被正确设置:
kubectl get node <节点名> -o yaml | grep -A2 spec
如果输出中spec.unschedulable为true,但kubectl get nodes未显示SchedulingDisabled,说明是kubectl的输出缓存或状态同步问题,可尝试重新获取:
kubectl get nodes --refresh
2. 排查etcd存储
etcd是Kubernetes的核心存储,api-server的变更需要同步到etcd。如果api-server日志无错误,检查etcd是否成功写入了节点的变更:
- 如果etcd以systemd服务运行:
查找包含journalctl -u etcd.service -fPUT /registry/nodes/<节点名>的日志,确认写入操作是否成功(返回200 OK)。 - 如果etcd以容器运行在kube-system命名空间:
同样检查节点资源的写入日志,排查是否有存储异常、集群同步问题(比如etcd节点间数据不一致)。kubectl logs -n kube-system etcd-<节点主机名> -f
3. 排查节点kubelet服务
节点的状态由kubelet上报并同步,kubelet会定期从api-server拉取节点的配置信息。如果etcd中已正确存储unschedulable=true,但节点状态未更新,检查kubelet日志:
- 对于systemd部署的kubelet:
查找是否有拉取节点资源失败、状态更新报错的日志,比如与api-server通信异常、权限不足等问题。journalctl -u kubelet.service -f
4. 关于Scheduler的排查
Scheduler本身不负责节点的Ready状态或unschedulable标记的设置,它只是读取这些属性来决定是否将Pod调度到节点上。只有当你发现Pod仍被调度到已cordon的节点时,才需要排查Scheduler日志,否则优先排查上述几个组件。
内容的提问来源于stack exchange,提问作者tollboy

