想象你是一家 AI 推理餐厅的厨房总调度。大厅里五口灶台同时开火,每口灶台都用同一份菜谱、做出完全一样的菜——它们就是 Pod。从前小店靠喊:“三号灶,换新菜谱!”可当餐厅开到上百口灶台时,喊话彻底失效。于是你不再逐口灶台下命令,而是把一张排班表贴在后厨墙上:需要几口灶、每口用什么菜谱、客流暴涨怎么加灶、换菜谱如何保证不断供。排班表一贴,整个厨房就自己朝着表上的状态运转,缺了补、旧了换、坏了修。这张“排班表”就是 Kubernetes Deployment 的声明式配置,而那个自动盯表、反复核对的总调度,就是 Deployment 控制器。本文就用这座厨房,带你完整理解 Deployment 的配置、更新、回滚、伸缩与排障,把 AI 模型服务稳稳端上生产环境的餐桌。

岗位关联

掌握 Deployment 的声明式管理与滚动更新,是 AI 工程师把推理服务安全送进生产环境的基本功,也是 Kubernetes 面试的高频考点。

目录
  1. 可视化演示
  2. 核心概念:谁是厨房总调度
  3. YAML 编写:排班表怎么写
  4. 更新策略:换新菜谱不断供
  5. 回滚机制:菜谱翻车就翻旧账
  6. 扩缩容:客流增减加撤灶台
  7. 故障排查:灶台罢工如何急救
  8. AI 推理实战:把模型服务开进厨房
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示Deployment滚动更新、金丝雀发布与回滚操作三种核心部署策略,交互切换查看ReplicaSet副本伸缩与流量分配机制。

本节配有交互动效(进入视口后自动加载,约 3KB)。

滚动更新Rolling Update RS1旧版副本逐步缩容v1:3到0 RS2新版副本逐步扩容v2:0到3 maxSurge=1 maxUnavail=0 零停机更新保证服务持续可用

核心概念:谁是厨房总调度

后厨真正说了算的不是某个厨师,而是贴在墙上的那张排班表。你作为厨房总调度,不再逐口锅喊话,而是明确写下:“我要 5 口灶台,每口都用这份菜谱。”之后的反复核对、缺了补、坏了换,全部由 Deployment 这台“自动调度器”完成。它唯一的信仰就是表上的字。

Deployment 是 Kubernetes 里负责管理“无状态应用”的核心控制器。所谓无状态,就像快餐灶台——做完一份菜递给窗口,灶台自己不保留任何记忆,谁来接班都一样。Deployment 不直接创建单个 Pod,而是管辖一个叫 ReplicaSet 的中间层,由 ReplicaSet 批量量产规格完全一致的 Pod。Pod 是灶台,ReplicaSet 是一组同款灶台的施工队,Deployment 则是管施工队的总调度。

用声明式方式提交一份 YAML 后,Deployment 读取其中的期望状态(期望副本数 + Pod 模板),启动一个永不疲倦的控制循环:计数当前就绪 Pod,少了就创建,多了就回收,模板变了就滚动替换。这与命令式操作正好相反——命令式是“帮我杀掉三号灶”,声明式是“我要五口灶,你看着办”。Kubernetes 会不断把现实状态向期望状态收敛,直到二者完全一致。

你只需要维护好墙上那张排班表,剩下的核对、补位、换人,都是总调度自动完成的——这就是声明式管理的魅力:管理者只写“要什么”,不写“怎么做”。

Ddesired={ nreplicas,  Tpod }\displaystyle D_{\text{desired}} = \{\, n_{\text{replicas}},\; T_{\text{pod}} \,\}
Deployment 的期望状态由两个要素构成:期望的副本数量 n_replicas,以及每份 Pod 长什么样的模板 T_pod。控制循环的唯一目标就是让现实等于这个集合。
  1. 期望状态 D_desired这是排班表上的“终极目标”,Deployment 把这张表当作一切行动的出发点。
    Ddesired\displaystyle D_{\text{desired}}
  2. 副本数 n_replicas期望同时运行多少个一模一样的 Pod,对应“我需要几口灶台”。
    nreplicas\displaystyle n_{\text{replicas}}
  3. Pod 模板 T_pod每口灶台用什么镜像、暴露哪个端口、占多少资源,统称为 Pod 模板。
    Tpod\displaystyle T_{\text{pod}}

