K8s节点优雅关机维护
Kubernetes节点优雅关机维护指南:生产环境最佳实践
在Kubernetes集群运维中,节点维护是不可避免的操作。本文将分享一套经过生产验证的节点停机维护方案,确保业务零感知、数据零丢失,附带真实场景的排错技巧。
一、核心维护原则
- 黄金法则:所有维护必须遵循
排水(Drain)→停机→维护→恢复→回注流程 - 影响范围控制:单次维护节点数不超过集群总节点的20%
- 时间窗口选择:业务低峰期执行,避开定时任务/数据结算等关键时段
二、全流程操作手册
1. 预检清单(必须执行)
# 检查节点状态
kubectl get node <target-node> -o wide
# 确认节点标签(用于业务亲和性判断)
kubectl describe node <target-node> | grep -A10 Labels
# 检查本地存储数据(重要!)
kubectl get pods --all-namespaces -o wide \
--field-selector spec.nodeName=<target-node>,spec.volumes[].emptyDir!=nil
2. 节点排水(关键步骤)
# 优雅排水命令(生产推荐参数)
kubectl drain <node-name> \
--ignore-daemonsets \
--disable-eviction \ # 1.24+版本必须
--skip-wait-for-delete-timeout=600 \ # 等待删除超时
--grace-period=900 \ # 优雅终止宽限期
--timeout=3600s \
--delete-emptydir-data
参数解析:
--disable-eviction:绕过Pod驱逐API,直接删除Pod(应对旧版本兼容问题)--grace-period:覆盖Pod的terminationGracePeriodSeconds配置--skip-wait-for-delete:跳过已标记删除的Pod等待
3. 排水状态检查
# 实时监控排水进度
watch -n 2 "kubectl get pods -A -o wide | grep <node-name>"
# 检查残留Pod(DaemonSet除外)
kubectl get pods --field-selector spec.nodeName=<node-name> -A \
| grep -v 'ds-'
# 强制删除卡死Pod(慎用!)
kubectl delete pod <pod-name> --grace-period=0 --force
4. 节点关机操作
# 通过SSH安全关机
ssh <node-user>@<node-ip> \
"sudo systemctl poweroff --no-wall"
# 检查关机状态(等待5分钟)
for i in {1..30}; do
kubectl get node <node-name> | grep 'Not Ready' && break
sleep 10
done
5. 维护后唤醒节点
# 物理开机后检查服务状态
ssh <node-user>@<node-ip> \
"systemctl status kubelet containerd"
# 重新标记为可调度
kubectl uncordon <node-name>
# 验证节点状态
kubectl get node <node-name> -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}'
三、生产环境进阶技巧
1. Pod中断预算(PDB)保护
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: critical-service-pdb
spec:
minAvailable: 2 # 至少保留2个实例
selector:
matchLabels:
app: critical-service
2. 自定义排水过滤器
# 排除特定标签的Pod
kubectl drain <node> --pod-selector='!critical'
# 过滤命名空间
kubectl drain <node> --exclude-namespaces=monitoring,kube-system
3. 维护窗口自动化脚本
#!/bin/bash
NODE=$1
# 预检
kubectl get node $NODE -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' | grep -q True || exit 1
# 排水
kubectl drain $NODE --ignore-daemonsets --timeout=2h
# 关机(通过带外管理)
ipmitool -H $BMC_IP -U admin -P password power off
# 维护完成后自动唤醒
ipmitool -H $BMC_IP -U admin -P password power on
# 等待节点恢复
until kubectl get node $NODE -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' | grep True; do
sleep 10
done
# 恢复调度
kubectl uncordon $NODE
4. 多云环境特殊处理
- AWS:结合EC2 Auto Scaling生命周期钩子
- GCP:使用托管实例组自动平衡
- 裸金属:集成IPMI带外管理
四、故障应急手册
场景1:排水卡在Deployment Pod
# 查看Pod事件
kubectl describe pod <stuck-pod>
# 常见原因:
# 1. 无可用副本(检查HPA/副本数)
# 2. 资源不足(检查目标节点资源)
# 3. 存储卷绑定(检查PVC状态)
# 应急方案:
kubectl scale deploy <deploy-name> --replicas=+1
场景2:节点无法标记NotReady
# 强制移除节点(仅限etcd模式)
kubectl delete node <node-name>
# 在目标节点清理残留
sudo kubeadm reset --force
sudo rm -rf /etc/kubernetes/*
场景3:关机后Pod仍显示Running
# 强制修正状态
kubectl patch pod <pod-name> -p '{"metadata":{"finalizers":null}}'
五、维护效果验证矩阵
| 检查项 | 合格标准 | 检测命令 |
|---|---|---|
| 节点排水时间 | < 300秒 | 记录drain命令输出耗时 |
| 业务中断时间 | 零中断(滚动更新成功) | 监控流量曲线 |
| 存储卷迁移 | 无残留PV | kubectl get pv -l node= |
| 节点服务健康度 | kubelet/容器运行时无异常 | journalctl -u kubelet -n 100 |
| 调度恢复验证 | 新Pod可正常调度 | kubectl scale deploy测试用例 |
通过以上方案,我们成功在数千节点规模的金融级K8s集群中实现了无感知节点维护。建议每次维护后生成《节点维护报告》,包含关键指标记录和异常处理总结,持续优化维护流程。
浙公网安备 33010602011771号