Skip to content

K8s 节点下线与恢复流程

场景:k8s-node01 需要扩容物理内存,属于临时下线——节点维护完成后会重新加入集群。
本文以 monitoring 命名空间(kube-prometheus-stack 监控组件)为例,其他业务同理。

一、下线前准备

1.1 看目标节点上跑了哪些 Pod

bash
kubectl get pods -n monitoring -o wide

node01 上的 Pod(案例):

Pod类型迁移风险
alertmanager-0StatefulSet有状态,需确认存储
grafana-0StatefulSet有状态,需确认存储
node-exporterDaemonSet无风险,不用管

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-0grafana-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 删除和重新添加节点

最近更新