想象你是一家连锁餐厅的老板。总台有一本《理想运营手册》,上面不写菜谱,只写目标:大堂需要有 3 位传菜员、后厨需要有 5 道招牌菜随时可出、包间至少保留 2 个空位。你不需要天天站在后厨喊“快点炒”,你只需要盯住“现状和手册的差距”:差人就补人,差菜就补菜,多了就撤。Kubernetes(简称 K8s)就是给云上应用开的这样一家“数字化餐厅”。它不直接帮你写业务代码,而是管理“对象”:每个对象就是一张写着目标的卡片,包含类型、名字、期望状态、实际状态。K8s 里的控制器就像值班经理,不停地把实际状态拉回期望状态。本文从这张“卡片”开始,带你认识 Pod、Deployment、Service、Namespace、ConfigMap/Secret、PV/PVC 这些日常必备的 K8s 核心对象模型。

岗位关联

对 AI 从业者而言,K8s 对象模型是搭建训练平台、推理服务、多团队资源隔离的第一块拼图。搞懂它,你就能用“声明目标”的方式管理上千个 AI 任务,而不是靠手工重启容器。

目录
  1. 可视化演示
  2. 声明式调控
  3. Pod单元
  4. 工作负载
  5. 服务发现
  6. 命名空间
  7. 配置密钥
  8. 持久存储
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示Kubernetes核心对象模型:声明式API期望状态循环、Pod为核心的对象层级、Deployment/Service/Ingress协作,通过交互理解对象编排机制。

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

声明式API:期望状态 提交期望状态清单Desired 控制器调和至实际状态Actual Desired → Reconcile → Actual 偏离时自动修复自愈

声明式调控

餐厅总台的《理想运营手册》不会写“张三下午三点去传菜”,只会写“传菜口保持 3 位传菜员”。谁来做、什么时候做,由值班经理根据当前人员数动态安排。这就是“声明式”和“命令式”的区别:命令式是“你去做某事”,声明式是“最终必须达到某个状态”。

K8s 也是这套逻辑。你提交一份 YAML,告诉它“我要 3 个副本”,而不必告诉它“现在创建 Pod、不行,再创建第 2 个”。这份 YAML 就是一个 K8s 对象。每个对象都包含四个核心部分:kind 表示对象类型,metadata 记录名字和标签,spec 是用户声明的期望状态,status 是系统观察到的实际状态。K8s 的 controller-manager 里有一组控制器循环,像值班经理巡店一样不断比较 spec 和 status。

这个“比较差距”的过程可以写成差值的概念:

餐厅经理不会替厨师颠勺,但会盯着“传菜口人数是否达标”。同理,K8s 不关心业务内部如何运行,它只负责让对象的 status 不断逼近 spec。这就是整个对象模型的底层节拍。

Δ(t)=Scurrent(t)−Sdesired\displaystyle \Delta(t) = S_{\mathrm{current}}(t) - S_{\mathrm{desired}}
正值表示实际资源比期望多,负值表示还不够,控制器看到负值就补建,看到正值就回收。
  1. 差值符号它代表 t 时刻“实际状态”与“期望状态”的距离,是控制器每次巡检时算的账。
    Δ(t)\displaystyle \Delta(t)
  2. 当前状态来自对象里的 status,例如当前真实存在的 Pod 数量。
    Scurrent(t)\displaystyle S_{\mathrm{current}}(t)
  3. 期望状态来自对象里的 spec,例如用户写下的 replicas: 3。
    Sdesired\displaystyle S_{\mathrm{desired}}

Pod单元

餐厅里最小服务单位不是“一道菜”,而是一个“餐位”。一个餐位上可以同时放一杯水、一个餐盘、一副餐具,它们共用一张小桌。K8s 里最小的部署单元也是一张“小桌”,叫 Pod。

