跳到主要内容
约 9 分钟3 张卡

Kubernetes 架构

Kubernetes 是容器编排系统:用户声明“期望的状态”(运行几个副本、用什么镜像、需要多少资源),系统中的各个控制器持续比较实际状态和期望状态,并采取动作消除差异。理解这一点,就能解释各个组件为什么这样分工。本文讲控制平面和节点上的组件、一个 Pod 从提交到运行的完整链路、调度器的工作方式,以及 etcd 的作用。

1. 面试核心​

先记住这几条,再读正文
  • 控制平面包括 kube-apiserver(唯一的访问入口)、etcd(保存全部集群状态)、kube-scheduler(为 Pod 选择节点)、kube-controller-manager(运行各种控制器);每个节点上运行 kubelet(管理本节点的 Pod)、kube-proxy(实现 Service 转发)和容器运行时。卡 · 组件
  • 组件之间不直接调用,都通过 apiserver 读写对象,并用 watch 机制监听变化。只有 apiserver 直接访问 etcd。
  • 创建 Deployment 的链路:apiserver 校验并写入 etcd → Deployment 控制器创建 ReplicaSet → ReplicaSet 控制器创建 Pod → 调度器选择节点并绑定 → 该节点的 kubelet 调用运行时创建容器 → 就绪后加入 Service 的后端。卡 · 一个 Pod 的创建链路
  • 调度分两步:过滤掉不满足条件的节点(资源请求、节点选择器、污点、亲和性),再给剩余节点打分,选择分数最高的。调度依据的是 requests,而不是实际用量。
  • etcd 是基于 Raft 的强一致键值存储,写入要多数节点确认;集群一般部署 3 或 5 个节点,需要定期备份快照。etcd 不可用时已运行的 Pod 不受影响,但无法创建、修改和调度。卡 · etcd

2. 组件​

位置组件职责
控制平面kube-apiserver提供 REST API,负责认证、授权、准入控制和对象校验,是唯一读写 etcd 的组件;默认安全端口 6443
控制平面etcd保存集群的全部对象和状态
控制平面kube-scheduler为未分配节点的 Pod 选择节点
控制平面kube-controller-manager运行 Deployment、ReplicaSet、Node、Job、EndpointSlice 等控制器,每个控制器负责把一类对象调整到期望状态
控制平面cloud-controller-manager对接云厂商:创建负载均衡器、管理云主机节点
节点kubelet根据分配给本节点的 Pod 创建和监控容器,执行探针,上报状态
节点kube-proxy根据 Service 和 EndpointSlice 维护 iptables 或 IPVS 规则
节点容器运行时如 containerd,kubelet 通过 CRI 接口调用它拉取镜像、运行容器
插件CNI 插件、CoreDNS、Ingress 或 Gateway 控制器、metrics-server分别负责 Pod 网络、集群内域名解析、外部七层流量入口和资源指标

控制循环:每个控制器 watch 自己关心的对象,发现实际状态与期望不一致就采取动作。例如 ReplicaSet 期望 3 个副本,某个 Pod 被删除后,控制器发现只剩 2 个,就再创建一个。这种设计让系统在部分失败后能自动恢复,也让各组件可以独立重启。

静态 Pod:kubelet 直接读取节点上某个目录(kubeadm 默认 /etc/kubernetes/manifests)中的清单启动的 Pod,不经过 apiserver 调度。kubeadm 部署的集群中,apiserver、etcd、scheduler、controller-manager 本身就是以静态 Pod 运行的,这解决了“控制平面还没启动时由谁来启动它”的问题。

3. 一个 Pod 的创建链路​

