Kubernetes 节点安全维护全流程:从驱逐 Pod 到彻底清理残留

前言

在 Kubernetes 集群运维中,经常需要对单个节点进行维护,比如升级内核、重装 NVIDIA 驱动、扩容磁盘甚至重装系统。这时最核心的需求是:安全地将节点隔离出来,确保不影响集群其他部分,同时彻底清理本地残留,避免容器和 Pod 反复重建

下面分享一套经过实战验证的完整流程,适用于大多数基于 kubeadm 或类似方式部署的集群(版本 v1.20+ 均适用)。

1. 标记节点不可调度

防止新 Pod 被调度到目标节点。

bash 复制代码
kubectl cordon <node-name>

节点状态变为 Ready,SchedulingDisabled

2. 删除节点上所有 Pod(包括 DaemonSet)

bash 复制代码
kubectl delete pod --all-namespaces --field-selector spec.nodeName=<node-name> --grace-period=0 --force

这一步会强制删除所有 Pod,包括 DaemonSet 管理的系统组件(如 calico-node、kube-proxy 等)。

3. 让节点进入 NotReady 状态(关键步骤)

这是阻止 DaemonSet Pod 重建的核心。

在目标节点上执行:

bash 复制代码
sudo systemctl stop kubelet
sudo pkill -9 -f kubelet    # 确保进程彻底结束

几秒到一分钟后,节点状态变为 NotReady,SchedulingDisabled

此时即使 DaemonSet 控制器尝试创建新 Pod,也只会卡在 Pending 状态,不会真正启动容器。

4. 清理本地运行的容器

kubelet 停止前可能已拉起部分容器,需要手动清理。

bash 复制代码
sudo docker rm -f $(sudo docker ps -aq)   # Docker 环境
# 或 containerd 环境
sudo crictl rm -f $(sudo crictl ps -q)

5. 清理镜像和运行时残留

bash 复制代码
sudo docker rmi -f $(sudo docker images -q)
sudo docker system prune -a --volumes -f

6. 清理 Kubernetes 残留文件和挂载

常会遇到 Device or resource busy 错误,因为 secret/configmap 等卷以 tmpfs 方式挂载。

bash 复制代码
# 先卸载所有 kubelet 相关 tmpfs
sudo mount | grep kubelet | awk '{print $3}' | xargs -r sudo umount

# 再删除残留目录
sudo rm -rf /var/lib/kubelet/* /var/log/pods/* /var/log/containers/*

# 重建必要空目录
sudo mkdir -p /var/lib/kubelet /var/log/pods /var/log/containers

7. 可选:进一步释放磁盘空间

  • 清理 snap 旧版本(Ubuntu 常见):

    bash 复制代码
    sudo snap list --all | awk '/disabled/{print $1, $3}' | while read n r; do sudo snap remove "$n" --revision="$r" --purge; done
  • 清理系统日志:

    bash 复制代码
    sudo journalctl --vacuum-size=500M

8. 维护完成后恢复节点

在目标节点上:

bash 复制代码
sudo systemctl start kubelet

等待节点恢复 Ready 状态后,在控制平面执行:

bash 复制代码
kubectl uncordon <node-name>

所有 DaemonSet Pod 会自动重建,节点恢复正常运行。

常见问题与解决方案

  • Pod 或容器反复重建 → 节点仍为 Ready 状态 → 必须停止 kubelet 让节点 NotReady
  • 删除 /var/lib/kubelet 时提示 busy → 未卸载 tmpfs 挂载 → 先 umount 再删除
  • docker stop 无效 → kubelet 仍在拉起容器 → 彻底杀死 kubelet 进程

总结

这套流程的核心思想是:

  1. cordon 阻止调度
  2. 强制删除 Pod
  3. 停止 kubelet 让节点 NotReady(阻止重建)
  4. 彻底清理本地残留

执行完后,节点完全隔离且干净,可安全进行任何破坏性操作。恢复时仅需启动 kubelet 并 uncordon 即可自动愈合。

相关推荐
程序喵大人1 小时前
【C++进阶】STL容器与迭代器 - 05 map 和 set 为什么按键保持有序
开发语言·c++·容器·迭代器·stl
huahailing10242 小时前
Spring Boot 集成 XXL-Job 完整实现方案(支持动态CRUD)
java·spring boot·后端
薛定谔的猫-菜鸟程序员3 小时前
基于 Electron 的本地短视频解析与下载工具:架构设计与工程实践
java·electron·音视频
老孙讲技术3 小时前
做过安防后端的人都懂:别把「云录像留证」和「告警外呼叫醒」拆成两套台账——分层搭重大事件触达
物联网·安全
风曦Kisaki3 小时前
Kubernetes(K8s)笔记Day03: Pod命名空间,标签,Pod 的调度,污点与容忍度,Pod 常见状态和重启策略,Pod 生命周期
linux·运维·笔记·docker·云原生·容器·kubernetes
张忠琳3 小时前
【NVIDIA】NVIDIA k8s-device-plugin v0.19.3 资源管理器模块深度分析之三
云原生·容器·架构·kubernetes·nvidia
音符犹如代码4 小时前
Arthas Profiler 火焰图实战:CPU 热点在哪一目了然
java·jvm·spring boot
小园子的小菜4 小时前
Java 并发编程:线程安全队列全解 —— 阻塞与非阻塞实现原理及源码深度剖析
java·开发语言
好好沉淀4 小时前
Windows 下升级 Maven 3.6.1 到 3.9.9 踩坑全记录
java·windows·maven
zzq77974 小时前
Android 风险识别机制实测:从录屏悬浮窗到远程控制的边界评估
android·安全·安卓·app加固·御盾安全