k8s集群如何在业务不中断的前提下安全下线一个Node

在确保线上业务不中断的情况下,安全下线一个Kubernetes节点需要遵循一套严谨的流程。核心在于先将节点隔离,然后优雅地将其上的工作负载迁移到其他节点,最后再执行移除操作。

以下表格详细说明了安全下线节点的完整步骤、核心命令及关键要点。

🔄 节点下线操作流程

步骤

核心操作

命令示例

关键要点/解释

1. 预检与准备​

检查节点及工作负载状态

kubectl get nodes
kubectl describe node <node-name>
kubectl get pods -o wide --all-namespaces \| grep <node-name>

确认节点状态为Ready,并识别其上所有Pod,特别关注有状态服务(如数据库)和DaemonSet

2. 隔离节点​

标记节点为不可调度

kubectl cordon <node-name>

阻止新Pod被调度到该节点,现有Pod不受影响。节点状态会变为 Ready,SchedulingDisabled

3. 驱逐工作负载​

清空节点上的Pod

kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data --grace-period=900 --timeout=3600s

这是最核心的步骤。命令会优雅终止Pod并将其在其他健康节点上重建

4. 移除节点​

从API Server中删除节点对象

kubectl delete node <node-name>

此操作仅从控制平面移除节点记录,不会影响节点本身运行的服务

5. 后续清理​

在已下线的节点上执行清理

sudo kubeadm reset
sudo rm -rf /etc/kubernetes/ /var/lib/kubelet
sudo systemctl stop kubelet docker containerd

清理K8s组件和数据,为服务器后续用途做准备。如果是云服务器,则可在云平台中删除实例

6. 最终验证​

确认集群和工作负载状态

kubectl get nodes
kubectl get pods -A -o wide

确保节点已消失,所有Pod已在新节点上正常运行,服务访问无异常

 

 

 

 

Question:

在驱逐工作负载时,若没有其他可用节点,该如何处理?

当执行 kubectl drain驱逐工作负载时,如果集群中没有其他节点拥有足够的可用资源来接收被驱逐的 Pod,操作将会失败或卡住,Pod 会保持 Pending状态。这是一个典型的集群资源容量规划问题。

🔍 核心原因分析

kubectl drain的本质是优雅地删除目标节点上的 Pod,然后依赖其控制器(如 Deployment、StatefulSet)在其他可用节点上重新创建新的 Pod 副本。如果所有其他节点都没有足够的可分配 CPU、内存,或者因为污点(Taint)、节点选择器(nodeSelector)​ 不匹配而无法调度,那么新 Pod 就无法被创建,导致驱逐流程停滞

🛡️ 预防措施(最佳实践)

在计划下线节点前,应主动避免此情况:

  1. 预留缓冲资源:确保集群总有 10-20%​ 的闲置可分配资源,以应对节点维护等突发调度需求

  2. 容量规划与监控:使用 kubectl top nodes持续监控节点资源使用率,在资源吃紧时提前扩容节点

  3. 确保应用高可用:关键业务应通过 Deployment 配置多个副本,并分散在不同节点上,避免单点

  4. 调整 Pod 资源请求:如果某些 Pod 的 requests设置过高,可适当调低,使其更容易被调度

🚨 应急处理方案(当问题已发生)

如果 drain命令已因资源不足而卡住,可以按以下顺序尝试解决:

步骤

操作

命令/说明

风险与注意

1. 检查调度失败原因​

查看待迁移 Pod 的事件信息

kubectl describe pod <pod-name> -n <namespace>

查看 Events部分,确认是否是 Insufficient cpu/memory或其他原因(如污点)

2. 尝试释放资源​

清理低优先级 Pod:临时缩容或删除非关键业务的 Pod,释放资源。

kubectl scale deployment <non-critical-deploy> --replicas=0

需谨慎评估,确保不影响核心业务。

 

扩容集群:紧急添加一个新工作节点。

根据云平台或物理机流程快速加节点。

最根本的解决方案,但可能需要时间。

3. 调整调度约束​

临时移除污点或调整亲和性:如果节点因污点或亲和性规则无法调度。

kubectl taint nodes <node-name> key:NoSchedule-

需确保 Pod 可以运行在目标节点上。

4. 作为最后手段​

接受业务中断:如果节点必须立即下线,且无法腾出资源,则需评估业务影响。

1. 强制驱逐:kubectl drain <node> --force --grace-period=0
2. 记录受影响的 Pod/服务,准备事后恢复。

会导致 Pod 被直接删除且无法重建,服务中断。仅在所有其他方案都不可行时考虑。

💡 总结建议

“无可用节点”的根本原因是集群资源容量不足或调度策略过严。预防远胜于补救。在执行任何节点维护前,务必通过 kubectl get nodeskubectl top nodeskubectl describe node命令全面评估集群容量和负载分布,确保有足够的资源缓冲区

 

posted on 2025-12-17 15:42  Karlkiller  阅读(5)  评论(0)    收藏  举报

导航