YAML 编写:排班表怎么写

写排班表不需要会编程,但必须知道格式。一张合格的 YAML 排班表有四个固定栏目:apiVersion(API 版本)、kind(资源类型)、metadata(名字与标签)、spec(期望状态)。其中 spec 才是正文,replicas 写灶台数,selector 负责圈定哪些 Pod 归这家厨房管,template 定义新灶台长什么样。

selector 容易踩坑:它必须能匹配上 template 里的标签。你可以把标签想象成厨师服上的工号牌,Deployment 靠 app: inference 这样的标签来认领自己的灶台。如果选择器匹配不到任何 Pod,Deployment 会一直等;如果匹配到了别人的 Pod,就会误接管。所以排班表里 selector.matchLabels 与 template.metadata.labels 必须约定同一张工号牌。

副本数写在 spec.replicas,默认是 1。控制器看到这个数字后,会清点现实中的就绪 Pod 数,少了就补建,多了就回收。只有当“现实就绪数”达到“期望数”时,Deployment 才会在状态里打上 Available 的标记——意思是厨房完全进入接待状态。

一张排班表写清楚四栏目,剩下的补灶、撤灶、换人全是自动的。你唯一要做的,是保证“工号牌”对得上、数字写得对。

nready≥ndesired⇒Available\displaystyle n_{\text{ready}} \ge n_{\text{desired}} \Rightarrow \text{Available}
就绪 Pod 数量大于等于期望副本数时,Deployment 被判定为“可用”。这也是 kubectl get deployment 时 AVAILABLE 列的数字来源。
  1. 就绪数 n_ready厨房里实际通过验收、能正常出菜的灶台数量,只有就绪探针通过才算数。
    nready\displaystyle n_{\text{ready}}
  2. 期望数 n_desired排班表上写明的目标灶台总额,即 spec.replicas 的值。
    ndesired\displaystyle n_{\text{desired}}
  3. 可用判定 Available当实际就绪数不少于期望数,Deployment 进入 Available 状态,可以放心接客。
    Available\displaystyle \text{Available}

更新策略:换新菜谱不断供

餐厅要换新菜谱,最笨的办法是熄掉全部火再重做——客人全跑了。聪明的总调度会“一次换一口锅”:先熄一口旧灶,按新菜谱起一口新灶,等新灶试菜合格再接客,再动下一口。这就是滚动更新(RollingUpdate):每一步都保证还有灶台在出菜,客人永远不断供。

滚动更新背后由两个旋钮控制。maxUnavailable 规定更新过程中最多允许几口灶同时熄火,相当于“保底出菜数”;maxSurge 规定最多可以比排班表多起几口灶,比如先起一口新灶待命,再熄旧灶,避免高峰期产能下降。金丝雀发布则是滚动更新的精修版:先只更新 1 个副本,观察它的错误率和延迟,确认新菜谱没问题,再放大更新节奏铺满全量。

更新流程本质上是“新旧两个 ReplicaSet 的交接”。新 ReplicaSet 从 0 个 Pod 开始向上建,旧 ReplicaSet 从满额向下撤,此消彼长。控制器实时检查一个约束:当前可用 Pod 数绝不能跌破“期望数减去 maxUnavailable”这条红线,否则更新暂停、等产能回血。

换菜谱不再需要打烊。一次一口锅,旧锅慢慢熄、新锅慢慢旺,客人从头到尾都有菜吃——这就是滚动更新的优雅之处,也是 AI 服务发版不中断的底牌。

navailable≥ndesired−maxUnavailable\displaystyle n_{\text{available}} \ge n_{\text{desired}} - \text{maxUnavailable}
更新期间,可用 Pod 数必须始终不小于期望数减去 maxUnavailable。这条不等式是滚动更新的安全气囊——保证任何时刻都有足够的灶台在出菜。
  1. 可用数 n_available当前正在正常出菜的灶台总数,包括新旧两个版本的灶台。
    navailable\displaystyle n_{\text{available}}
  2. 期望数 n_desired排班表上要求的同时工作的灶台总数。
    ndesired\displaystyle n_{\text{desired}}
  3. 最大不可用 maxUnavailable更新期间容忍的熄火灶台上限,默认 25%(向下取整)。
    maxUnavailable\displaystyle \text{maxUnavailable}

回滚机制:菜谱翻车就翻旧账