以 kubectl apply -f deployment.yaml 为例:

  1. kubectl 把清单发给 apiserver。
  2. apiserver 认证用户身份,检查 RBAC 授权,执行准入控制(修改型准入可以注入默认值或 sidecar,校验型准入可以拒绝不合规的对象),校验通过后写入 etcd。
  3. Deployment 控制器 watch 到新的 Deployment,创建对应的 ReplicaSet。
  4. ReplicaSet 控制器 发现 Pod 数量不足,创建 Pod 对象,此时 Pod 的 nodeName 为空,处于 Pending 状态。
  5. 调度器 watch 到未调度的 Pod,经过过滤和打分选出节点,把绑定结果写回 apiserver。
  6. kubelet watch 到分配给本节点的 Pod:通过 CRI 让运行时创建 Pod 沙箱(持有网络等 Namespace 的 pause 容器),调用 CNI 插件分配 IP,挂载卷,拉取镜像,依次运行 init 容器,再启动业务容器,执行启动、存活、就绪探针,并把状态上报给 apiserver。
  7. EndpointSlice 控制器 在 Pod 就绪后把它的 IP 加入对应 Service 的后端;各节点的 kube-proxy 更新转发规则,流量开始进入。

4. 调度​

阶段做什么例子
过滤排除不能运行该 Pod 的节点剩余可分配资源小于 requests;不满足 nodeSelector 或必需的节点亲和性;有 Pod 不能容忍的污点;端口冲突;卷所在的可用区不匹配
打分对剩余节点评分资源分配均衡、首选的亲和性、镜像已在本地、拓扑分布
绑定把 Pod 分配给得分最高的节点写入 nodeName

没有节点通过过滤时,Pod 保持 Pending,事件中会写明原因,例如 0/5 nodes are available: 3 Insufficient cpu, 2 node(s) had untolerated taint。

Pod 分布不均的常见原因是调度只看 requests:requests 设置偏小的 Pod 实际占用很高,调度器却认为节点仍有余量;另外调度只在创建时发生,节点扩容后已有 Pod 不会自动迁移。可以用拓扑分布约束(topologySpreadConstraints)和 Pod 反亲和让副本分散,用 descheduler 定期重新平衡。

5. etcd​

etcd 保存集群中的全部对象:节点、Pod、Service、ConfigMap、Secret 等。它的特点决定了集群的行为:

  • 强一致:基于 Raft 协议,写请求由 Leader 接收,复制到多数节点后才提交,读请求默认也保证读到最新的已提交数据。3 个节点可以容忍 1 个故障,5 个节点可以容忍 2 个;节点数取奇数,因为偶数不会增加容错能力。
  • watch:客户端可以监听键的变化,apiserver 依靠它向各组件推送对象变化。
  • 性能敏感:每次写入都要落盘,磁盘延迟高会导致 Leader 频繁切换、apiserver 变慢,所以 etcd 应使用低延迟的 SSD 并与高 I/O 的负载隔离。

运维要点:定期用 etcdctl snapshot save 备份,并演练恢复;Secret 默认以 base64 编码存储,需要开启静态加密;etcd 故障时已运行的容器继续工作,但所有变更都无法进行。排查时先看 etcd 的成员健康状态、Leader 是否频繁变化和磁盘延迟,不要直接删除数据目录重建,那会丢失全部集群状态。

6 · 面试题卡片​

6.1 Kubernetes 的控制平面和节点上分别有哪些组件?各自的作用是什么?​

出现公司:嘉银科技、DaoCloud、波克城市、虾皮、矩阵起源、字节跳动、米哈游、哔哩哔哩、蘑菇车联

考察重点

  • 控制平面与节点组件的职责。
  • 组件通过 apiserver 和 watch 协作的控制循环模式。

相关内容:组件。

参考回答

控制平面有四个核心组件。kube-apiserver 是唯一的入口,负责认证、授权、准入控制和对象校验,也是唯一直接读写 etcd 的组件。etcd 保存集群的全部状态。kube-scheduler 为还没有分配节点的 Pod 选择节点。kube-controller-manager 运行各种控制器,例如 Deployment 控制器管理 ReplicaSet、ReplicaSet 控制器维持副本数、Node 控制器处理失联节点、EndpointSlice 控制器维护 Service 后端。在云上还有 cloud-controller-manager 对接云负载均衡和云主机。

