小张在街角开了一家“深夜食堂”,生意越做越好,决定开成连锁店。可他很快发现:后厨灶台多,菜谱乱,顾客排队没人管。于是他招了三个人:店长负责规划后厨要开几个灶台、灶台坏了马上换新的;服务员负责站在门口,不管后厨怎么调整,顾客永远从这个门点餐;而灶台本身,是厨师们炒菜的最小阵地。这三者缺一不可,配合起来就是一套完整的餐饮管理体系。 在 Kubernetes(简称 K8s)的世界里,这套体系对应着三个最核心的资源对象:Pod 是后厨的灶台,Service 是门口的服务员,Deployment 是统筹全局的店长。本文用大白话讲清楚它们各自管什么、怎么配合,并通过一个完整案例,带你理解一次“订单从进店到上桌”的完整旅程。读完你就能建立起容器编排的底层直觉,而不是被一连串陌生名词吓住。

岗位关联

掌握这三件套,等于拿到了 K8s 世界的第一把钥匙。无论你是做 AI 模型部署还是后端服务运维,它们都是云原生时代绕不开的必修课。

目录
  1. 可视化演示
  2. K8s入门总览
  3. Pod核心概念
  4. Service网络机制
  5. Deployment发布控制
  6. 三件套协同关系
  7. 实战部署流程
  8. 核心面试考点
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

动态演示K8s三件套的核心机制,通过全局/局部/动态/静态四种模式展示关键概念与交互流程。

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

K8s三件套:三件套协 三件套协作架构与职责划分 Pod容器运行与生命周期管理 核心机制可视化 K8s三件套整体架构与关键组件

K8s入门总览

小张的“深夜食堂”在一条街上连开了五家分店,每家店的灶台数量、营业时间、员工排班都不一样。靠人肉管理显然行不通,他需要一套“总部管理系统”:总部下达指令,各分店执行报告,所有状态汇到一块大屏上。Kubernetes 就是这套餐饮集团的总部管理系统,只是它管理的不是门店,而是成千上万个容器。

K8s 的名字来源于希腊语“舵手”,由 Google 基于内部 Borg 系统开源。它解决的核心问题是容器编排:当你要部署 100 个 AI 推理服务实例,靠手动 docker run 会疯掉的。K8s 让“运维厨房”自动化——你只需要告诉系统“我想要什么”,它会自己搞定“怎么实现”。

从架构上看,K8s 集群由两类角色组成:Master(主节点)是总部大脑,负责调度、认证、存储配置;Node(工作节点)是各分店厨房,真正运行 Pod。日常你通过 kubectl 命令行工具与集群对话,就像用手机 App 给总部下指令;而 YAML 文件里的内容,就是你和总部签的“服务标准合同”。这套声明式管理的核心思想,可以浓缩成一个收敛公式:

一句话回扣:就像总部盯着各分店的实际营业额与目标营业额,差距大就加派人手、调整菜单,K8s 控制器就是那个永不休息的区域经理。理解了这套“期望—实际—调节”的循环,三件套的戏份就好安排多了。

实际状态⟶控制器调节期望状态\text{实际状态} \overset{\text{控制器调节}}{\longrightarrow} \text{期望状态}
  1. 期望状态你在 YAML 里写下的目标,例如“我要 3 个 Pod 副本运行我的模型服务”。
    期望状态=spec.replicas\text{期望状态} = \text{spec.replicas}
  2. 实际状态当前集群里真实存在的 Pod 数量与版本,可能因为崩溃、停机而偏离期望。
    实际状态=∑运行中的 Pod\text{实际状态} = \sum \text{运行中的 Pod}
  3. 控制器调节K8s 内部的控制器(如 ReplicaSet)不断对比两者,发现差异就创建或删除 Pod,让实际状态始终向期望状态收敛。
    Δ=期望状态−实际状态⇒控制器执行∣Δ∣次调整\Delta = \text{期望状态} - \text{实际状态} \Rightarrow \text{控制器执行} \lvert \Delta \rvert \text{次调整}

Pod核心概念

深夜食堂的后厨里,每个灶台都配好了燃气、排烟管和案板。一个灶台可以只给一位厨师用,也可以两位厨师共用——一位颠勺、一位配菜,他们共享同一个台面空间和调味料架。在 K8s 里,这个“灶台”就是 Pod,而灶台上的厨师们,就是容器。

