宏观架构与集群之脑 - API Server 和 etcd
宏观架构:数据中心的操作系统
在开始之前,让我们先建立一个高层视角。你可以将 Kubernetes 想象成一个管理整个数据中心的分布式操作系统。在这个操作系统中:
- 控制平面 (Control Plane) 就是它的“内核”,负责管理和决策。
- 工作节点 (Worker Nodes) 就是它的“CPU 和内存”,是真正运行应用程序的地方。
- 我们常用的
kubectl
就是与这个“内核”交互的“命令行 Shell”。
控制平面主要由四个核心组件构成:API Server, etcd, Scheduler, Controller Manager。而我们今天的旅程,就从这个操作系统的“前门”和“大脑”开始。
前门与枢纽:kube-apiserver
kube-apiserver
是整个 Kubernetes 控制平面的唯一入口。任何组件——无论是外部的 kubectl
、CI/CD 系统,还是内部的 Scheduler、Kubelet——想要查询或修改集群的状态,都必须通过 API Server。
它远不止是一个简单的 REST API 网关,它是一个复杂的、承担着守门、转接、通知等多种角色的核心枢纽。让我们跟随一个 kubectl create -f pod.yaml
命令,看看它在 API Server 中经历了怎样的旅程:
1\. 认证 (Authentication) - “你是谁?”
当请求到达时,API Server 的第一道关卡是认证。它需要确认请求者的身份。K8s 支持多种认证方式,如客户端证书、静态 Token、Bearer Token、OIDC 等。我们最常用的 kubectl
,通常就是通过 ~/.kube/config
文件中配置的客户端证书来向 API Server 证明自己身份的。
2\. 授权 (Authorization) - “你被允许做什么?”
身份被确认后,第二道关卡是授权。API Server 会检查这个经过认证的用户,是否有权限执行请求的操作。例如,“user-A
是否有权限在 default
命名空间中创建 Pod
?”
这个决策主要由 RBAC (Role-Based Access Control) 模块来完成。RBAC 通过几种资源来定义权限:
Role
/ClusterRole
: 定义了一组权限(可以对哪些资源执行哪些操作)。RoleBinding
/ClusterRoleBinding
: 将一个“身份”(用户、用户组、ServiceAccount)与一个“角色”绑定起来。
只有当授权模块确认该用户拥有相应权限后,请求才能进入下一关。
3\. 准入控制 (Admission Control) - “你做的事情合规吗?”
这是请求被持久化到 etcd
之前的最后一道、也是非常强大的一道关卡。准入控制器是一系列插件,它们可以检查、甚至修改请求的对象。
准入控制器分为两种:
- 变更型准入控制器 (Mutating Admission Webhooks): 它可以修改请求的对象。一个经典的例子是,Istio 的 Sidecar 注入器就是一个 Mutating Webhook。当你创建一个 Pod 时,它会拦截这个请求,并自动在你的 Pod 定义中加入 Istio-proxy sidecar 容器的配置。
- 验证型准入控制器 (Validating Admission Webhooks): 它只进行检查,如果检查不通过,就拒绝该请求。例如,我们可以配置一个 Validating Webhook 来强制所有 Pod 都必须设置
resources.limits
,或者禁止使用latest
标签的镜像。
只有通过了所有准入控制器的检查,这个请求对象才被认为是“合法”的,准备好被持久化。
大脑与真相之源:etcd
当一个对象(如 Pod 的 YAML 定义)通过了 API Server 的层层关卡后,API Server 会将它序列化并存入 etcd。
etcd 是一个分布式的、高可用的、强一致性的键值存储系统。它是整个 Kubernetes 集群的唯一数据后端和单一事实来源 (Single Source of Truth)。集群中所有资源的状态——无论是我们期望的状态(如 Deployment 的定义),还是观察到的实际状态(如 Pod 的当前 IP),都存储在 etcd 中。
为什么不用 MySQL 或 PostgreSQL? 因为控制平面数据库的首要需求是高可用和数据一致性。一个单点的数据库无法满足分布式系统的要求。如果数据库挂了,整个集群就“失忆”了。etcd 被设计出来的目的,就是为了解决这个问题。
etcd 的魔法:Raft 共识算法 etcd 的高可用和一致性,来源于它所使用的 Raft 共识算法。
- 核心思想: 让一个集群(通常是3、5、7个节点)中的多个服务器,能够像一个统一的整体一样工作,对数据的每一次变更达成“共识”,即使部分服务器出现故障。
- 工作原理 (简化版):
- 领导者选举 (Leader Election): 集群中的节点会自动选举出一个领导者 (Leader)。
- 写操作由领导者处理: 所有的写请求都必须先发给 Leader。
- 日志复制: Leader 会将这个写操作作为一条日志,复制给所有的跟随者 (Followers)。
- 达成共识 (Quorum): Leader 不会立刻应用这个写操作。它会等待,直到超过半数(即“法定人数”或 Quorum) 的节点都成功地将这条日志写入了自己的磁盘。
- 提交并响应: 一旦达到 Quorum,Leader 就会“提交”这条日志,应用这个写操作,并向客户端返回成功。
正是这个“必须超过半数节点确认”的机制,保证了即使有少数节点宕机,整个集群的数据也不会丢失或不一致。一个3节点的 etcd 集群可以容忍1个节点故障,一个5节点的集群可以容忍2个节点故障。
K8s 如何使用 etcd?
K8s 中的每个资源,在 etcd 中都以 key-value
的形式存储,其 key 的路径类似 /registry/pods/default/my-pod
。
更重要的是,API Server 与 etcd 的交互并不仅仅是简单的 CRUD。其他控制平面组件(如 Scheduler)可以通过 API Server 对 etcd 中的资源建立一个长连接的监视 (watch)。当 etcd 中的某个 key 发生变化(增、删、改)时,etcd 会立刻通知 API Server,API Server 再将这个变化事件推送给所有正在监视该资源的客户端。
这种事件驱动的架构,使得 K8s 的各个组件能够高效、实时地响应集群状态的变化,而不是通过低效的轮询。
连接所有点
现在,让我们把今天的旅程串起来:
- 你运行
kubectl apply -f my-pod.yaml
。 - 请求通过认证、授权、准入控制三道关卡,到达
kube-apiserver
的核心。 kube-apiserver
将 Pod 的定义写入etcd
。etcd
集群通过 Raft 协议达成共识,安全地持久化了数据。kube-apiserver
立即通过watch
机制,向所有“订阅”了 Pod 创建事件的客户端发出通知:“嘿,有一个新的 Podmy-pod
被创建了,但它还没有被调度到任何节点上!”
总结与展望
今天,我们深入了 Kubernetes 的心脏地带,剖析了它的“前门”kube-apiserver
和“大脑”etcd
。我们理解了 API Server 不仅是 API 网关,更是一个精密的、分阶段的请求处理器;我们也理解了 etcd 如何通过 Raft 协议,为整个分布式集群提供一个坚如磐石的数据基座。
我们的故事讲到了一个关键的节点:一个 Pod 对象已经被成功地创建并存储,但它还只是一个存在于 etcd 中的“幽灵”,尚未在任何物理节点上“化为肉身”。
接下来会发生什么?谁会接收到这个“新 Pod 诞生”的通知?谁来为它挑选一个最合适的家(工作节点)?又是谁在背后默默地确保我们 Deployment 定义的副本数永远得到满足?
在下一篇中,我们将认识控制平面中另外两位智慧的决策者:Scheduler(调度器) 和 Controller Manager(控制器管理器)。敬请期待!