再谨慎的试菜也可能翻车:新菜谱让客人排队变长、差评飙升。幸好排班表保留了每一次改版的“历史底稿”——Deployment 每次更新都会生成一个新的 ReplicaSet,并在 revision 里记下版本号,相当于后厨的改版档案室。翻车时,一条命令就能把排班表换回上一版。

kubectl rollout history deployment/ai-inference 可以查看所有历史版本;kubectl rollout undo deployment/ai-inference 一键回滚到上一个版本;想回滚到指定版本,用 --to-revision=2。回滚并不是“修改”当前版本,而是把旧版本的 ReplicaSet 重新请出来接管灶台——档案室里旧底稿一直保存着,随时可以重新上台。

为什么要通过 ReplicaSet 而不是直接改 YAML?因为 Deployment 的历史是由一个个不可变的 ReplicaSet 串联起来的。每次 spec 变化都新建一个 ReplicaSet、归档一个版本,这让回滚变得非常干净:想回到哪个版本,就让对应 ReplicaSet 的副本数从 0 涨回来,同时把当前 ReplicaSet 缩到 0。

菜谱翻车不可怕,可怕的是没有历史底稿。保留好每一版 ReplicaSet,就是给 AI 服务上了“后悔药”保险。

Rrollback=Rn−1\displaystyle R_{\text{rollback}} = R_{n-1}
回滚的本质是:默认选取最新版本 R_n 的前一个版本 R_(n-1),让那个旧 ReplicaSet 重新接管全部副本。旧档案不会丢,所以“后悔药”随时有效。
  1. 当前版本 R_n最新一次发布产生的 ReplicaSet 版本,它是档案室里最新的底稿。
    Rn\displaystyle R_{n}
  2. 回滚目标 R_{n-1}默认回滚选中的是当前版本的前一版,即上一次成功发布的底稿。
    Rn−1\displaystyle R_{n-1}
  3. 版本交接回滚时新旧两套 ReplicaSet 再次执行滚动交替,但方向反过来——旧菜谱重新变为主力。
    Rrollback\displaystyle R_{\text{rollback}}

扩缩容:客流增减加撤灶台

周末客流翻倍,五口灶不够用;深夜没人吃饭,五口灶纯浪费。扩缩容就是灶台数量的加减法。手动模式下,一条 kubectl scale deployment/ai-inference --replicas=8 就能把期望副本数改成 8,控制器自动补齐三口新灶。

但人手盯客流总慢半拍,于是有了 HPA(Horizontal Pod Autoscaler,水平 Pod 自动伸缩器)。HPA 像一位盯着客流的值班经理:每 15 秒看一次监控指标(CPU 利用率、GPU 利用率或自定义 QPS 指标),按公式算出需要的灶台数,再调用 Deployment 的 scale 接口改变副本数。流量涨,它加灶;流量退,它撤灶。

HPA 的计算逻辑并不玄妙:如果当前 5 个 Pod 的 CPU 利用率平均已达 90%,而目标阈值是 50%,那就说明产能差了一倍,需要加灶。它用“当前副本数 ×(当前指标 / 目标指标)”估算,并向上取整,避免出现半口灶。除了自动伸缩,Deployment 还有一个隐性能力——自愈:某口灶台崩溃,ReplicaSet 立刻起一口新的补位,客人几乎无感知。

客流是餐馆的指挥棒。手动 scale 是“看到排队才加灶”,HPA 是“刚有排队苗头就自动加灶”——前者救火,后者防火。

ndesired=⌈ncurrent×mcurrentmtarget⌉\displaystyle n_{\text{desired}} = \left\lceil n_{\text{current}} \times \frac{m_{\text{current}}}{m_{\text{target}}} \right\rceil
HPA 的期望副本数 = 当前副本数 ×(当前指标值 ÷ 目标指标值),结果向上取整。客流翻倍,灶台数也随之翻倍。
  1. 当前副本 n_current正在运行的 Pod 数量,是扩缩容的起点。
    ncurrent\displaystyle n_{\text{current}}
  2. 当前指标 m_current最近一次采样到的平均负载指标,比如 90% 的 CPU 利用率。
    mcurrent\displaystyle m_{\text{current}}
  3. 目标指标 m_target你设定的理想水位,比如 50% 利用率,超过就扩、低于就缩。
    mtarget\displaystyle m_{\text{target}}
  4. 向上取整 ceil计算结果如 7.2,则实际创建 8 个 Pod,保证产能不缩水。
    ⌈⋅⌉\displaystyle \left\lceil \cdot \right\rceil