Pod 是 Kubernetes 中最小的调度和部署单元。以前我们直接用 Docker 启动容器,但在 K8s 中,容器必须被“包”进 Pod 里运行。Pod 里的多个容器共享同一个网络命名空间和存储卷:它们可以用 localhost 互相通信,也可以读写同一块数据盘。最常见的例子是“主容器 + 边车容器”:主容器跑 AI 模型推理,边车容器专门采集日志、转发监控指标,两者同生共死。

Pod 的存在是“短命”的。它可能因为节点宕机、内存不足、探针失败而被删除重建。每次重建,Pod 的 IP 都会变化,就像灶台随时可能被拆掉换新址,但灶台本身的功能不变。一个 Pod 的生命周期会经历 Pending(排队等资源)、Running(正常运行)、Succeeded(成功退出)或 Failed(异常退出)等状态。K8s 会通过重启策略决定是否把“死掉”的 Pod 拉起来重跑。Pod 的多容器特性和共享拓扑,可以写成这样:

回扣比喻:正因为灶台(Pod)会随时被拆掉重建,顾客(请求)才不能永远记着某个灶台的位置。这就轮到服务员(Service)登场了——她不需要关心后厨的灶台换了几轮,只需要提供一个永远不变的“点餐窗口”。

Pod=⋃i=1n(容器i+共享存储卷i)\displaystyle \text{Pod} = \bigcup_{i=1}^{n} \left( \text{容器}_i + \text{共享存储卷}_i \right)
  1. 容器_iPod 内第 i 个容器镜像,例如 AI 推理引擎和日志采集器各一个容器。
    容器i=imagei\text{容器}_i = \text{image}_i
  2. 共享存储卷_i多个容器共同挂载的存储卷,让它们能读写同一份模型文件或日志文件。
    存储卷↦容器1,容器2,…\text{存储卷} \mapsto \text{容器}_1, \text{容器}_2, \dots
  3. 并集所有这些容器和卷“打包”成一个整体,由 K8s 统一调度。
    ∀i∈{1,…,n}:容器i⊆Pod\forall i \in \{1,\dots,n\}: \text{容器}_i \subseteq \text{Pod}

Service网络机制

深夜食堂的顾客永远不会直接冲进后厨找灶台,那样既危险又混乱。服务员站在门口,顾客只要说“来一份鱼香肉丝”,服务员就会下单,让后厨任意一个空闲灶台来做。对顾客来说,他始终只面对同一个“点餐窗口”——这就是 Service 的角色。

在 K8s 里,Pod 随时会重建,IP 也跟着变。如果 A 服务直接记录 B 服务的 Pod IP,B 一重启,A 就找不到它了。Service 提供了一个稳定访问入口,可以是固定的虚拟 IP(ClusterIP),也可以是一个 DNS 名字。用户请求打到 Service 上,Service 再转发给后端的某一个 Pod。

Service 怎么知道该把流量转给谁?靠的是标签选择器(selector)。Pod 上有标签,比如 app: nginx 或 tier: backend;Service 声明“我要选择哪些标签的 Pod”,凡匹配的 Pod 自动进入它的后端列表,不匹配的则被剔除。这就像服务员手里有一份“会做鱼香肉丝的厨师名单”,新厨师入职时贴上菜系标签,就自动补进名单;离职时撕掉标签,就自动移出名单。Service 内部通过 kube-proxy 组件实现负载均衡,默认是轮询算法,每个后端 Pod 被选中的概率是均等的:

回扣比喻:服务员(Service)最棒的地方是,她手里那张“厨师名单”永远实时更新。哪怕后厨灶台全换新了,顾客依然在同一个窗口点单——这正是微服务之间通信的基础。

P(请求被转发到某个 Pod)=1N\displaystyle P(\text{请求被转发到某个 Pod}) = \frac{1}{N}
  1. NService 后端可用 Pod 的数量,即 Endpoints 列表的长度。
    N=∣Endpoints∣N = \lvert \text{Endpoints} \rvert
  2. 分子 1假设每个请求独立,且采用轮询/随机策略,每个 Pod 被选中的机会相等。
    每个 Pod 的权重=1\text{每个 Pod 的权重} = 1
  3. 分母 N后端 Pod 越多,单个 Pod 分到的流量比例越小,天然实现负载均衡。
    lim⁡N→∞1N=0\lim_{N \to \infty} \frac{1}{N} = 0

Deployment发布控制

