导读:本期聚焦于兔子创作的《Kubernetes Pod 驱逐与节点排水实操步骤详解,如何避免业务中断?》,敬请观看详情。节点内存不足时为什么 Pod 会被莫名杀掉?执行 kubectl drain 维护节点时为什么总是卡住报错?这篇文章从 kubelet 的驱逐机制讲起,先说清软驱逐与硬驱逐阈值的触发原理和 Pod 排序规则,再完整演示 cordon、drain、uncordon 三步排水流程,配合常用参数逐一解释。针对 DaemonSet 无法驱逐、本地存储 Pod 阻塞、宽限期不够导致 Terminating 卡住等高频问题,文章也给出了对应的排查思路和处理命令,帮助你把节点维护做成一套可复用的标准操作。

节点内存吃紧时 Pod 被悄悄杀掉、执行维护时业务突然抖动,这类问题十有八九和驱逐机制有关。理解 Kubernetes 的驱逐原理,掌握规范的节点排水流程,是保障线上稳定性的基本功。

Kubernetes Pod 驱逐与节点排水实操步骤详解,如何避免业务中断?

一、kubelet 驱逐机制是怎么工作的

Kubernetes 的驱逐分为两类:一类是节点资源压力触发的自动驱逐,由 kubelet 负责;另一类是通过 Eviction API 主动发起的驱逐,kubectl drain 走的就是这条路。自动驱逐依赖一组阈值配置,分为软驱逐和硬驱逐两种。硬驱逐没有宽限期,条件一满足 kubelet 立刻回收 Pod,典型配置如 memory.available<100Mi;软驱逐则要配合宽限期,条件持续满足超过设定时间才动手,比如 memory.available<500Mi 配合 1 分 30 秒的宽限期。

驱逐时 kubelet 会给 Pod 发送终止信号,并遵循 terminationGracePeriodSeconds 指定的优雅退出时间。如果超过宽限期 Pod 仍未退出,就会被强制杀死。这里有个容易踩的坑:使用 emptyDir 存储 Pod 内部数据的容器,被驱逐时本地数据会直接丢失。所以给关键 Pod 配置 PodDisruptionBudget 就显得尤为重要,它能保证驱逐过程中始终保持最小可用副本数,避免服务整体不可用。

还需要区分驱逐与抢占的不同。抢占发生在调度阶段,是高优先级 Pod 抢走低优先级 Pod 的节点位置;驱逐则发生在运行阶段,由节点压力或管理员主动触发。两者都会删除 Pod,但触发链路和影响范围完全不一样。

二、节点排水的标准操作流程

排水一般分三步走:先封锁节点阻止新 Pod 调度过来,再驱逐存量 Pod,最后维护完成解除封锁。第一步用 cordon 命令:

# 标记节点为不可调度
kubectl cordon node-worker-01

# 查看节点状态,会显示 SchedulingDisabled
kubectl get nodes

这一步执行后,节点上已有的 Pod 不受影响,只是调度器不再往这个节点分配新的 Pod。它是排水的安全前置动作,即使维护计划临时取消,随时可以用 uncordon 恢复,成本几乎为零。

第二步是核心的 drain 命令。直接执行通常会报错,因为节点上往往存在 DaemonSet 管理的 Pod(比如日志采集、网络插件),这类 Pod 本来就应该跟着节点走,驱逐没有意义,需要显式忽略:

# 驱逐节点上所有可驱逐的 Pod
kubectl drain node-worker-01 \
  --ignore-daemonsets \
  --delete-emptydir-data \
  --grace-period=120 \
  --force

几个关键参数要理解清楚。--ignore-daemonsets 跳过 DaemonSet Pod,几乎必加;--delete-emptydir-data 允许删除使用 emptyDir 的 Pod,注意数据会丢失,加之前务必确认;--force 用于驱逐不受控制器管理的裸 Pod,这类 Pod 被删后不会在其他节点重建,加不加要想清楚;--grace-period 设定优雅退出时间,给应用留够清理资源、完成收尾的时间。drain 执行成功后,节点会自动处于封锁状态,不需要重复 cordon。

第三步,维护结束后解除封锁:

# 解除节点封锁,恢复调度
kubectl uncordon node-worker-01

节点恢复调度能力后,新的 Pod 会正常分配过来。之前被驱逐的 Pod 已经在其他节点重建,不会自动迁回,这一点要心里有数。如果希望重新均衡负载,可以考虑用 Descheduler 之类的工具做二次调度。

三、排水过程中的常见报错与排查

最常见的报错是 Pod 驱逐被阻塞,命令卡住不动。除了前面提到的 DaemonSet 问题,还有两种情况。一是存在裸 Pod,报错信息会提示 use --force to delete;二是 PodDisruptionBudget 不满足条件,比如Deployment 只有 2 个副本,PDB 要求 minAvailable 为 2,drain 就无法驱逐任何一个 Pod。这时不要盲目加 --force,应该先评估业务容量,临时扩容副本数或调整 PDB 配置后再操作:

# 查看 PDB 状态和当前允许的驱逐数量
kubectl get pdb -n production
# 查看 ALLOWED DISRUPTIONS 列,为 0 说明暂时不能驱逐

# 查看节点上还残留哪些 Pod
kubectl get pods -A --field-selector spec.nodeName=node-worker-01

另一个高频问题是 Pod 卡在 Terminating 状态,drain 命令迟迟不返回。这通常是因为容器内的进程没有正确处理 SIGTERM 信号,或者清理逻辑耗时超过了宽限期。可以单独查看某个 Pod 的事件和状态确认原因,必要时用 kubectl delete pod xxx --grace-period=0 --force 强制删除,但这属于最后手段,强删可能导致数据不一致,生产环境要谨慎。

还有一种情况值得注意:drain 提示 cannot delete Pods with local storage。这是因为 Pod 使用了 emptyDir 或宿主机本地存储,默认策略禁止驱逐以保护数据。确认数据可丢后再加 --delete-emptydir-data,如果数据重要,就要先做数据迁移,而不是想办法绕过限制。

四、生产环境排水的实践建议

排水前先做容量检查。用 kubectl describe nodes 看一眼其他节点的可分配资源,确认被驱逐的 Pod 有地方接收。如果集群本身资源就很紧张,先扩容节点池再排水,否则 Pod 会进入 Pending 状态,反而制造故障。

给关键业务配好 PodDisruptionBudget 是排水安全的前提。建议所有多副本服务都设置 minAvailable 或 maxUnavailable,让驱逐过程天然受保护。对于单副本的有状态服务,比如数据库类应用,先评估是否支持自动迁移,很多时候更稳妥的做法是手动控制迁移节奏,而不是依赖 drain 一把梭。

维护多台节点时务必逐台进行,等上一台节点的 Pod 全部重新调度并就绪后再处理下一台。批量 cordon 再批量 drain 的做法看似高效,实际等于一次性抽走大片容量,很容易触发连锁故障。把 cordon、drain、uncordon 这套流程写成脚本或纳入自动化运维平台时,记得加上就绪探针校验和失败回滚逻辑,让节点维护真正做到业务无感。

Kubernetes Pod驱逐节点排水kubectl drain修改时间:2026-09-07 08:39:04

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260907/52095.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。