Pod 是一个或多个容器的集合。这些容器共享同一个网络命名空间、同一个 IP 地址,也能挂载同一块数据卷。就像餐位上的水杯和餐盘共享桌面,业务容器和辅助容器(sidecar)共享网络和存储。Pod 是 K8s 直接调度到节点上的最小单位,节点的 kubelet 负责把 Pod 里的容器拉起来。

一个 Pod 的生命周期通常包括 Pending(等待调度)、Running(运行中)、Succeeded(正常结束)、Failed(失败)。为了让 K8s 判断 Pod 是否“健康”,我们还可以配置探针:存活探针决定是否重启容器,就绪探针决定是否把流量打进来,启动探针决定容器是否完成初始化。探针就像服务员看一眼餐位:杯子空了就续水,客人没走就不能收桌。

如果把这个结构提炼成一张关系图:

所以 Pod 不是简单地把容器堆在一起,而是给它们一个共享的“房间”。容器之间可以用 localhost 通信,也可以读写同一块卷。理解这一点,你就能明白为什么“一个 Pod 只放一个容器”并不是唯一正确姿势。

P=(⋃i=1nci, V, N)\displaystyle P = \left( \bigcup_{i=1}^{n} c_i,\ V,\ N \right)
Pod 可以看作“容器集合 + 共享卷 + 共享网络栈”的整体。
  1. Pod 整体P 表示一个 Pod 对象,它是调度的最小边界。
    P\displaystyle P
  2. 容器集合c_i 是 Pod 里的第 i 个容器,多个容器通过并集组合在一起。
    ⋃i=1nci\displaystyle \bigcup_{i=1}^{n} c_i
  3. 共享卷与共享网络V 代表 Pod 内挂载的数据卷,N 代表所有容器共享的网络栈,这就是“同一个小桌”的含义。
    (V, N)\displaystyle (V,\ N)

工作负载

餐厅有排班表,今天传菜口需要 3 位传菜员。如果其中一人请假,值班经理会立刻补一位;如果生意清淡,又会减少排班。K8s 里负责这种“排班表”的对象是 Deployment,而真正执行“人数控制”的是它下面的 ReplicaSet。

Deployment 是面向应用版本的工作负载对象,它声明期望副本数、容器镜像等信息。ReplicaSet 则像一个“值班班长”,确保集群中随时有指定数量的 Pod。Deployment 管理 ReplicaSet,ReplicaSet 管理 Pod,是一条清晰的控制链。当你要发布新版本时,Deployment 会创建新的 ReplicaSet,然后执行滚动更新:先起新 Pod,再逐步销毁旧 Pod,避免服务瞬间下线。

ReplicaSet 的对账逻辑可以简化成一句话:缺多少就补多少。

这份排班表的威力在于:你要的只是“3 个 Pod 持续存在”,而不是“某个固定 Pod 永远不挂”。Pod 死了,控制器重建一个;镜像更新了,控制器滚动替换。这就是云原生应用能够快速迭代、自动恢复的原因。

nneed=max⁡(0, ndesired−ncurrent)\displaystyle n_{\mathrm{need}} = \max\left(0,\ n_{\mathrm{desired}} - n_{\mathrm{current}}\right)
n_need 是控制器要新建的 Pod 数,只有当前 Pod 数小于期望值时才需要创建。
  1. 期望副本数n_desired 是 Deployment 的 spec.replicas,就是“排班表上的人数”。
    ndesired\displaystyle n_{\mathrm{desired}}
  2. 当前副本数n_current 是 ReplicaSet 当下管理着的 Pod 总数,包括还没就绪的 Pod。
    ncurrent\displaystyle n_{\mathrm{current}}
  3. 取最大值max(0, ...) 保证差值不会变成负数,多出来的 Pod 不会被“补”出来,而是进入缩容流程。
    max⁡(0, ndesired−ncurrent)\displaystyle \max\left(0,\ n_{\mathrm{desired}} - n_{\mathrm{current}}\right)

服务发现

顾客去餐厅吃饭,不需要知道今天后厨是哪位厨师,只需要打餐厅总机。总机按“当前值班传菜员”的名单转接,名单变了,号码不变。K8s 里的 Service 就是这台总机。

