登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  科技周边 >  业界新闻

Kubernetes Deployment 怎样理解滚动更新的最大不可用数

来源:17golang原创

时间:2026-10-26 22:24:30 478浏览 收藏

Kubernetes Deployment 的 maxUnavailable 表示滚动更新时允许不可用的副本预算,以期望副本数为基数,可以写整数或百分比。百分比向下取整;例如 7 个期望副本、25% 的预算,计算得到 1,控制器按至少 6 个可用副本的目标推进更新。它不是“每批删除多少个 Pod”的固定批次大小。

还要同时看 maxSurge:它给新副本预留额外空间,百分比向上取整。两者控制不同约束。预算是发布控制策略,不是节点故障、应用故障或真实请求错误率的绝对保障。本文围绕这一长期配置问题展开,不把它包装成版本发布新闻。

官方地址:https://kubernetes.io/docs/concepts/workloads/controllers/deployment/

先把百分比换成副本预算

设当前期望副本数为 D,不可用预算为 U,额外副本预算为 S。对百分比配置,先计算 U 的向下取整值和 S 的向上取整值,再讨论控制器为什么保留旧副本或创建新副本。下面都是计算示例,并非某个集群的运行结果。

期望副本maxUnavailable不可用预算maxSurge额外预算
725%125%2
325%025%1
41111

第二行很容易误读:3 的 25% 不足一个,不可用预算就是 0,而额外预算是 1。若旧副本都健康,发布可以先借额外空间启动新副本,等它可用后再减少旧副本,并非两个参数都等于零而无法更新。

Deployment可用预算与额外容量静态关系图
静态预算说明图:maxUnavailable 约束可用副本预算,maxSurge 则描述额外副本空间,两者不能互相替代。

整数配置适合希望预算不随副本数成比例变化的情况,百分比则随当前期望副本变化。若自动扩缩容正在修改 replicas,排障时应以当时生效的期望值解释状态,不能一直拿最初的副本数算预算。两项都显式设置为 0 的 RollingUpdate 配置不可用。

更新停住时,分别看容量与可用状态

假设原有 3 个副本健康,配置 maxUnavailable 为 0、maxSurge 为 1,但新 Pod 一直 Pending。此时先排查能否调度新 Pod:节点资源、配额和调度约束可能阻止额外副本落地。控制器不继续缩旧副本,可能正是在遵守零不可用预算;把预算调大只是允许先少一些服务副本,并没有修好资源问题。

另一个常见情况是新 Pod 显示 Running,却没有变成可用。Running 说明进程所处阶段,Ready 依赖就绪条件;若配置了 minReadySeconds,Ready 还需持续满足相应时长才能计入可用。应用启动失败、探针路径错误、依赖未就绪,会让新版本占用容量而不提供预期可用副本。

Pod就绪状态与Deployment可用副本及发布条件关系图
静态状态关系图:Running、Ready、Available 和 Deployment 条件表达不同信息,不能只凭 Pod 数量判断发布成功。

以下只读命令供读者在有权限的环境使用,命名空间和对象名均为示例;本文没有访问集群或执行命令。

# 确认当前策略、副本期望值与状态字段,按实际对象修改名称
kubectl -n demo get deployment report-api -o yaml
# 查看控制器事件与发布条件
kubectl -n demo describe deployment report-api
# 仅当应用标签确实是 app=report-api 时使用这个筛选
kubectl -n demo get pods -l app=report-api -o wide

把 updatedReplicas 与 availableReplicas 分开读:前者关注新模板副本,后者关注可用状态。Available=True 说明满足最低可用条件,不代表新版本全部替换完成;发布过程中仍可能有旧副本支撑服务。

根据故障证据调整配置

先确认策略类型是 RollingUpdate。Recreate 使用另一种替换方式,不能套用本节预算解释。下面是已有 Deployment 清单的相关片段,并非可单独提交的完整资源;更新时应合并到维护中的完整声明文件。

# 示例:七个期望副本,允许一个不可用,预留两个额外副本
spec:
  replicas: 7
  minReadySeconds: 10
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 2

这个片段表达的是一种取舍,不是适用于所有应用的推荐值。若服务只能容忍一个副本离线,要确认剩余副本承载能力;若集群没有两个额外副本的资源,就先解决容量。若新版本无法 Ready,应修应用或就绪条件,单纯允许更多不可用副本会扩大影响范围。

终止中的 Pod 还可能继续占用资源,实际观察到的 Pod 对象数量或资源消耗不一定严格等于 D+S。不要看到额外 Pod 就立刻判定控制器违背策略,更不要把删除宽限期直接调短当作通用解法。

只修改 strategy 不会改变 Pod 模板,因此不能用它代替发起新版本发布。发布通常由 Pod template 的变更触发;排查时要分清“修改发布预算”和“产生新模板版本”这两个动作。本文不提供对生产对象直接修改的自动执行操作。

确认更新完成,再回看业务可用性

# 观察指定Deployment的发布完成情况;超时是观察结果,不会自动回滚
kubectl -n demo rollout status deployment/report-api --timeout=120s
# 发布后再次查看完整状态,结合期望副本与新旧ReplicaSet判断
kubectl -n demo get deployment report-api -o yaml
kubectl -n demo get replicasets -l app=report-api

进度超出 progressDeadlineSeconds 时,控制器可报告 ProgressDeadlineExceeded;这不是内置自动回滚承诺。观察命令超时也不代表集群已经停止后续协调。修复和回退需要结合实际版本、镜像和应用状态明确决定。

最后检查业务请求。副本满足 Available 只是控制面可用信号;探针设计、流量切换和应用依赖仍会影响真实请求。maxUnavailable=0 不能承诺零错误,PDB 也不应被当成 Deployment 滚动更新预算的替代配置。

  • 核对当前 replicas 与整数化后的 U、S。
  • 区分 Pending、Running、Ready 和 Available。
  • 分别查看新模板副本、可用副本与控制器条件。
  • 依据资源或应用故障修复,避免只放宽预算。
  • 发布完成后再观察实际业务请求,而非只看 Pod 总数。

maxUnavailable=1 是只能有一个新 Pod 不健康吗?

不是专门统计新版本失败数。它影响整个滚动更新的可用预算,应结合新旧副本的可用状态判断,不是允许多少次失败后就停止的计数器。

把 maxSurge 设为 0 就能节省所有临时资源吗?

它取消额外创建预算,但终止中的旧 Pod 仍可能占资源;并且此时需要非零的不可用预算才能推进常规替换。容量和可用性要一起考虑。

为什么预算都满足,更新还是没结束?

满足最低可用目标不代表新副本全部可用或旧副本已经缩为零。检查 Deployment 进度、ReplicaSet 和新 Pod 事件,才能解释发布停在哪个约束上。

字段定义、舍入规则、可用状态和发布进度依据 Kubernetes Deployment 官方文档。表中数值、排查场景与两张说明图为原创推导,未声称实测。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>