K8s节点优雅关机维护

Kubernetes节点优雅关机维护指南:生产环境最佳实践

在Kubernetes集群运维中,节点维护是不可避免的操作。本文将分享一套经过生产验证的节点停机维护方案,确保业务零感知、数据零丢失,附带真实场景的排错技巧。


一、核心维护原则

  1. 黄金法则:所有维护必须遵循排水(Drain)→停机→维护→恢复→回注流程
  2. 影响范围控制:单次维护节点数不超过集群总节点的20%
  3. 时间窗口选择:业务低峰期执行,避开定时任务/数据结算等关键时段

二、全流程操作手册

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集群中实现了无感知节点维护。建议每次维护后生成《节点维护报告》,包含关键指标记录和异常处理总结,持续优化维护流程。

posted on 2025-03-15 09:15  Leo-Yide  阅读(274)  评论(0)    收藏  举报