Pod 的 IP 地址是临时的,Pod 重建后就会变。如果让业务方直接记住 Pod IP,就像让顾客记厨师手机号,完全不现实。Service 提供一个稳定的虚拟 IP(ClusterIP)和 DNS 名称,然后通过 selector 按标签筛选后端 Pod。只要 Pod 的标签匹配,Service 就会把流量转发过去;后端 Pod 增删时,Service 后端的 Endpoints 会自动更新。

这个选择过程可以看作一个集合:

Service 把“后端 Pod IP 变化”这件事彻底隐藏了。前端服务访问 http://web-svc,不管背后 Pod 换了多少次,总机号码永远不变。这也是微服务之间互相调用不混乱的关键。

E(S)={p∈Pods∣labels(p)⊇Sselector}\displaystyle E(S) = \left\{ p \in \mathrm{Pods} \mid \mathrm{labels}(p) \supseteq S_{\mathrm{selector}} \right\}
Service 的后端集合,就是所有“标签满足 selector 条件”的 Pod。
  1. 后端集合E(S) 表示 Service 动态计算出的可用后端 Pod 集合。
    E(S)\displaystyle E(S)
  2. 候选 Podp 是集群中的任意 Pod,只有标签匹配才进入集合。
    p∈Pods\displaystyle p \in \mathrm{Pods}
  3. 标签匹配labels(p) 是 Pod 的标签集合,S_selector 是 Service 要求匹配的标签集合,前者包含后者时才算命中。
    labels(p)⊇Sselector\displaystyle \mathrm{labels}(p) \supseteq S_{\mathrm{selector}}

命名空间

餐厅会分成大堂、包间、后厨。包间客人不能随便闯进后厨,包间之间也各有门牌。K8s 的 Namespace 就是这种“分区隔间”。

Namespace 可以把一个集群内的资源划分成多个逻辑区域。不同团队可以把对象放进各自的 Namespace,互不干扰;同一个 Namespace 内对象名必须唯一,但不同 Namespace 可以有同名对象。常见的默认 Namespace 包括 default、kube-system(系统组件)、kube-public(公共资源)等。

为了不让某个团队“点太多菜”,K8s 还提供 ResourceQuota 和 LimitRange。ResourceQuota 限制整个 Namespace 的资源总量,比如 CPU、内存、PVC 数量;LimitRange 限制单个 Pod 或容器的上下限。这样,一个大集群就像一个大餐厅,每个包间既独立,又有各自的消费上限。

资源配额的核心约束可以表达为:

Namespace 是大型 AI 平台必备的分隔工具。算法团队、训练团队、推理团队各占一个“包间”,互不干扰,却共享同一个 K8s 集群。配额制也避免了某一个团队把 GPU 全部占走。

∑o∈NSrequest(o)≤quota(NS)\displaystyle \sum_{o \in \mathrm{NS}} \mathrm{request}(o) \le \mathrm{quota}(\mathrm{NS})
一个 Namespace 内所有对象的资源申请总和,不能超过该 Namespace 的配额。
  1. 对每个对象求和o 是该 Namespace 内的对象,把所有对象的请求量加起来。
    ∑o∈NSrequest(o)\displaystyle \sum_{o \in \mathrm{NS}} \mathrm{request}(o)
  2. 资源配额quota(NS) 是管理员给这个 Namespace 设定的资源上限。
    quota(NS)\displaystyle \mathrm{quota}(\mathrm{NS})
  3. 小于等于总和不超过配额,超出的 Pod 会排队等待,直到有资源释放。
    ≤\displaystyle \le

配置密钥

餐厅的招牌菜配方分两种:一种是贴在墙上的公开做法,比如“今日例汤加两片柠檬”;另一种是放在保险柜里的秘方,比如酱料比例。K8s 也提供了两个对应的对象:ConfigMap 和 Secret。

