主题
K8s 节点下线与恢复流程
场景:
k8s-node01需要扩容物理内存,属于临时下线——节点维护完成后会重新加入集群。
本文以monitoring命名空间(kube-prometheus-stack 监控组件)为例,其他业务同理。
一、下线前准备
1.1 看目标节点上跑了哪些 Pod
bash
kubectl get pods -n monitoring -o widenode01 上的 Pod(案例):
| Pod | 类型 | 迁移风险 |
|---|---|---|
| alertmanager-0 | StatefulSet | 有状态,需确认存储 |
| grafana-0 | StatefulSet | 有状态,需确认存储 |
| node-exporter | DaemonSet | 无风险,不用管 |
1.2 确认存储类型(决定能不能直接 drain)
StatefulSet 的 Pod 能不能漂移,取决于 PVC 用的什么存储:
bash
kubectl get pvc -n monitoring
kubectl get pv | grep -i monitoring- 网络存储(NFS / Ceph-RBD / Rook / Longhorn)→ 可以直接 drain,数据不丢。
- 本地存储(local PV / hostPath)→ 不能直接 drain,Pod 会卡 Pending 甚至丢数据,需先迁数据。
1.3 确认有节点能承接迁移
至少留一个 Ready 的 worker 节点,保证 StatefulSet 迁移过去后能正常调度。
二、下线流程
bash
# 1. 封锁节点,禁止新 Pod 调度上来
kubectl cordon k8s-node01
# 2. 驱逐 Pod(必须忽略 DaemonSet,否则会卡在 node-exporter)
kubectl drain k8s-node01 --ignore-daemonsets --delete-emptydir-data
# 3. 验证迁移结果
kubectl get pods -n monitoring -o wide
kubectl get nodes预期结果:
alertmanager-0、grafana-0迁移到其他节点node-exporter留在原节点——这是 DaemonSet 的正常行为,不用处理k8s-node01状态变为SchedulingDisabled
验证没问题后,就可以安全关机、进行物理内存扩容了。
三、恢复流程
bash
# 1. 节点开机,等待状态恢复 Ready
kubectl get nodes
# 预期 k8s-node01 从 NotReady 变回 Ready
# 2. 解除封锁,恢复调度
kubectl uncordon k8s-node01
# 3. 确认一切正常
kubectl get nodes
kubectl get pods -n monitoring -o wide节点重新 Ready 后,DaemonSet 会自动把 node-exporter 拉回来,集群恢复原状。
四、常见问题
4.1 节点都 NotReady 了,node-exporter 为什么还是 Running?
正常。DaemonSet 的 Pod 带有对节点失联的容忍(tolerations),节点关机也不会被驱逐,会一直显示 Running,直到节点被删除。这是设计行为,不是 bug。
4.2 drain 一直卡住不结束?
多半是 DaemonSet 或带 emptyDir 的 Pod 挡住了。带上 --ignore-daemonsets 和 --delete-emptydir-data 重试。
4.3 什么时候才需要 kubectl delete node?
只有节点永久下线(退役、换机)时才执行。扩容内存这种临时维护不要删节点,删了节点回来后还得重新 join,白白增加工作量。
永久下线可参考:K8s 节点管理:使用 kubeadm 删除和重新添加节点