故障排查:灶台罢工如何急救

再好的厨房也会出乱子:新灶台起不来、镜像拉取失败、一接客就崩溃。排查的第一步是“看状态”。kubectl get deployment 看总览,kubectl get rs 看历史施工队,kubectl get pods 看每口灶台的实时状态。常见的灶台状态有 CrashLoopBackOff(一开火就熄、反复重启)、ImagePullBackOff(菜谱原料拉不到)、Pending(灶台没位置,资源不足)。

第二步是“看口供”。kubectl describe pod <name> 会展示事件列表:为什么没调度成功、镜像拉取卡在哪一步、存活探针失败了几次。事件里通常直接写着根因,比如 Insufficient nvidia.com/gpu 表示 GPU 资源不够,Failed to pull image 表示镜像仓库地址写错或认证失败。

第三步是“看体检报告”。readinessProbe(就绪探针)决定一口灶合格后才能接客,livenessProbe(存活探针)发现灶台“假死”就重启。AI 服务的探针尤其关键:模型文件大、加载慢,如果一启动就接客,首波请求会全部超时。startupProbe 专门给慢启动的模型服务留出加载时间。就绪率是体检总评分:

排查故障的路线图永远是:先看状态知道“卡在哪”,再看事件知道“为什么卡”,最后看探针知道“谁不合格”。三步走完,九成的灶台罢工都能定位根因。

pready=nreadyndesired×100%\displaystyle p_{\text{ready}} = \frac{n_{\text{ready}}}{n_{\text{desired}}} \times 100\%
就绪率 = 就绪 Pod 数 ÷ 期望 Pod 数 × 100%。滚动更新期间就绪率会短暂低于 100%,但如果长期上不去,说明新版本根本没通过体检。
  1. 就绪数 n_ready通过了就绪探针、真正在接客的 Pod 数量。
    nready\displaystyle n_{\text{ready}}
  2. 期望数 n_desired排班表要求的 Pod 总数。
    ndesired\displaystyle n_{\text{desired}}
  3. 就绪率 p_ready用百分比量化厨房的接待能力,100% 表示全员上岗。
    pready\displaystyle p_{\text{ready}}

AI 推理实战:把模型服务开进厨房

把 AI 推理服务部署到 Deployment 上,本质上是在排班表里加入三类“厨房专属配置”。第一是资源配额:推理模型吃 GPU,必须在 resources.limits 里显式声明 nvidia.com/gpu: 1,否则调度器不会把它安排到 GPU 节点上;同时设置 CPU/内存的 requests,让 Kubernetes 能准确计算节点余量。

第二是启动与就绪探针:模型要从磁盘加载进显存,耗时几十秒到几分钟。startupProbe 给足加载时间,readinessProbe 定期请求模型的 /health 接口,只有模型真正加载完成才把流量放进来。这样滚动更新时,新 Pod 没就绪之前,流量一滴都不会切过去。

第三是副本数的估算。可以先压测得出单 Pod 承载的 QPS(每秒请求数),再用业务预估总 QPS 反推最少需要的副本数,通常还要预留 20% 到 50% 的余量应对突发流量。上线后再配 HPA 按 GPU 利用率或自定义 QPS 指标自动伸缩,配合 Prometheus 监控告警,就构成了完整的 AI 推理服务生命周期管理。

AI 推理服务和普通 Web 服务的差别,就在于“灶台预热慢、原料特别重”。用探针兜住加载期,用 GPU 配额锁住资源,用 QPS 公式算清产能,这座模型厨房就能在 Kubernetes 里安稳运转。

nreplicas=⌈Qtotalqper-pod⌉\displaystyle n_{\text{replicas}} = \left\lceil \frac{Q_{\text{total}}}{q_{\text{per-pod}}} \right\rceil
推理服务的最小副本数 = 业务总 QPS ÷ 单 Pod 实测 QPS,向上取整后再加 20%–50% 余量,作为生产环境的副本数基准。
  1. 总流量 Q_total业务高峰期预估的每秒请求总数,来自压测或历史监控。
    Qtotal\displaystyle Q_{\text{total}}
  2. 单 Pod 吞吐 q_per-pod一口“模型灶台”实测每秒能处理的请求数,与模型大小、GPU 型号强相关。
    qper-pod\displaystyle q_{\text{per-pod}}
  3. 取整并留余量除法结果向上取整得到下限,再乘上 1.2–1.5 的冗余系数。
    ⌈⋅⌉\displaystyle \left\lceil \cdot \right\rceil