ConfigMap 用来保存非敏感配置,比如日志级别、开关参数、URL 地址;Secret 用来保存敏感信息,比如数据库密码、API Token、证书。两者都可以通过环境变量或文件卷的方式注入容器。容器不关心配置来自哪里,就像厨师不关心配方在墙上还是在保险柜里,只要拿到就能做菜。

需要特别注意的是,Secret 只是做了 base64 编码,并不是加密。base64 相当于把配方换成一种“看着不像原文”的写法,但懂行的人一眼就能还原。真正想要安全,还要配合 RBAC 权限、外部密钥管理服务(如 Vault)等措施。

ConfigMap 与 Secret 的数据结构可以写成:

把配置从镜像里抽出来,是十二要素应用的重要原则。ConfigMap 和 Secret 让“同一份镜像,不同环境配置”成为可能:开发、测试、生产只需换不同的配置对象,不需要重新打包镜像。

CM={(k1,v1),…,(kn,vn)},Secret={(k1,base64(v1)),…,(km,base64(vm))}\displaystyle \mathrm{CM} = \{(k_1,v_1),\dots,(k_n,v_n)\},\quad \mathrm{Secret} = \{(k_1,\mathrm{base64}(v_1)),\dots,(k_m,\mathrm{base64}(v_m))\}
两者都是键值对集合,区别在于 Secret 的值用 base64 包装了一层。
  1. ConfigMap 键值对CM 是普通配置的键值对集合,k_i 是键,v_i 是明文值。
    CM={(k1,v1),…,(kn,vn)}\displaystyle \mathrm{CM} = \{(k_1,v_1),\dots,(k_n,v_n)\}
  2. Secret 编码值Secret 保存敏感数据,每个值都要经过 base64 编码后存储。
    base64(vi)\displaystyle \mathrm{base64}(v_i)
  3. 集合结构两组公式都表示“一系列键值对”,这正是环境变量和配置文件最自然的表达方式。
    {(k1,v1),…,(kn,vn)}\displaystyle \{(k_1,v_1),\dots,(k_n,v_n)\}

持久存储

餐厅后厨有个大仓库,里面是各种食材和半成品。厨师不会直接去超市买货,而是写一张领料单,仓库管理员看到单子后去匹配对应的货架。K8s 的存储模型也是这个流程:PVC 是领料单,PV 是真实存在的货架。

PV(PersistentVolume)是集群中的一块真实存储,它独立于 Pod 存在,可能是云硬盘、NFS、本地盘。PVC(PersistentVolumeClaim)是用户发起的存储申请,声明需要多大容量、什么访问模式。K8s 会把 PVC 和满足条件的 PV 绑定。如果集群配置了 StorageClass,还可以实现“动态供给”:用户不用预先买好 PV,系统按 StorageClass 自动创建一块合适的存储。

绑定关系可以用集合表示:

在 AI 场景里,训练数据和模型权重通常很大,Pod 可以随时销毁重建,但数据必须留下。PVC/PV 把“数据生命周期”和“计算生命周期”分开管理:Pod 走了,存储还在;下一个训练任务来了,重新申领同一个 PVC,就能接着上次的模型继续训练。

Bind(PVC)={PVj∣PVj.capacity≥PVC.request∧mode(PVj)∼mode(PVC)}\displaystyle \mathrm{Bind}(\mathrm{PVC}) = \left\{ PV_j \mid PV_j.\mathrm{capacity} \ge \mathrm{PVC}.\mathrm{request} \land \mathrm{mode}(PV_j) \sim \mathrm{mode}(\mathrm{PVC}) \right\}
一个 PVC 会绑定到某个容量足够、访问模式匹配的 PV 上。
  1. 候选 PV 集合Bind(PVC) 表示能与当前 PVC 绑定的所有 PV。
    Bind(PVC)\displaystyle \mathrm{Bind}(\mathrm{PVC})
  2. 容量条件PV_j.capacity 必须不小于 PVC.request,就像仓库货架装得下领料量。
    PVj.capacity≥PVC.request\displaystyle PV_j.\mathrm{capacity} \ge \mathrm{PVC}.\mathrm{request}
  3. 访问模式匹配读写方式需要匹配,比如“单节点读写”和“多节点读写”不能乱用。
    mode(PVj)∼mode(PVC)\displaystyle \mathrm{mode}(PV_j) \sim \mathrm{mode}(\mathrm{PVC})