店长小张每天要操心三件事:后厨开几个灶台、灶台坏了要不要补、新菜单怎么在不影响营业的情况下换上去。这些事,在 K8s 里都由 Deployment 负责,它堪称最称职的店长。

Deployment 是一种控制器资源,它负责描述“应用期望的最终状态”:副本数要几个、用哪个镜像版本、资源限制是多少。你只需要写一份 YAML,Deployment 就会保证集群里时刻有这么多 Pod 在运行。Pod 挂了,它立刻重建;副本不够,它立刻扩容。它不直接创建 Pod,而是通过管理 ReplicaSet(副本集)来间接控制 Pod。

比起“保证数量”,更体现店长功力的是滚动更新(Rolling Update)。假设你的 AI 模型从 v1 升级到 v2,Deployment 不会把旧的 3 个 Pod 全部杀掉再开新的,而是像旧灶台换新灶台一样:先起一个新 Pod,等它 ready,再停掉一个旧 Pod。整个过程服务不中断,随时有可用的 Pod 在接客。更贴心的是,如果 v2 启动失败,Deployment 会自动暂停并支持一键回滚到 v1,就像店长发现新菜不行,立刻把旧菜单翻回来。滚动更新期间,维护可用副本数量的核心约束是:

回扣比喻:店长从不让后厨“全军覆没”。他每次只换一个灶台,新灶台点火成功才拆旧灶台,生意始终红火。Deployment 就是这样一个懂节奏的店长,把更新这件事变得像呼吸一样自然。

Availablet=Desired−Unavailablet\displaystyle \text{Available}_t = \text{Desired} - \text{Unavailable}_t
  1. DesiredDeployment 声明想要的副本总数,例如 3。
    Desired=spec.replicas=3\text{Desired} = \text{spec.replicas} = 3
  2. Unavailable_t时刻 t 正处于不可用状态的副本数量,包括正在被杀掉的旧 Pod 和还没 ready 的新 Pod。
    Unavailablet=旧 Pod 中已下线数+新 Pod 中未就绪数\text{Unavailable}_t = \text{旧 Pod 中已下线数} + \text{新 Pod 中未就绪数}
  3. Available_t时刻 t 真正能对外提供服务的副本数。K8s 的部署策略保证它不低于 Desired - maxUnavailable。
    Availablet≥Desired−maxUnavailable\text{Available}_t \ge \text{Desired} - \text{maxUnavailable}

三件套协同关系

现在把三个角色放到同一个场景里:顾客走进深夜食堂,对服务员说“来一份招牌炒饭”。服务员在菜单上记下订单,转身把订单递给任意一个空闲灶台;灶台上的厨师开始炒菜;店长在旁边巡视,随时准备补灶台或换新菜单。整个流程环环相扣,缺一不可。

用 K8s 的话说,一次完整请求的路径是这样的:用户或上游服务发起请求到 Service 的稳定 IP;Service 通过 label selector 找到一组健康的 Pod,把请求转发给其中一个;Deployment 则持续监控这组 Pod 的数量与版本,确保永远有足够的灶台在待命。三者各司其职:Pod 管运行、Service 管流量、Deployment 管声明。

这条链路还有个精妙之处:三个对象通过“标签”这个暗号联系。Deployment 创建的 Pod 带着 app: recommend 标签;Service 的 selector 也写着 app: recommend。于是,当 Deployment 滚动更新时,新 Pod 带着同样的标签加入,Service 自动感知并开始给它分流量;旧 Pod 被删除时,Service 自动把它从后端列表里摘掉。用户无感知,流量不中断。整条协同链路可以形式化表示为:

回扣比喻:小张的餐厅能越开越大,正是因为三个角色配合默契:服务员不碰菜刀,店长不直接炒菜,灶台只专心出餐。K8s 的设计哲学就是“单一职责”,每个对象把自己的事做到极致。

请求→Service 转发PodiPodi←ReplicaSet 管理Deployment\displaystyle \text{请求} \xrightarrow{\text{Service 转发}} \text{Pod}_{i} \qquad \text{Pod}_i \xleftarrow{\text{ReplicaSet 管理}} \text{Deployment}
  1. Service 转发Service 根据标签选择器,把流量按策略转发给 Pod_i。
    selector(app)=Pod 的 labels\text{selector}(app) = \text{Pod 的 labels}
  2. Pod_i被选中的第 i 个后端 Pod,它是真正承载容器运行的单元。
    Podi∈Endpoints\text{Pod}_i \in \text{Endpoints}
  3. ReplicaSet 管理Deployment 通过 ReplicaSet 对 Pod 进行扩容、缩容和版本替换。
    Deployment→ReplicaSet→Pod\text{Deployment} \rightarrow \text{ReplicaSet} \rightarrow \text{Pod}