每个节点上有 kubelet,负责按分配给本节点的 Pod 创建容器、执行探针、上报状态;kube-proxy 根据 Service 维护 iptables 或 IPVS 转发规则;容器运行时(如 containerd)通过 CRI 被 kubelet 调用。此外还需要 CNI 网络插件、CoreDNS 和流量入口控制器等插件。

这些组件不直接互相调用,而是通过 apiserver 读写对象并 watch 变化,各控制器持续把实际状态调整为期望状态,所以某个组件重启后能自动恢复工作。

6.2 从 kubectl apply 一个 Deployment 到 Pod 运行起来,中间经历了哪些步骤?调度器怎样选择节点?​

出现公司:DaoCloud、字节跳动、美团、地平线、虾皮

考察重点

  • apiserver、控制器、调度器、kubelet、CNI 在链路中的先后顺序。
  • 调度的过滤与打分;调度依据 requests;分布不均的原因和处理。

相关内容:一个 Pod 的创建链路、调度。

参考回答

kubectl 把清单发给 apiserver,apiserver 完成认证、授权和准入控制后写入 etcd。Deployment 控制器 watch 到新对象,创建 ReplicaSet;ReplicaSet 控制器发现副本不足,创建 Pod 对象,这时 Pod 还没有节点,处于 Pending。调度器 watch 到未调度的 Pod,选出节点并写回绑定结果。目标节点上的 kubelet watch 到这个 Pod,通过 CRI 让 containerd 创建 Pod 沙箱,调用 CNI 插件分配 IP,挂载卷、拉取镜像,先运行 init 容器再启动业务容器,然后执行探针并上报状态。Pod 就绪后,EndpointSlice 控制器把它加入 Service 的后端,kube-proxy 更新规则,开始接收流量。

调度器先过滤:排除剩余可分配资源小于 Pod requests 的节点、不满足节点选择器或必需亲和性的节点、带有 Pod 不能容忍的污点的节点。再对剩余节点打分,考虑资源均衡、首选亲和性、拓扑分布等,选择最高分的节点。因为调度只看 requests 而不看实际用量,并且只在创建时进行,所以 requests 设置不准或节点扩容后会出现分布不均,可以用拓扑分布约束、反亲和和 descheduler 处理。

6.3 etcd 在 Kubernetes 中起什么作用?它怎样保证多节点数据一致?etcd 出问题会有什么影响?​

出现公司:矩阵起源、字节跳动、滴滴、影石、DaoCloud、共济科技

考察重点

  • etcd 保存集群状态、提供 watch。
  • Raft 的多数派写入;奇数节点;故障影响与备份恢复;静态 Pod。

相关内容:etcd、Raft 选举与日志复制。

参考回答

etcd 是 Kubernetes 唯一的状态存储,节点、Pod、Service、ConfigMap、Secret 等对象都保存在里面;apiserver 是唯一访问它的组件,并利用 etcd 的 watch 能力把对象变化推送给控制器、调度器和 kubelet。

一致性由 Raft 保证:集群选出一个 Leader,写请求由 Leader 追加到日志并复制给其他成员,多数成员持久化后才提交并返回;Leader 故障时,拥有最新已提交日志的成员才能当选新 Leader。所以 3 个节点能容忍 1 个故障,5 个能容忍 2 个,节点数取奇数。每次写入都要刷盘,磁盘慢会导致 Leader 频繁切换和 apiserver 变慢,etcd 应使用低延迟磁盘。

etcd 不可用时,已运行的容器不受影响,但所有创建、更新、调度和扩缩容都无法进行,控制平面组件也会报错。运维上要定期做快照备份并演练恢复,开启 Secret 的静态加密,出问题时先检查成员健康、Leader 变化和磁盘延迟,优先从快照恢复,而不是删除数据目录重建。kubeadm 部署的集群中 etcd 以静态 Pod 运行,由 kubelet 直接读取节点上的清单启动。

7. 参考资料​