AI 应用场景

AI 训练任务发布平台

阶段:模型训练与部署

解决的问题:传统方式直接登录服务器,手工修改代码、重启进程,版本混乱且无法回滚。K8s 用 Deployment 管理训练或推理服务,指定镜像版本和副本数,滚动更新可以逐个替换旧版本,一旦新版本异常还能快速回滚。

具体案例:某 AI 团队的推理服务从 v1 升级到 v2,使用 Deployment 的 RollingUpdate 策略,先启动 1 个新 Pod,确认就绪后再销毁 1 个旧 Pod,直到全部替换完成;配合 Service 的稳定 DNS,客户端无感知。

多团队 GPU 资源隔离

阶段:资源调度与治理

解决的问题:多个算法团队共享一个 K8s 集群时,容易出现“某个任务吃掉所有 GPU”的问题。用 Namespace 把团队隔开,再用 ResourceQuota 限制每个团队最多申请多少 GPU 和内存。

具体案例:某公司为算法团队、数据预处理团队、推理团队分别创建 Namespace,每个 Namespace 配额 8 张 GPU。某个团队提交过量任务时,新 Pod 会 Pending,直到该团队其他任务释放资源。

模型配置与密钥管理

阶段:服务配置与环境管理

解决的问题:同一个推理镜像要在测试和生产环境使用,但测试环境连测试数据库,生产环境连生产数据库;数据库密码也不能直接写进镜像。ConfigMap 和 Secret 分别保存环境差异配置与敏感凭据,实现“镜像不变,配置随环境切换”。

具体案例:某推荐系统服务通过 ConfigMap 传入“模型版本号、日志级别、特征服务地址”,通过 Secret 挂载数据库密码;每次切换模型版本只需更新 ConfigMap,再触发滚动更新即可。

Python 演示

python36 行
class Pod:    def __init__(self, name, version):        self.name = name        self.version = version        self.ready = False class Deployment:    def __init__(self, name, replicas, version):        self.name = name        self.replicas = replicas        self.version = version class SimController:    def __init__(self, deployment):        self.deployment = deployment        self.pods = []     def reconcile(self):        while len(self.pods) < self.deployment.replicas:            self.pods.append(Pod("pod-" + str(len(self.pods) + 1), self.deployment.version))        while len(self.pods) > self.deployment.replicas:            removed = self.pods.pop()            print("delete " + removed.name)        for pod in self.pods:            pod.ready = (pod.version == self.deployment.version)        ready = len([p for p in self.pods if p.ready])        return ready, len(self.pods) if __name__ == "__main__":    app = Deployment("web", 3, "v2")    controller = SimController(app)    for round_no in range(5):        ready, total = controller.reconcile()        print("round " + str(round_no) + ": ready " + str(ready) + "/" + str(total))        if round_no == 2:            app.replicas = 2
目的:用对象模拟 Deployment 和控制器,展示“期望状态”变化后,控制器如何自动扩容、缩容并统计就绪 Pod。
  1. class SimController:定义控制器类,K8s 中对应 controller-manager 里的控制器组件。
  2. def reconcile(self):对账方法,每次循环都让实际状态向期望状态靠近。
  3. while len(self.pods) < self.deployment.replicas:当前 Pod 少于期望副本时,补建 Pod。
  4. while len(self.pods) > self.deployment.replicas:当前 Pod 多于期望副本时,删除多余 Pod。
  5. pod.ready = (pod.version == self.deployment.version)版本匹配才标记为就绪,对应“镜像版本正确并且健康检查通过”。
  6. if round_no == 2: app.replicas = 2模拟运行中途修改 Deployment 的期望副本数,下一次循环会自动缩容。