实战部署流程

理论讲了一堆,我们来真实走一遍“深夜食堂”上线新菜品的全流程。假设你是一个 AI 应用开发者,要把一个 PyTorch 模型推理服务部署到 K8s 集群,版本 v1,需要 3 个副本。

第一步,编写 YAML 文件。YAML 是 K8s 的世界语言,它告诉集群“我想要什么”。最简配置包含三部分:Deployment 里写镜像地址、副本数、容器端口;Service 里写稳定访问端口和标签选择器。第二步,执行 kubectl apply -f app.yaml 把声明提交给集群。第三步,用 kubectl get pods 查看 Pod 是否全部 Running。当 3 个 Pod 都变为 Ready 后,Service 会自动创建 Endpoints,把流量分发到这些 Pod 上。

第四步,版本升级。你训练出了精度更高的 v2 模型,修改 YAML 中的镜像标签为 v2,再次 kubectl apply。Deployment 开始滚动更新:新建 v2 Pod,逐步替换 v1 Pod。期间你可以用 kubectl rollout status 实时观察进度;如果 v2 有 Bug,用 kubectl rollout undo 一键回滚。判断一次发布是否成功的黄金标准是就绪副本数是否达标:

回扣比喻:这一套流程把“开店”变成了“填表格”——你只需把菜单(YAML)交给总部,店长(Deployment)、服务员(Service)、灶台(Pod)会自动跑起来。AI 工程落地的效率,就是这么被提上去的。

