主题
面试题深度详解:架构与原理(10 题)
每题包含:答题思路、技术原理深度剖析、三级参考答案(B/A/S)、关联知识点、面试官评判标准。
Q1: K8s 控制平面各组件的职责和交互流程
答题思路
回答层次:
第一层(B):列举组件名称和基本职责
第二层(A):描述组件间的交互流程和数据流
第三层(S):深入到 apiserver 请求链、Informer 机制、Leader Election 等内部原理技术原理深度剖析
控制平面四大组件:
┌─────────────────────────────────────────────────────────┐
│ 控制平面(Control Plane) │
│ │
│ ┌──────────────┐ ┌─────────┐ ┌──────────────────┐ │
│ │ kube-apiserver│◄──►│ etcd │ │ kube-scheduler │ │
│ │ (唯一API入口) │ │(状态存储)│ │ (调度决策) │ │
│ └──────┬───────┘ └─────────┘ └────────┬─────────┘ │
│ │ │ │
│ │ ┌──────────────────────┐ │ │
│ └────────►│ kube-controller-manager│◄┘ │
│ │ (调谐循环) │ │
│ └──────────────────────┘ │
└─────────────────────────────────────────────────────────┘
│
│ Watch
▼
┌─────────────────────────────────────────────────────────┐
│ 节点(Node) │
│ ┌──────────┐ ┌────────────┐ ┌───────────────────┐ │
│ │ kubelet │ │ kube-proxy │ │ 容器运行时 │ │
│ │(节点代理) │ │(网络代理) │ │(containerd/CRI-O) │ │
│ └──────────┘ └────────────┘ └───────────────────┘ │
└─────────────────────────────────────────────────────────┘关键交互流程:
1. 所有组件只通过 apiserver 通信(不直接互相通信)
2. apiserver 是唯一可以读写 etcd 的组件
3. Controller/Scheduler 通过 Informer Watch apiserver 的变更
4. kubelet 通过 Watch 获取分配到本节点的 Pod
5. kube-proxy Watch Service/Endpoints 变更,更新 iptables/IPVS 规则三级参考答案
B 级(基础):
控制平面包括 kube-apiserver 作为 REST API 入口,etcd 作为分布式键值存储保存集群状态,kube-scheduler 负责 Pod 调度,kube-controller-manager 运行各种控制器。节点上 kubelet 管理 Pod 生命周期,kube-proxy 处理网络转发。
A 级(深入):
补充:所有组件通过 apiserver 通信,apiserver 是唯一读写 etcd 的组件。Controller 通过 Informer 机制 Watch apiserver 变更,执行 Reconciliation Loop。apiserver 请求经过 认证→授权→准入 三层处理。kubelet 通过 CRI 调用容器运行时,kube-proxy 通过 Watch 更新 iptables/IPVS 规则。
S 级(卓越):
进一步深入:apiserver 采用 Level-triggered 设计而非 Edge-triggered,天然具备自愈能力。Informer 由 List-Watch + DeltaFIFO + Indexer 组成,资源版本(ResourceVersion)实现断点续 Watch。etcd 基于 Raft 协议,3 节点容忍 1 故障。scheduler/controller-manager 多副本时通过 Leader Election 保证只有一个活跃实例。apiserver 支持 API 聚合层扩展自定义 API Server。
面试官评判标准
| 等级 | 标志 |
|---|---|
| B | 说出 4+2 个组件名称和基本职责 |
| A | 能描述组件间交互流程(Watch、Informer) |
| S | 深入 Level-triggered、Leader Election、API 聚合层 |
Q2: 声明式 API 的工作原理,Level-triggered vs Edge-triggered
答题思路
核心是解释"声明式"与"命令式"的根本区别,然后用 Level/Edge-triggered 解释 K8s 为什么选择声明式。技术原理深度剖析
Level-triggered vs Edge-triggered(核心概念):
Edge-triggered(边缘触发):
- 基于事件通知驱动
- 收到"创建 Pod"事件 → 执行创建动作
- 如果错过事件通知 → 丢失状态,无法自愈
Level-triggered(水平触发):
- 基于当前状态差异驱动
- 只看 "期望状态 vs 实际状态" 的差异
- 即使错过事件,重启后重新比对仍能自愈
举例:
Deployment 期望 3 个 Pod,当前只有 1 个
→ 不关心"为什么只有 1 个"
→ 只看到差异:期望 3 - 实际 1 = 需要创建 2 个三级参考答案
B 级:
声明式 API 是用户描述期望状态,控制器持续调谐使实际状态趋近期望状态。
A 级:
K8s 使用 Level-triggered 设计:控制器只看当前状态和期望状态的差异,不依赖事件通知序列。即使 kubelet 重启错过了事件通知,重启后重新比对仍能自愈。Reconciliation Loop 是其核心模式。
S 级:
kubectl apply 使用三方合并(Last Applied + Current + Desired),annotation 中存储 last-applied-configuration。server-side apply(SSA)通过 managedFields 解决了客户端合并冲突问题。Level-triggered 借鉴了 Google Borg 的经验,天然具备最终一致性。
Q3: Informer 机制的工作原理(List-Watch、DeltaFIFO、Indexer)
答题思路
这是 K8s 内部机制的核心问题。回答要覆盖 Informer 的四大组件及其协作流程。技术原理深度剖析
┌─────────────────────┐
│ kube-apiserver │
└──────────┬──────────┘
│
┌──────────▼──────────┐
│ Reflector │
│ (List + Watch) │
└──────────┬──────────┘
│
┌──────────▼──────────┐
│ DeltaFIFO │
│ (变更事件队列) │
└──────────┬──────────┘
│ │
┌─────▼──┐ ┌───▼────────┐
│ Pop() │ │ Indexer │
│ 事件分发│ │ (本地缓存) │
└───┬────┘ └───┬────────┘
│ │
┌───▼────────┐ │
│ EventHandlers│
│ Add/Update/ │
│ DeleteFunc │
└────────────┘四大组件详解:
| 组件 | 职责 | 关键设计 |
|---|---|---|
| Reflector | List 全量 + Watch 增量 | ResourceVersion 断点续 Watch |
| DeltaFIFO | 变更事件队列 | 记录变更类型(Delta),保证有序 |
| Indexer | 本地缓存 + 索引 | 基于线程安全的 store,自定义索引函数 |
| EventHandlers | 事件回调 | Add/Update/Delete 三个回调函数 |
ResourceVersion 的作用:
1. 每个资源变更时 ResourceVersion 递增
2. Watch 请求携带上次的 ResourceVersion
3. apiserver 从该版本开始推送变更
4. 如果版本已过期(etcd compaction),返回 410 Gone
5. Reflector 收到 410 后重新全量 List三级参考答案
B 级:
Informer 是 K8s 内部获取资源变更的机制,通过 List-Watch 从 apiserver 获取数据,缓存在本地,各组件通过 Event Handler 响应变更。
A 级:
Informer 由 Reflector(List+Watch)、DeltaFIFO(变更队列)、Indexer(本地缓存+索引)、EventHandlers(回调函数)组成。Reflector 通过 ResourceVersion 实现断点续 Watch,Indexer 提供 O(1) 的本地查询能力,避免频繁访问 etcd。
S 级:
DeltaFIFO 的四种 Delta 类型(Added/Updated/Deleted/Sync),Sync 类型在全量 List 后用于同步已有缓存对象。SharedInformer 多个 Controller 共享同一个 Watch 连接,减少 apiserver 压力。ResourceVersion 过期返回 410 Gone 时触发 relist。大规模集群需调优
--watch-cache-sizes参数。
Q4: etcd 的 Raft 共识算法原理,如何保证一致性
答题思路
从分布式系统 CAP 理论出发,解释 Raft 如何在 CP 之间取舍,再讲具体机制。技术原理深度剖析
Raft 三大机制:
1. Leader 选举(Leader Election)
- 初始所有节点为 Follower
- Follower 超时未收到心跳 → 变为 Candidate → 发起选举
- 获得多数票的 Candidate 成为 Leader
- Term(任期号)递增,保证唯一性
2. 日志复制(Log Replication)
- 所有写请求只由 Leader 处理
- Leader 将写操作追加到本地日志
- 并行复制日志到所有 Follower
- 多数节点确认后 → 提交(Commit)→ 应用到状态机
3. 安全性(Safety)
- 选举限制:只有日志最新的 Candidate 才能当选
- 日志匹配:相同 Term + Index 的日志内容一定相同
- 状态机安全:已提交的日志不会被覆盖为什么 etcd 节点数必须是奇数?
容错能力 = (N-1)/2
节点数 容错 Quorum 写入延迟
1 0 1 最低(单点故障风险)
3 1 2 低(生产推荐最小)
5 2 3 中(大规模推荐)
7 3 4 高(极少使用)
偶数节点(如 4)容错能力 = 1,和 3 节点相同
但写入需要 3 个节点确认(Quorum = 3),延迟更高
→ 偶数节点是浪费,没有额外收益三级参考答案
B 级:
etcd 使用 Raft 共识算法,通过 Leader 选举和日志复制保证数据一致性。写操作需要多数节点确认(Quorum),所以节点数必须是奇数。
A 级:
Raft 包含三大机制:Leader 选举(超时触发,Term 递增)、日志复制(Leader 写入→复制到 Follower→多数确认→提交)、安全性保证(最新日志才能当选)。3 节点容忍 1 故障,5 节点容忍 2 故障。脑裂时少数派分区不可写,网络恢复后通过 Term 号自动合并。
S 级:
深入 Raft 安全性:选举限制保证只有包含所有已提交日志的 Candidate 才能当选(Election Restriction)。日志匹配原则:如果两个日志在相同 Term 和 Index 处相同,则之前的日志也完全相同。etcd 的 WAL(Write-Ahead Log)和 Snapshot 机制保证持久性。生产调优:NVMe SSD、独立磁盘、
--quota-backend-bytes=8GB、定期 defrag。
Q5: Controller 的 Reconciliation Loop 原理
答题思路
从控制论角度解释"调谐循环"是 K8s 的核心设计模式,再举例说明。三级参考答案
B 级:
Reconciliation Loop 是 K8s 控制器的核心模式,不断比较期望状态和实际状态,执行调谐动作使两者一致。
A 级:
每个控制器独立运行 Reconciliation Loop:Watch 变更 → 获取期望状态 → 获取实际状态 → 计算差异 → 执行调谐。设计原则是幂等性和最终一致性。Deployment Controller 管理 ReplicaSet 数量,ReplicaSet Controller 管理 Pod 数量,形成级联调谐。
S 级:
深入:Controller 使用 workqueue 实现重试和退避(指数退避 + 抖动)。rate limiter 防止雪崩。多个 Controller 之间通过 OwnerReference 形成级联关系(Deployment → ReplicaSet → Pod)。自定义 Controller 使用 controller-runtime / Kubebuilder 框架。Operator 模式本质上是特定领域 Controller + CRD 的组合。
Q6: kubelet 的 PLEG(Pod Lifecycle Event Generator)工作原理
答题思路
PLEG 是 kubelet 感知 Pod 状态变化的核心机制,从"为什么需要 PLEG"入手。三级参考答案
B 级:
PLEG 是 kubelet 的 Pod 生命周期事件生成器,定期检查容器状态变化,生成事件通知 kubelet 处理。
A 级:
PLEG 每秒获取所有 Pod 状态快照,与上次对比生成事件(PodAdded/ContainerStarted/ContainerDied/PodRemoved),推送到 event channel。kubelet syncLoop 消费事件并更新 apiserver。PLEG 卡死通常因为容器运行时响应慢或 CNI 阻塞。
S 级:
PLEG 内部有 GenericPLEG 和 RemotePLEG 两种实现。kubelet 的 syncLoop 是主循环,整合 PLEG 事件、kubelet 配置变更、Pod 更新三种输入源。PLEG relist 超时阈值默认 3 分钟,可通过
--node-status-update-frequency调整。大规模节点建议关注 PLEG relist 延迟指标。
Q7: CRI/CNI/CSI 接口的设计理念和交互流程
答题思路
三个接口是 K8s 插件化的核心设计,从"为什么要解耦"入手。三级参考答案
B 级:
CRI 是容器运行时接口(对接 containerd),CNI 是容器网络接口(对接 Calico 等),CSI 是容器存储接口(对接 Ceph 等)。三者通过标准化 gRPC 接口实现可插拔。
A 级:
三者统一设计理念是将核心功能与实现解耦。CRI 通过 gRPC 与容器运行时通信(RuntimeService + ImageService)。CNI 通过 ADD/DEL/CHECK 命令配置容器网络。CSI 分 Controller Plugin(卷生命周期)和 Node Plugin(节点挂载)。Pod 创建时三者按序协作:CRI 创建 Sandbox → CNI 配网络 → CSI 挂存储 → CRI 启动容器。
S 级:
CRI 从 dockershim 演进到标准化的 gRPC 接口,K8s 1.24 移除 dockershim。CNI 的 IPAM(IP Address Management)独立于网络插件,可由 host-local 或 calico-ipam 等提供。CSI 的 Controller Plugin 通常 Deployment 部署(1 副本 + Leader Election),Node Plugin 用 DaemonSet。Sidecar 容器(provisioner/attacher/registrar/snapshotter)辅助 CSI 驱动与 K8s 交互。
Q8: K8s 如何实现零停机部署?涉及哪些组件的协作
答题思路
这是端到端理解题,需要从 Deployment → Pod → Service → 流量 全链路分析。技术原理深度剖析
零停机部署涉及 5 个层面的协作:
1. Deployment 层面:滚动更新策略
maxUnavailable: 0 → 不同时停掉旧 Pod
maxSurge: 25% → 先创建新 Pod 再停旧的
2. Pod 层面:优雅终止
preStop: sleep 5 → 给 kube-proxy 时间更新端点
terminationGracePeriodSeconds: 60
3. 探针层面:就绪检查
readinessProbe → 新 Pod 就绪后才加入 Service
4. Service 层面:端点更新
kube-proxy Watch Endpoints 变更 → 更新 iptables/IPVS 规则
存在时间窗口:端点移除 → 规则更新 → 期间可能有少量请求到旧 Pod
5. PDB 层面:中断预算
PodDisruptionBudget → 限制同时被驱逐的 Pod 数量时间窗口问题(核心难点):
Pod 终止的时序:
t0: Pod 标记为 Terminating
t1: apiserver 通知 kube-proxy(EndSlice 变更)
t2: kube-proxy 更新 iptables/IPVS 规则 ← 这里有延迟!
t3: kubelet 执行 preStop Hook
t4: 发送 SIGTERM
t5: 等待 grace period
t6: SIGKILL
问题:t1 → t2 之间有延迟,期间新请求仍可能路由到正在终止的 Pod
解决:preStop sleep 5s,确保 t2 完成后再执行 t3三级参考答案
B 级:
通过 Deployment 的 RollingUpdate 策略,设置 maxUnavailable: 0 保证不中断。新 Pod 通过 readinessProbe 就绪后才接收流量,旧 Pod 通过 grace period 优雅退出。
A 级:
零停机需要 5 层协作:Deployment 滚动更新策略(maxUnavailable:0 + maxSurge)、Pod preStop Hook(sleep 给 kube-proxy 更新时间)、ReadinessProbe(新 Pod 就绪才接入流量)、Service 端点更新(kube-proxy Watch 并更新规则)、PDB(限制驱逐数量)。关键难点是 kube-proxy 端点更新存在时间窗口。
S 级:
深入时间窗口问题:Pod 终止时,apiserver 更新 EndpointSlice → kube-proxy Watch 并更新 iptables/IPVS 规则,这个过程有 1-3 秒延迟。preStop sleep 5s 就是为了覆盖这个窗口。另外,Connection draining 需要应用层面配合(如 HTTP keep-alive 超时)。对于 gRPC 服务,需要客户端感知服务端变化(如使用 xDS 协议)。Gateway API 的 BackendTLSPolicy 和 HealthCheckPolicy 提供了更细粒度的健康检查控制。
Q9: K8s 中 Secret 的存储和加密机制
答题思路
从 Secret 的"不安全"现状入手,解释加密方案。三级参考答案
B 级:
Secret 的 data 字段是 base64 编码,不是加密。存储在 etcd 中默认是明文。可以通过 EncryptionConfiguration 配置 apiserver 加密存储 Secret。
A 级:
Secret 安全需要多层保障:1) EncryptionConfiguration 加密 etcd 中的 Secret(支持 AES-CBC、AES-GCM、KMS);2) RBAC 限制 Secret 访问权限;3) NetworkPolicy 限制 API 访问;4) 审计日志监控 Secret 访问。旧 Secret 需要重写才能加密。
S 级:
生产推荐 External Secrets Operator + HashiCorp Vault 方案:Secret 存储在 Vault 中,External Secrets Operator 定期同步到 K8s Secret。Sealed Secrets 适合 GitOps 场景(加密后可安全提交到 Git)。KMS 插件允许使用云厂商 KMS(如 AWS KMS、阿里云 KMS)管理加密密钥。Secret 在 Pod 中以 tmpfs 挂载,不写磁盘。
Q10: K8s 的 API 聚合层(API Aggregation)是什么
答题思路
从 K8s 的扩展性需求入手,解释 API 聚合层如何允许第三方扩展 K8s API。三级参考答案
B 级:
API 聚合层允许第三方注册自定义 API Server,扩展 K8s 的 API。典型例子是 metrics-server,它注册了 metrics.k8s.io API,kubectl top 命令就是通过它获取数据。
A 级:
API 聚合层通过 APIService 资源注册自定义 API Server。kube-apiserver 作为代理,将匹配注册路径的请求转发到自定义 API Server。与 CRD 相比,API 聚合层更灵活(可自定义认证、授权、存储逻辑),但开发复杂度更高。CRD 数据存储在 etcd,API 聚合层可以用任意后端。
S 级:
API 聚合层的请求处理:主 apiserver 先执行认证和授权,然后代理请求。自定义 API Server 需要做 delegated authentication(委托认证)和 delegated authorization(委托授权),复用主 apiserver 的 TokenReview 和 SubjectAccessReview。开发框架推荐 apiserver-builder / kube-aggregator。生产环境需要注意聚合 API 的可用性,如果自定义 API Server 挂了,对应的 API 会返回 503。
下一章:面试题深度详解:网络(10 题)