AI 应用场景

AI 模型版本的滚动升级

阶段:模型部署与运维

解决的问题:传统做法是停服换模型,业务中断数分钟,用户请求全部失败。Deployment 的滚动更新逐 Pod 替换推理镜像:先拉起新版本 Pod,等就绪探针确认模型加载成功,再摘掉旧 Pod,全程服务不中断。

具体案例:某推荐系统团队将推理镜像从 v3 升级到 v4,配置 maxUnavailable: 1,5 个 Pod 逐个替换。GPU 显存随旧 Pod 释放、新 Pod 分配,峰值显存占用平稳,升级期间 P99 延迟几乎无波动。

大模型服务的金丝雀发布

阶段:模型灰度验证

解决的问题:新 checkpoint 效果未知,全量上线一旦出现“AI 说胡话”就是事故。金丝雀发布先只更新 1 个副本,让少量真实流量先“试菜”,观察延迟、拒绝率和回答质量,确认无误后再滚动铺满全量。

具体案例:某对话大模型团队上线新 checkpoint,先更新 1/8 的 Pod 运行新版本,用 shadow 流量对比新旧版本输出,观察 30 分钟 P99 延迟稳定后,再分两批完成全量更新。

HPA 自动扩缩容应对推理洪峰

阶段:资源弹性调度

解决的问题:人工盯监控扩缩容慢则 5 分钟,快则 1 分钟,而流量洪峰以秒级到达。HPA 监听 GPU 利用率或 QPS 自定义指标,自动调整 Deployment 副本数,让推理服务像弹性餐厅一样随客流增减灶台。

具体案例:某在线翻译服务在晚高峰 GPU 利用率冲到 85%,HPA 触发扩容,3 个 Pod 在 2 分钟内自动扩到 8 个;深夜流量回落,自动缩回 2 个,一个月节省约 60% GPU 成本。

Python 演示

python52 行
class DeploymentSimulator:    """极简版 Deployment 控制器:贴着期望状态,不断收敛现实。"""     def __init__(self, name, desired_replicas):        self.name = name        self.desired = desired_replicas        self.ready = {}      # pod_id -> image version        self.image = "v1"        self.revision = 1     def rollout(self, new_version, max_unavailable=1):        while any(v != new_version for v in self.ready.values()):            old_pods = [p for p, v in self.ready.items() if v != new_version]            for pod_id in old_pods[:max_unavailable]:                del self.ready[pod_id]            while len(self.ready) < self.desired:                key = "pod-%d" % (len(self.ready) + 1)                self.ready[key] = new_version        self.image = new_version        self.revision += 1     def scale(self, new_replicas):        pods = list(self.ready.keys())        for pod_id in pods[new_replicas:]:            del self.ready[pod_id]        self.desired = new_replicas        while len(self.ready) < self.desired:            key = "pod-%d" % (len(self.ready) + 1)            self.ready[key] = self.image        self.revision += 1     def ready_count(self):        return len(self.ready)     def __str__(self):        return "%s image=%s desired=%d ready=%d revision=%d" % (            self.name, self.image, self.desired, self.ready_count(), self.revision        )  def main():    deploy = DeploymentSimulator("ai-inference-gpu", 3)    deploy.rollout("v1")    print(deploy)    deploy.rollout("v2", max_unavailable=1)    print(deploy)    deploy.scale(5)    print(deploy)  if __name__ == "__main__":    main()
目的:用纯 Python 模拟 Deployment 控制器的核心逻辑——滚动更新、副本补齐与手动扩缩容,帮助理解 Kubernetes 内部“现实向期望收敛”的过程。
  1. self.ready = {}用字典记录“此刻在岗的每个 Pod 和它端的菜谱版本”,对应控制器眼中的当前状态。
  2. while any(v != new_version for v in self.ready.values()):只要还有旧版本 Pod 在岗,就继续滚动替换,直到全员换新。
  3. for pod_id in old_pods[:max_unavailable]:每轮最多撤下 max_unavailable 个旧灶台,对应滚动更新的“保底可用数”。
  4. while len(self.ready) < self.desired:撤旧的同时立刻补新 Pod,让就绪数始终向期望副本数收敛。
  5. def scale(self, new_replicas):手动扩缩容:客流变大就加灶(补建 Pod),客流变小就撤灶(删除多余 Pod)。
  6. self.revision += 1每次发布或伸缩都记一个版本号,对应 kubectl rollout history 里的 revision 档案。
  7. if __name__ == "__main__":程序入口,依次模拟“初始发布 → 滚动更新 → 扩容”的完整生命周期。

