深色模式
节点宕机演练
摘要:节点宕机检验的是三件事:Pod 能否重新调度、调度是否违反反亲和、数据类服务能否安全漂移。本文给出 drain 演练与硬关机两种强度的做法与恢复校验。
适用环境
bash
kubectl get nodes
kubectl get pdb -A
# 确认集群有冗余:单节点集群不适合此演练
kubectl get nodes --no-headers | wc -l1
2
3
4
2
3
4
操作步骤
第 1 步:先做安全驱逐(推荐先做这档)
bash
# 驱逐前确认:该节点上的 Pod 都有控制器,否则驱逐后不会重建
kubectl get pod -A --field-selector spec.nodeName=<node> -o json \
| jq -r '.items[] | select(length(.metadata.ownerReferences)==0) | "裸 Pod: \(.metadata.namespace)/\(.metadata.name)"'
# 安全驱逐:尊重 PDB,优雅终止
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data --grace-period=30 --timeout=5m1
2
3
4
5
6
2
3
4
5
6
第 2 步:观察重建过程
bash
# 看 Pod 是否在新节点起来,以及耗时
kubectl get pod -A -o wide --watch | grep -v <node>
# 记录调度失败原因(若有)
kubectl get events -A --sort-by=.lastTimestamp | grep -iE 'failedscheduling|preempt' | tail1
2
3
4
5
2
3
4
5
第 3 步:恢复节点
bash
kubectl uncordon <node>
kubectl get node <node> -o jsonpath='{.spec.unschedulable}{"\n"}' # 应为空1
2
2
第 4 步:硬关机演练(更强一档)
bash
# 在云上:直接停止实例(控制台或 CLI)
# 在自建机上(危险,仅在专用演练节点执行):
sudo systemctl poweroff1
2
3
2
3
DANGER
poweroff 是不可逆的即时中断。必须确认:节点上的服务有足够副本、有状态服务(如数据库)已从该节点排除、且演练窗口已通知相关方。
bash
# 观察节点 NotReady 与 Pod 驱逐(默认 5 分钟后开始驱逐)
kubectl get node -w
kubectl get pod -A -o wide | grep <node>1
2
3
2
3
第 5 步:恢复后校验
bash
kubectl get nodes
kubectl get pod -A --field-selector spec.nodeName=<node> | head
kubectl get pdb -A1
2
3
2
3
验证
bash
# 1. 所有 Deployment 副本数达标
kubectl get deploy -A -o custom-columns='NS:.metadata.namespace,NAME:.metadata.name,WANT:.spec.replicas,READY:.status.readyReplicas' \
| awk '$3!=$4 {print "副本不足: "$0}' | head
# 2. 无 Pending Pod
kubectl get pod -A --field-selector status.phase=Pending | wc -l
# 3. 节点状态全部 Ready
kubectl get nodes --no-headers | awk '$2!="Ready" {print $1}'1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
常见坑
驱逐被 PDB 卡住,演练变挂起
maxUnavailable=0 的 PDB 会让 drain 永久等待。演练前检查 PDB 配置是否合理。
有状态服务在演练中丢数据
本地存储(emptyDir/hostPath)的 Pod 被驱逐后数据即失。有状态服务必须先确认存储与副本策略。
直接对承载控制面的节点做关机
apiserver/etcd 所在节点宕机会导致整个集群不可控。演练节点必须排除控制面与存储节点。