常见误区

误区K8s 的最小单位是 Pod,所以为了简单,一个 Pod 里永远只放一个容器。多容器 Pod 很怪异,应该尽量避免。

正解Pod 允许并鼓励将“生命周期相同、需要共享网络或存储”的容器放在一起。比如业务容器 + 日志采集 sidecar,就是最常见模式。使用多容器 Pod 的前提是它们必须同生共死、紧密协作,而不是把无关服务硬塞进同一个 Pod。

为何常见:许多人接触 K8s 时先学到“一个 Pod 一个容器”的简单用法,看到多容器 Pod 会误以为违背了最小职责原则。

误区我创建了一个 Deployment,里面写了副本数 3,所以 Deployment 内部直接管理这 3 个 Pod,Pod 挂了 Deployment 重建。

正解Deployment 并不直接操作 Pod。它创建并管理 ReplicaSet,由 ReplicaSet 负责维护 Pod 数量。Deployment 主要管“版本和发布策略”,ReplicaSet 管“数量保证”。理解这条控制链,才能看懂滚动更新时新旧 ReplicaSet 并存的现象。

为何常见:从用户视角看,写的是 Deployment,Pod 也确实被创建了,中间层 ReplicaSet 被忽略了。

误区Secret 里的密码和 Token 是加密保存的,即使被看到也泄露不了。

正解Secret 默认只做 base64 编码,不是加密。base64 只是一种可逆的编码方式,任何人拿到 Secret 的 YAML 都能解码出明文。真正保护 Secret 要靠 RBAC 权限、etcd 加密以及外部密钥管理服务。

为何常见:Secret 从名称到展示形式都让人联想到“秘密”,初学者容易把“编码”误当成“加密”。

误区我写好 PVC,它就会马上分配一块硬盘,然后 Pod 就能使用。

正解PVC 只是“存储申请单”,必须找到匹配的 PV 或由 StorageClass 动态创建存储后才会 Bound。如果集群没有配置 StorageClass,也没有符合容量和访问模式的 PV,PVC 会一直处于 Pending。此时需要检查存储类、云盘配额或 PV 的标签选择器。

为何常见:使用云服务时,StorageClass 通常是默认配置好的,看不到“动态供给”的幕后过程,就会以为 PVC 天生自动完成。

面试题

Q1. 在 Kubernetes 对象模型中,描述“期望状态”的字段通常位于哪个部分?

单选题 · easy

  • A.spec 字段声明期望状态← 正确答案
  • B.status 字段记录实时状态
  • C.kind 字段表示对象类型
  • D.metadata 字段保存元数据

答案:A。spec 是用户声明的期望状态,status 是系统观察到的实际状态。用餐厅比喻,spec 是《理想运营手册》,status 是现实情况,控制器负责让两者对齐。

Q2. Pod 是 K8s 中最小调度单位,以下哪种说法最准确?

单选题 · easy

  • A.一个 Pod 只能运行一个容器
  • B.一个 Pod 内可多容器共享网络← 正确答案
  • C.Pod 只能被 Deployment 管理
  • D.Pod 删除后会自动原地重启

答案:B。Pod 内的多个容器共享网络命名空间、IP 和存储卷,就像餐位上的多个餐具共享一张小桌。Pod 并不只能由 Deployment 管理,删除 Pod 后是否重建取决于控制器。

Q3. Deployment、ReplicaSet 和 Pod 的管控关系是?

单选题 · mid

  • A.Deployment 管理 ReplicaSet,Deployment 直接管 Pod
  • B.Deployment 管理 ReplicaSet,ReplicaSet 管理 Pod← 正确答案
  • C.ReplicaSet 管理 Deployment,Deployment 管理 Pod
  • D.Pod 直接管理 ReplicaSet 和 Deployment

答案:B。正确控制链是 Deployment → ReplicaSet → Pod。Deployment 负责版本发布,ReplicaSet 负责副本数量,Pod 是被管理的工作单元。这就像餐厅老板管排班表,排班表管传菜员。