Ready 数=∑i=1n1(Podi 就绪)\displaystyle \text{Ready 数} = \sum_{i=1}^{n} \mathbb{1}(\text{Pod}_i \text{ 就绪})
  1. 求和号遍历 Deployment 期望创建的全部 Pod,逐个统计状态。
    i=1,2,…,ni = 1, 2, \dots, n
  2. 指示函数当 Pod_i 的就绪探针通过时取 1,否则取 0,即只有真正 Ready 的副本才被计入。
    1(Podi 就绪)={1,Ready0,Not Ready\mathbb{1}(\text{Pod}_i \text{ 就绪}) =\begin{cases}1, & \text{Ready} \\0, & \text{Not Ready}\end{cases}
  3. Ready 数当 Ready 数等于 Desired 时,发布完成;小于 Desired 时,系统继续调度直至收敛。
    Ready 数=Desired⇔发布完成\text{Ready 数} = \text{Desired} \Leftrightarrow \text{发布完成}

核心面试考点

前面六节已经把三件套的日常讲清楚了。如果你要参加面试或写简历,还需要把下面这些“暗号”记住:它们是你和面试官对暗号的钥匙。

第一组暗号是对象关系:容器嵌套在 Pod 里,Pod 由 ReplicaSet 管理,ReplicaSet 由 Deployment 管理;Service 独立于这条链,只通过标签与 Pod 松耦合。第二组是更新策略:滚动更新有两个关键参数 maxSurge(最多允许多出几个 Pod)和 maxUnavailable(最多允许几个 Pod 不可用),它们共同保证更新期间服务不中断。第三组是网络原理:Service 的 ClusterIP 是虚拟 IP,真正转发靠节点上的 kube-proxy 写 iptables/IPVS 规则。

还有一道高频题:Pod 被删除重建后,IP 变了,为什么 Service 还能找到它?答案是,Service 的 Endpoints 控制器会持续监听 Pod 的变化,把新 Pod 的 IP 加入转发列表。这也是“服务员手里名单实时更新”的底层实现。面试中最常考的更新容错公式是:

回扣比喻:面试官问的其实不是“背参数”,而是你有没有理解店长脑子里那本账:既不能把灶台全拆了停工(maxUnavailable),也不能一下开太多灶台浪费成本(maxSurge)。账算明白了,K8s 三件套也就真正吃透了。

不可用副本上限=⌊Desired×maxUnavailable⌋\displaystyle \text{不可用副本上限} = \left\lfloor \text{Desired} \times \text{maxUnavailable} \right\rfloor
  1. Desired × maxUnavailablemaxUnavailable 可以写成百分比,与期望副本数相乘得到允许不可用的副本数。
    Desired×25%=0.75 个\text{Desired} \times 25\% = 0.75 \text{ 个}
  2. 向下取整副本数必须是整数,不能出现 0.75 个 Pod 的说法。
    ⌊0.75⌋=0\lfloor 0.75 \rfloor = 0
  3. 配合 maxSurgemaxSurge 控制最多能多创建几个新 Pod,两者合力保证既快又稳。
    maxSurge+maxUnavailable≥1\text{maxSurge} + \text{maxUnavailable} \ge 1

AI 应用场景

模型推理服务部署

阶段:模型部署上线阶段

解决的问题:训练好的 AI 模型要对外提供 API 服务,传统方式是在几台服务器上手动运行 docker run,一旦进程崩溃或流量突增,需要人工介入重启或扩容,既慢又容易出错。用 K8s 三件套后,Deployment 保证推理服务始终有 N 个副本在运行;Service 提供稳定的 API 地址;流量增大时,修改副本数即可快速扩容。

具体案例:某推荐系统团队把训练好的排序模型打包成 v1 镜像,编写 Deployment YAML 声明 3 个副本,再创建 Service 暴露 8080 端口。模型上线当天流量翻倍,运维人员把 replicas 改为 6,30 秒内新增的 Pod 全部就绪,服务无感知扩容。

推理服务灰度发布

阶段:模型版本迭代阶段

解决的问题:新模型在离线评测指标更好,但线上效果未知。传统做法是深夜停机换版本,风险大且影响用户体验。用 Deployment 的滚动更新机制,可以让新版本 Pod 逐个替换旧版本,随时观察日志和指标;一旦发现异常,kubectl rollout undo 秒级回滚。

具体案例:某语音识别团队将模型从 v2 升级到 v3,滚动更新过程中,先启动 1 个 v3 Pod,此时 Service 会把部分流量分给它;v3 的错误率明显低于 v2,Deployment 继续替换剩余 Pod;若错误率飙升,团队立刻中止更新并回滚到 v2,全程用户几乎无感知。

Python 演示

python58 行
"""K8s三件套概念模拟:用代码演示滚动更新与流量分发"""import time  class Pod:    id_counter = 0     def __init__(self, version):        self.id = Pod.id_counter        Pod.id_counter += 1        self.version = version        self.is_ready = True     def describe(self):        state = "就绪" if self.is_ready else "下线"        return f"Pod-{self.id}(v{self.version},{state})"  class Deployment:    def __init__(self, name, replicas, version):        self.name = name        self.desired_replicas = replicas        self.version = version        self.pod_list = [Pod(version) for _ in range(replicas)]     def rolling_update(self, new_version, batch_size=1):        print(f"开始滚动更新:v{self.version} -> v{new_version}")        order_count = 0        while order_count < self.desired_replicas:            new_pod = Pod(new_version)            old_pod = self.pod_list.pop(0)            old_pod.is_ready = False            self.pod_list.append(new_pod)            order_count += batch_size            print(f"  {old_pod.describe()},替换为 {new_pod.describe()}")            time.sleep(0.2)        self.version = new_version        print(f"更新完成:{self.name} 现运行 v{new_version}")  class Service:    def __init__(self, deployment):        self.deployment = deployment        self.endpoint_list = deployment.pod_list     def request(self):        if not self.endpoint_list:            return "无可用 Pod"        pod = self.endpoint_list[0]        return f"请求命中 {pod.describe()}"  if __name__ == "__main__":    dep = Deployment("ai-model", 3, "v1")    svc = Service(dep)    print(svc.request())    dep.rolling_update("v2")    print(svc.request())
目的:用纯 Python 模拟 Deployment 滚动更新和 Service 流量分发,理解三件套的核心分工。
  1. class Deployment对应 K8s 里的 Deployment 控制器,维护期望副本数和版本号。
  2. self.pod_list = [Pod(version) for _ in range(replicas)]初始化时创建期望数量的 Pod,像店长一次性开好三个灶台。
  3. def rolling_update(self, new_version, batch_size=1)对应滚动更新流程,每次只替换 batch_size 个旧 Pod。
  4. old_pod.is_ready = False模拟旧 Pod 被下线,真实 K8s 中它会收到终止信号并腾空流量。
  5. self.pod_list.append(new_pod)新 Pod 加入列表,Service 会自动感知并向它分发流量。
  6. class Service对应 K8s 里的 Service 对象,负责把请求转发到后端的某一个 Pod。
  7. self.endpoint_list = deployment.pod_list模拟 Service 的 Endpoints 列表,始终指向当前存活的 Pod。
  8. svc.request()模拟一次用户请求被分发到后端 Pod,验证服务在更新过程中始终可用。

常见误区

误区我一直以为 Pod 就是容器,K8s 里运行的最小单位是 Docker 容器,Pod 只是给容器改了个名字。

正解Pod 是比容器高一层的东西。一个 Pod 里可以放多个容器,这些容器共享网络命名空间、共享存储卷,同生共死。就像灶台上可以站两位厨师,他们共用一个燃气表和调料架。K8s 的最小调度单元是 Pod,不是容器。

为何常见:大家从 Docker 进入 K8s,天然容易把容器当作核心概念;而实际使用中很多 Pod 确实只放一个容器,导致两者容易被混淆。

误区Service 的作用就是把请求均匀分给多个 Pod,这不就是负载均衡器吗?

正解负载均衡只是 Service 的副业,它的本职工作是提供稳定的访问入口。Pod 会不断重建、IP 会变,Service 提供了一个固定的虚拟 IP 和 DNS 名,让上游服务不用关心后端 Pod 的生老病死。它更像餐厅门口的服务员,顾客只需面对一个窗口,至于后厨怎么分工,是服务员内部的事。

为何常见:很多人看到 Service 把流量分发给多个 Pod,就把它类比成 Nginx,忽略了它解决“IP 漂移”的核心价值。

误区Deployment 创建了 Pod,所以它直接管着每一个 Pod。

正解Deployment 不直接管理 Pod,而是通过 ReplicaSet 间接管理。Deployment 只管“我要什么版本、几个副本”,ReplicaSet 负责“具体创建和删除 Pod”。更新时,Deployment 会新建一个 ReplicaSet,逐步把 Pod 从旧 ReplicaSet 迁移到新 ReplicaSet;回滚时切换到旧 ReplicaSet 即可。像店长不直接骂厨师,而是通过领班传达指令。

为何常见:我们操作 kubectl 时只接触 Deployment,很少看到中间的 ReplicaSet,所以容易产生“直管”的错觉;面试时深入到“回滚的本质”才会暴露这个盲点。

误区滚动更新嘛,把旧 Pod 全删了,再创建新 Pod,速度最快。

正解恰恰相反,Deployment 默认是“先建新、再删旧”,或者“删一个、建一个”,总之绝不一次性杀光。这就像换后厨灶台,你不能把 5 个灶台全拆了再装新的,那晚高峰就没法做生意了。maxUnavailable 和 maxSurge 两个参数锁定了替换节奏,保证服务零中断。

为何常见:“滚动”这个词容易让人联想到“全部换一遍”,而忽略了它是分批、渐进的过程;实际手动更新线上服务时,才体会到“全量替换”有多危险。

面试题

Q1. 在 Kubernetes 中,Pod 的本质是什么?

单选题 · easy

  • A.最小调度单元← 正确答案
  • B.网络流量入口
  • C.副本控制器
  • D.持久存储卷

答案:A。Pod 是 K8s 中最小的调度和部署单元,容器必须包含在 Pod 里运行。网络流量入口是 Service 的职责,副本控制器是 Deployment/ReplicaSet,持久存储卷是 PV/PVC 的概念。把 Pod 想象成后厨的灶台,它是资源分配和调度的最小单位。

Q2. Service 在 Kubernetes 中的核心作用是什么?

单选题 · easy

  • A.提供稳定访问入口← 正确答案
  • B.管理 Pod 副本数量
  • C.自动化构建镜像
  • D.定期清理运行日志

答案:A。Service 的核心是为一组动态变化的 Pod 提供稳定的虚拟 IP 和 DNS 访问入口,消费者无需关心后端 Pod 的 IP 是否变化。管理副本数量是 Deployment 的事,构建镜像是 CI/CD 的事,清理日志是日志系统的事。Service 就是门口的服务员,让你永远能找到点餐窗口。

Q3. Deployment 执行滚动更新时,默认采用什么策略?

单选题 · mid

  • A.分批替换旧版本← 正确答案
  • B.同时重启全部实例
  • C.先删光再重头建
  • D.仅在空闲时间执行

答案:A。滚动更新的精髓是“分批”:先启动一个新版本 Pod,等它就绪后,再停止一个旧版本 Pod,如此往复,直到全部替换完成。如果同时重启全部实例或先删光再建,都会导致服务短暂不可用。空闲时间执行是定时任务的概念,与滚动更新无关。

Q4. 以下哪些属于 Deployment 的职责?

多选题 · mid

  • A.保证副本数量正确← 正确答案
  • B.滚动更新应用版本← 正确答案
  • C.提供固定访问地址
  • D.支持一键回滚版本← 正确答案

答案:ABD。Deployment 是“店长”,负责保证 Pod 副本数符合期望、执行滚动更新、并在更新失败时回滚到上一版本。提供固定访问地址是 Service 的职责。Deployment 管“数量与版本”,Service 管“入口与转发”,两者各司其职。

Q5. 同一个 Pod 内的多个容器,共享下列哪项资源?

单选题 · mid

  • A.网络命名空间← 正确答案
  • B.独立的存储卷
  • C.各自独立 IP
  • D.隔离的进程视图

答案:A。Pod 内的容器共享同一个网络命名空间,因此它们共享 IP 和端口空间,可以用 localhost 互相通信;同时也建议共享存储卷。B、C、D 都是“独立/隔离”的描述,与 Pod 的“共享”设计相违背。好比同灶台的两位厨师共享燃气和案板。

Q6. Deployment 滚动更新参数 maxUnavailable 的含义是什么?

单选题 · hard

  • A.允许不可用的最大副本数← 正确答案
  • B.必须同时更新的最大数量
  • C.每次新增的副本数量
  • D.保留的旧版本数量

答案:A。maxUnavailable 定义了更新过程中允许同时处于不可用状态的最大副本数(可以是绝对数字或百分比),用来保证更新期间服务不中断。它不等于“同时更新的数量”,也不控制新增数量;新增上限由 maxSurge 控制,保留旧版本数量则不属于该参数职责。

Q7. 关于 Kubernetes 的 Service 类型,以下说法正确的有哪些?

多选题 · hard

  • A.ClusterIP 集群内访问← 正确答案
  • B.NodePort 暴露节点端口← 正确答案
  • C.LoadBalancer 对接云负载← 正确答案
  • D.ExternalName 必然分配 ClusterIP

答案:ABC。ClusterIP 是默认类型,仅在集群内部可达;NodePort 在每个节点上开端口,便于外部访问;LoadBalancer 对接云厂商负载均衡器,把流量引入集群。ExternalName 不会分配 ClusterIP,它只是返回一条 DNS CNAME 记录,把服务映射到外部域名,因此 D 错误。

Q8. Deployment 执行回滚操作的本质是什么?

单选题 · hard

  • A.切换到上一个版本集← 正确答案
  • B.物理删除所有 Pod
  • C.改写标签选择器
  • D.重启全部工作节点

答案:A。Deployment 的每次变更都会产生一个新的 ReplicaSet,回滚就是让 Deployment 把目标 ReplicaSet 切回历史版本,然后按副本数调整 Pod。它不是物理删除所有 Pod,也不改写标签选择器,更不需要重启节点。这就好比店长把“旧菜单”重新翻出来用。

Q9. Kubernetes 实现应用自愈的机制包括哪些?

多选题 · mid

  • A.监控 Pod 健康状态← 正确答案
  • B.重建崩溃的 Pod← 正确答案
  • C.流量避开故障 Pod← 正确答案
  • D.自动清理无用镜像

答案:ABC。K8s 通过探针监控 Pod 健康状态,发现故障后由控制器重建 Pod,同时 Service 会把故障 Pod 从 Endpoints 中摘除,避免流量打到坏实例上。自动清理无用镜像是节点层面的镜像垃圾回收机制,不属于应用自愈范畴。三者配合,就像服务员发现某灶台熄火,立刻叫店长换灶台,同时不再往那个灶台派单。

Q10. 用餐厅比喻来类比,Deployment 最像餐厅里的哪个角色?

单选题 · easy

  • A.店长← 正确答案
  • B.灶台
  • C.菜单
  • D.收银台

答案:A。Deployment 是统筹全局的“店长”,负责决定开几个灶台(副本数)、换新菜单(滚动更新)、出问题时换回旧菜单(回滚)。灶台对应 Pod,菜单对应镜像版本,收银台对应流量入口,但不等于 Service 的全部职责。店长管的是“数量和版本”,这正是 Deployment 的定位。