导读:本期聚焦于苏沐橙创作的《Kubernetes集群中Pod自愿中断与非自愿中断有什么区别?如何正确处理》,敬请观看详情。Pod被驱逐或意外挂掉后服务为什么还是抖动了?问题往往出在对两类中断的理解不到位。Kubernetes把中断分为自愿中断和非自愿中断两种:前者由驱逐、节点排水、升级维护等管理操作触发,可以通过PodDisruptionBudget设置最小可用副本数来保护;后者则来自节点故障、内核崩溃、资源耗尽等不可控事件,需要靠副本冗余、反亲和性和探针机制来兜底。本文梳理两种中断的触发场景、处理思路和常见配置误区,配合yaml示例讲解PDB的写法、maxUnavailable与minAvailable的区别,以及滚动更新、节点维护时的注意事项,帮助你在集群运维和发布过程中避免服务不可用。

Kubernetes集群中,Pod的“消失”并不都是同一种情况。有时是运维人员主动执行的排水操作或自动缩容,有时是节点突然宕机导致的意外丢失。官方把前者称为自愿中断,后者称为非自愿中断。两类中断的成因、影响面和应对手段完全不同,如果混为一谈,很容易出现“明明配了PDB服务还是挂了”或“节点维护时发布卡死”之类的怪问题。本文从触发场景入手,分别讲清楚两类中断的处理方式。

Kubernetes集群中Pod自愿中断与非自愿中断有什么区别?如何正确处理

什么是非自愿中断,如何兜底

非自愿中断指的是不由人主动触发的Pod丢失,典型场景包括:节点硬件故障或掉电、内核panic、kubelet挂掉后Pod被判定失联、容器因为OOM被内核杀掉、以及资源竞争导致的调度失败。这类中断的共同特点是Kubernetes本身无法预知,也就无法通过PDB(PodDisruptionBudget)之类的资源对象去“审批”它。节点坏了就是坏了, apiserver不会先问一句“你的预算够不够”再让节点宕机。

正因为无法阻止,应对非自愿中断的核心思路是冗余与快速自愈,具体包括几个层面:

  • 多副本部署:Deployment至少设置2个以上副本,单副本服务在任何一次节点故障中都会产生服务中断窗口。
  • 反亲和性调度:通过podAntiAffinity把同一组副本打散到不同节点,避免一个节点挂掉带走全部副本。
  • 拓扑分布约束:使用topologySpreadConstraints配合whenUnsatisfiable: DoNotSchedule,在跨可用区维度上做均匀打散。
  • 探针配置:合理设置livenessProbereadinessProbe,让真正故障的实例尽快从Service的endpoints中摘除。

下面是一个把副本打散到不同节点的典型写法:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              topologyKey: kubernetes.io/hostname
              labelSelector:
                matchLabels:
                  app: web
      containers:
      - name: web
        image: nginx:1.27
        readinessProbe:
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5

这里的preferredDuringScheduling是软策略,集群节点不足时仍能调度成功;如果服务容忍度低、希望强制打散,可以改成requiredDuringSchedulingIgnoredDuringExecution,但要接受极端情况下Pod Pending的代价。此外还要注意terminationGracePeriodSecondspreStop钩子的配合,给存量请求留出排空时间,这部分在下文自愿中断里同样关键。

自愿中断的触发场景与PDB保护

自愿中断是由管理动作触发的Pod终止,常见来源包括:节点排水(kubectl drain)、集群自动缩容、节点池升级、HPA缩容、删除Deployment、以及遵循优雅启动约定的控制器回收旧Pod。与非自愿中断最大的区别在于:执行删除的一方通常会遵循API约定的删除流程,这就给了我们干预的机会。PDB就是这个干预机制的载体,它告诉集群“这组Pod最多允许同时中断多少个”。

PDB支持minAvailablemaxUnavailable两种语义,二者只能选其一,都可以填绝对数量或百分比:

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: web-pdb
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: web

上面的配置含义是:无论何时,标签为app=web的Pod至少要有2个处于Ready状态。当执行kubectl drain时,如果驱逐某个Pod会让Ready数量跌破2,驱逐请求会被拒绝并重试,直到副本数恢复。而maxUnavailable: 1表达的是“最多允许1个Pod不可用”,对3副本的Deployment来说效果与minAvailable: 2等价,但在滚动扩缩场景下语义更直观。一个实用建议:副本数经常变化的服务优先用maxUnavailable,固定副本数的服务用minAvailable更直观。

需要特别强调的是PDB的局限性。它只对“自愿中断”生效,节点宕机、OOM Kill等非自愿事件完全不受PDB约束;它也不能保护滚动更新过程中的Pod——Deployment更新走的是自己的副本控制逻辑,绕过了PDB的预算检查。所以如果你发现“配了PDB发布时还是抖”,那不是PDB失效,而是它本来就不负责这件事,滚动更新的可用性要靠maxUnavailable: 0配合maxSurge: 1来保证。

节点维护与优雅终止的实战细节

有了PDB之后,日常的节点维护操作就顺畅多了。执行kubectl drain <node> --ignore-daemonsets --delete-emptydir-data时,drain会先给节点加cordon标记阻止新Pod调度,然后逐个驱逐Pod。驱逐过程中Eviction API会逐条检查相关PDB,符合预算的驱逐放行,不符合的返回429 Too Many Requests并进入重试。整个过程是异步的,实际体验是drain命令可能停留较久,直到被驱逐的Pod在新节点上Ready、预算释放后继续。

这里有几个容易踩的坑值得展开说一说。第一,单副本服务如果配了minAvailable: 1的PDB,drain会永远卡住,因为驱逐唯一副本必然违反预算。解决办法是提前扩容、接受短暂中断改用maxUnavailable: 1,或者干脆不给单副本服务配PDB。第二,PDB的预算计算基于Ready状态,如果探针配置不当导致新Pod长时间不Ready,也会连带阻塞drain。第三, StatefulSet在Kubernetes 1.25之前对PDB的支持很差(驱逐可能直接删除而非遵循预算),有状态服务的节点维护要格外小心,建议逐个确认副本健康。

最后是被很多团队忽略的优雅终止配置。自愿中断的“优雅”程度取决于Pod自己,默认30秒的宽限期对慢连接服务可能不够:

spec:
  containers:
  - name: web
    lifecycle:
      preStop:
        exec:
          command: ["sh", "-c", "sleep 10"]
    terminationGracePeriodSeconds: 45

preStop里的sleep看似多余,实际是为了对齐负载均衡的endpoint同步延迟:删除请求到达后,Pod的endpoint可能还要几秒才会从各节点的iptables/ipvs规则中移除,这期间仍有新流量打进来,直接退出就会产生连接错误。先sleep再进入SIGTERM处理,配合足够的terminationGracePeriodSeconds,才能真正做到无损发布和无损排水。

总结一下:非自愿中断靠架构兜底(多副本、打散、探针),自愿中断靠流程管控(PDB、驱逐API、优雅终止)。两者结合使用,并且在滚动更新、节点维护等场景分别验证,才是保证Kubernetes服务可用性的完整答案。

KubernetesPod中断PDB修改时间:2026-09-06 20:40:41

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