常见误区

误区“数据库这种有状态服务,也可以直接塞进 Deployment 跑,Pod 挂了自动重建不就完事了?”

正解有状态服务需要稳定的网络身份和持久化存储,而 Deployment 的 Pod 名字随机、IP 会变、数据不挂盘,Pod 一重建就是“失忆的克隆人”。模型推理这类“吃完就走”的无状态灶台才适合 Deployment;数据库、消息队列要用 StatefulSet,它提供固定序号、稳定网络标识和独立存储卷。

为何常见:初学 Kubernetes 时先接触 Deployment,容易把“自动重建”误当成“数据不丢”,忽略了无状态与有状态的本质区别。

误区“我把镜像版本一改,Deployment 就会先把所有旧 Pod 删掉,再统一创建新 Pod。”

正解默认策略是滚动更新(RollingUpdate),新旧 ReplicaSet 此消彼长:新 Pod 先创建并等待就绪,就绪后才摘掉一个旧 Pod。整个过程可用 Pod 数始终不低于“期望数减去 maxUnavailable”,不会出现全员下线的空窗。只有把 strategy.type 改成 Recreate 才会先删后建。

为何常见:习惯了“重启服务”的命令式思维,容易把声明式更新误解为“停服重来”。

误区“更新慢是因为这两个参数太小,我把 maxUnavailable 和 maxSurge 都调成 100%,一口气全换掉最快。”

正解maxUnavailable 越大,同时熄火的灶台越多,可用容量下降越明显;maxSurge 越大,同时新建的 Pod 越多,节点资源(尤其是 GPU 显存)可能瞬间被打满。这两个参数是“速度与安全”的天平,AI 推理服务建议 maxUnavailable=1、maxSurge=25%,用慢换稳。

为何常见:追求发布速度是人类直觉,但没意识到资源瓶颈和容量红线才是生产环境的真正约束。

误区“Deployment 只是排班表,删掉它之后,已经跑起来的 Pod 应该还在吧?”

正解默认删除 Deployment 是级联删除,其管理的 ReplicaSet 和全部 Pod 会一并清理。想保留 Pod,需要先把 Deployment 缩容到 0,或者删除时使用 --cascade=false。这也说明 Pod 从来不是独立存在的,它是 ReplicaSet 按排班表量产出来的“员工”。

为何常见:把 YAML 文件当成“配置文件”而非“控制器声明”,没理解对象之间的归属关系。

面试题

Q1. Deployment 管理应用最核心的理念是什么?

单选题 · easy

  • A.用脚本逐个创建并管理容器
  • B.声明式中定义期望状态并自动收敛← 正确答案
  • C.登录服务器手工安装运行环境
  • D.通过监控脚本自动修复所有故障

答案:B。Deployment 的核心是声明式管理:只描述“期望状态”,由控制循环自动把现实向期望收敛。脚本和手工操作是命令式思维;监控脚本只解决修复问题,不解决编排问题,因此 B 正确。

Q2. 以下哪个字段不是 Deployment YAML 的必要顶层字段?

单选题 · easy

  • A.apiVersion(API 版本号声明)
  • B.kind(资源类型声明)
  • C.metadata(资源的名称与标签)
  • D.status(当前状态信息)← 正确答案

答案:D。apiVersion、kind、metadata、spec 是 YAML 的四个必要顶层字段。status 是控制器写入的运行状态,由 Kubernetes 管理,用户不需要也不能在 YAML 中声明它,所以 D 不是必要字段。

Q3. 滚动更新中 maxUnavailable=1 的含义是什么?

单选题 · mid

  • A.同时最多只能创建 1 个新 Pod
  • B.更新中最多允许 1 个 Pod 不可用← 正确答案
  • C.每个节点最多运行 1 个 Pod
  • D.整个更新过程中只能重启一次

