如何从Kubernetes集群中安全移除节点

在 Kubernetes 集群的生命周期中,节点维护是不可避免的操作。常见场景包括:

硬件升级或更换缩减集群规模以优化资源利用率故障节点替换系统迁移或环境重构不当的节点移除可能导致:

⚠️ 服务中断 ⚠️ 数据丢失 ⚠️ 资源泄漏 ⚠️ 集群状态异常

本指南将详细介绍安全移除节点的全流程,确保操作平滑无感知。

1、预检准备1.1 环境检查代码语言:javascript复制kubectl get nodes # 查看所有节点状态

kubectl describe node <节点名称> # 检查目标节点详情确认节点状态为 Ready 且无异常事件(如内存压力、磁盘压力)。

1.2 资源评估代码语言:javascript复制kubectl get pods -o wide --all-namespaces | grep <节点名称>识别关键工作负载(如数据库、有状态服务)检查Pod Disruption Budget(PDB)是否允许驱逐

kubectl get pdb --all-namespaces1.3 维护窗口规划选择业务低峰期操作通知相关团队服务可能短暂中断2、节点移除四步流程2.1 步骤1:标记为不可调度(隔离节点)代码语言:javascript复制kubectl cordon <节点名称>原理:将节点标记为SchedulingDisabled,阻止新Pod调度到该节点,但现有Pod继续运行。

验证:

代码语言:javascript复制kubectl get nodes | grep <节点名称>输出应显示 STATUS 为 Ready,SchedulingDisabled

2.2 步骤2:驱逐工作负载(核心步骤)代码语言:javascript复制kubectl drain <节点名称> \

--ignore-daemonsets \ # 忽略DaemonSet管理的Pod

--delete-emptydir-data \ # 删除emptyDir临时数据

--force \ # 强制删除无响应Pod

--timeout=300s # 超时设置(建议5-10分钟)

--pod-selector="!controller-revision-hash" # 选择性排除特定Pod关键注意事项:

DaemonSet处理:Flannel/Calico 等网络插件通常通过 DaemonSet 运行,需确保其他节点有副本。有状态服务:

StatefulSet 需确认存储卷能自动迁移(如使用云存储)

kubectl get pv -o wide | grep <节点名称>本地存储:

使用 local 卷的 Pod 需手动迁移并删除重建驱逐过程监控:

代码语言:javascript复制watch kubectl get pods -o wide | grep <节点名称> # 实时观察Pod迁移状态2.3 步骤3:正式删除节点代码语言:javascript复制kubectl delete node <节点名称>效果:从 API Server 中移除节点对象,kube-controller-manager 停止监控该节点。

2.4 步骤4:节点级清理(在目标服务器执行)代码语言:javascript复制sudo kubeadm reset # 重置kubeadm安装

sudo rm -rf \

/etc/kubernetes \ # 删除配置

/var/lib/kubelet \ # 清理容器运行时数据

/var/lib/etcd \ # etcd数据(如果是控制节点)

~/.kube/config # 客户端配置

sudo iptables -F # 重置iptables规则

sudo ipvsadm --clear # 清理IPVS规则(如使用IPVS模式)

sudo systemctl stop kubelet docker containerd # 停止服务3、环境验证3.1 集群状态检查代码语言:javascript复制kubectl get nodes # 确认节点已消失

kubectl get pods -A -o wide # 检查所有Pod运行位置3.2 服务健康验证代码语言:javascript复制kubectl get svc # 检查服务Endpoint

kubectl top nodes # 确认资源负载均衡

curl -I <服务IP>:<端口> # 实际访问测试4、特殊场景处理4.1 场景1:节点已宕机无法连接代码语言:javascript复制kubectl delete node <节点名称> --force --grace-period=0后续操作:

物理重启节点手动清理残留进程:

sudo pkill -9 kubelet docker containerd4.2 场景2:驱逐过程卡住排查步骤:

检查阻塞Pod:

kubectl describe pod | grep -A 10 Events强制删除:

kubectl delete pod --grace-period=0 --force绕过保护机制(谨慎使用):

kubectl drain <节点名称> --disable-eviction4.3 场景3:关键Pod无法迁移解决方案:

修改Deployment/StatefulSet配置:

kubectl edit deploy/<名称> # 手动调整节点亲和性临时副本扩容:

kubectl scale deploy/<名称> --replicas=+15、最佳实践与风险防控维护窗口期:

避免业务高峰时段操作设置维护模式(如通过Cluster API)有状态服务保护:

# 示例:PodDisruptionBudget apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: zk-pdb spec: minAvailable: 2 # 保证最少可用副本数 selector: matchLabels: app: zookeeper自动化工具:

使用cluster-autoscaler自动缩容通过Argo CD/GitOps管理节点生命周期监控告警:

操作后检查:节点不可用告警Pod未就绪事件资源利用率突变6、结语安全移除Kubernetes节点是集群运维的核心技能。通过cordon→drain→delete的标准流程,配合完善的预检和验证,可确保服务零中断。

关键要点:

始终优先驱逐(drain)而非直接删除。特别关注有状态服务和本地存储操作后验证集群整体健康状态最后建议:在生产环境操作前,务必在测试集群验证流程。保留操作日志和快照(如etcd备份),为可能的回滚做好准备。

通过遵循本指南,您将能够高效安全地管理Kubernetes节点生命周期,确保集群稳定运行。