Q4. 某 Service 的 selector 是 app=web,但后端 Pod 标签写成 app=frontend,结果可能是?

单选题 · mid

  • A.Service 会自动改写 Pod 标签
  • B.Service 的 Endpoints 会变为空← 正确答案
  • C.Service 会把流量转发到全部 Pod
  • D.Service 会立即删除所有后端 Pod

答案:B。Service 通过标签选择器筛选 Pod,标签不匹配时,Service 对应的 Endpoints 为空,流量无法转发。它不会自动改标签,也不会删除 Pod,只会“找不到后端”。

Q5. 关于 Secret 的说法,正确的是?

单选题 · mid

  • A.Secret 在存储前会做加密
  • B.Secret 只是做了 base64 编码← 正确答案
  • C.Secret 只能通过文件方式挂载
  • D.Secret 不能保存访问令牌

答案:B。Secret 默认用 base64 编码而不是加密,base64 可逆且不安全。Secret 可以通过环境变量或卷挂载,也能保存 Token、密码等敏感数据,但需要配合权限控制。

Q6. ReplicaSet 控制器发现当前有 5 个 Pod,期望副本是 3,它会做什么?

单选题 · hard

  • A.先修改期望值再删除两个 Pod
  • B.删除多余 Pod 直到数量为 3← 正确答案
  • C.只记录事件不执行删除操作
  • D.将多余 Pod 标记为不可调度

答案:B。ReplicaSet 的职责是让当前 Pod 数量对齐期望值。当前数量大于期望时,它会主动删除多余的 Pod;当前数量小于期望时,它会新建 Pod。控制器不会修改用户的期望状态。

Q7. PVC 一直处于 Pending,以下哪个最可能是原因?

单选题 · hard

  • A.没有可绑定的 PV 或无法动态供给← 正确答案
  • B.当前 Pod 的镜像拉取策略出错
  • C.关联 Secret 的 base64 数据错误
  • D.Service 的 selector 标签不匹配

答案:A。PVC 是存储申请单,必须匹配到 PV 或由 StorageClass 动态创建。若没有可用 PV、存储类不存在或配额不足,PVC 会一直 Pending。镜像、Secret、Service 的问题不会直接导致 PVC Pending。

Q8. 以下哪些对象属于工作负载类 API?

多选题 · easy

  • A.Deployment 是工作负载对象← 正确答案
  • B.ConfigMap 是工作负载对象
  • C.ReplicaSet 是工作负载对象← 正确答案
  • D.Pod 也是工作负载对象← 正确答案

答案:ACD。工作负载类对象包括 Deployment、ReplicaSet、Pod、StatefulSet、DaemonSet、Job、CronJob 等。ConfigMap 属于配置类对象,用来保存配置数据,不是工作负载。

Q9. 关于 Namespace 的作用,下列说法正确的有?

多选题 · mid

  • A.可以隔离不同团队的资源对象← 正确答案
  • B.可以限制命名空间的资源配额← 正确答案
  • C.可以直接加密 Pod 之间的流量
  • D.为对象提供独立命名的作用域← 正确答案

答案:ABD。Namespace 提供对象隔离和命名作用域,ResourceQuota 可以限制配额。它本身不负责流量加密,流量加密需要 Service Mesh 或 mTLS 等方案。

Q10. 在控制器对账循环中,哪些情况会触发“新建 Pod”?

多选题 · extreme

  • A.存活 Pod 数小于期望副本数← 正确答案
  • B.存活 Pod 数大于期望副本数
  • C.Deployment 镜像版本发生变化← 正确答案
  • D.Service 的 selector 发生变化

答案:AC。当存活 Pod 数小于期望副本数时,控制器需要补建 Pod;Deployment 镜像版本变化时,滚动更新会创建新版本的 Pod。存活 Pod 多时应该删除 Pod,Service selector 变化不会直接触发 Pod 创建。