答案:B。maxUnavailable 规定更新过程中允许的最大不可用 Pod 数,等于“保底可用数”的保险丝。它不是新建 Pod 的上限(那是 maxSurge 的职责),与节点调度和重启次数无关,故选 B。

Q4. 金丝雀发布的核心做法是什么?

单选题 · mid

  • A.先更新全部副本观察整体效果
  • B.先更新少量副本小流量验证← 正确答案
  • C.先删除所有旧版本再发布新版本
  • D.同时部署两套环境再切换流量

答案:B。金丝雀发布先让新版本接收少量真实流量,观察指标稳定后再放大比例,本质是“小范围试错”。“先更新全部”是风险最高的全量发布;“先删后建”是 Recreate 策略;“两套环境”是蓝绿发布,故选 B。

Q5. 查看 Deployment 滚动更新进度的命令是什么?

单选题 · mid

  • A.kubectl get pods 查看所有容器
  • B.kubectl rollout status 查看进度← 正确答案
  • C.kubectl exec 进入容器内部调试
  • D.kubectl logs 查看容器日志输出

答案:B。kubectl rollout status deployment/<名字> 实时输出滚动更新进度,如“Waiting for deployment spec update to be observed“或”Successfully rolled out”。get pods、exec、logs 都只能看到单点信息,无法反映 rollout 整体状态,故选 B。

Q6. HPA 计算期望副本数的公式可以描述为?

单选题 · hard

  • A.期望副本等于当前指标值本身
  • B.期望副本正比当前指标且反比目标指标← 正确答案
  • C.期望副本等于目标指标除以当前指标
  • D.期望副本始终保持当前副本数不变

答案:B。HPA 公式为 n_desired = ceil(n_current × m_current / m_target):当前指标越高、目标阈值越低,需要的副本越多,故选 B。A 忽略了副本数;C 把比例颠倒了;D 否定了自动伸缩本身。

Q7. 判断 Pod 是否应该接收流量的探针是哪一个?

单选题 · easy

  • A.livenessProbe(存活状态探针)
  • B.readinessProbe(就绪状态探针)← 正确答案
  • C.startupProbe(启动状态探针)
  • D.任何探针都不需要配置

答案:B。readinessProbe 决定 Service 是否把流量转发给该 Pod,未就绪则摘除;livenessProbe 决定是否重启容器;startupProbe 保护慢启动应用。判断“能否接客”用的是就绪探针,故选 B。

Q8. 关于 Deployment 的回滚机制,下列说法正确的是?

多选题 · mid

  • A.回滚只能回到上一个历史版本
  • B.回滚可回到任意保留的历史版本← 正确答案
  • C.回滚会让旧 ReplicaSet 重新接管副本← 正确答案
  • D.回滚过程完全不保留任何历史信息

答案:BC。默认 undo 回滚到上一版,但通过 --to-revision 可回到任意保留的历史版本,故 A 错 B 对。回滚本质是让旧版本的 ReplicaSet 副本数从 0 涨回期望值,C 对。每次发布都会生成新 revision,历史始终留存,D 错。

Q9. 下列哪些属于 Deployment 更新策略的可调参数?

多选题 · mid

  • A.maxUnavailable 最大不可用数量← 正确答案
  • B.maxSurge 最大额外 Pod 数量← 正确答案
  • C.minReadySeconds 最短就绪时间← 正确答案
  • D.replicas 期望副本数量字段

答案:ABC。maxUnavailable、maxSurge 是滚动更新的核心旋钮,minReadySeconds 控制新 Pod 就绪后等待多久才算稳定,三者都属于更新策略调优项。replicas 是独立于更新策略的副本数声明,不属于策略参数,故排除 D。

Q10. 将 AI 推理模型服务部署到 Deployment 时,通常需要哪些配套配置?

多选题 · extreme

  • A.配置 GPU 等资源请求与限制← 正确答案
  • B.就绪探针检查模型加载状态← 正确答案
  • C.Service 暴露推理服务端口← 正确答案
  • D.把所有推理模型打包进镜像

答案:ABC。AI 推理必须声明 GPU 资源才能被调度到 GPU 节点(A);模型加载慢,就绪探针保证加载完成才接流(B);Service 提供稳定入口供调用(C)。D 错误:模型通常放在对象存储或 PVC 中动态加载,而非打进镜像,否则镜像体积达数 GB 且发版成本极高。