etcd 在 Kubernetes 中的角色
核心定位:Kubernetes 的 唯一持久化数据存储(一致性数据库)。
职责:
- 保存整个集群的期望状态(desired state),包括节点信息、Pod 清单、Service 定义、ConfigMap、Secrets 等所有 API 对象。
- 提供**强一致性(CP)**保障,保证即使多个 API Server 同时读写,也不会出现状态冲突。
- 支持 Watch 机制:当 etcd 中数据变更时,API Server 能实时推送事件给控制器和客户端。
关键关系:
- API Server 是所有组件的 “中枢”,所有读写状态都通过它。
- Controller Manager / Scheduler 都是 被动 响应 API Server 推送的事件(watch)。
- kubelet 负责 Pod 在 Node 上的实际运行,向 API Server 上报状态。
- CNI/CSI 插件由 kubelet 调用,实现网络和存储的实际配置。
数据存储结构
etcd 是一个 分布式键值数据库,内部使用 BoltDB(B+Tree 存储) 作为底层存储引擎。
Key 结构(逻辑路径):
Kubernetes 在 etcd 中为每种资源维护一个命名空间式路径,例如:
/registry/pods/default/nginx-pod /registry/deployments/default/web-deploy /registry/configmaps/kube-system/coredns
/registry
是 Kubernetes 存放 API 对象的根前缀。路径的最后一段是对象的名字(可能还带命名空间)。
Value 结构:
- 实际是序列化后的 Protocol Buffers(Protobuf) 或 JSON。
- 内含对象的
metadata
、spec
、status
等字段。 - 同时存储 ResourceVersion(单调递增)用于一致性和 Watch。
版本控制:
- etcd 每个 key 有 修改版本(mod_revision),整个数据库有全局递增 revision。
- Kubernetes API Server 用
resourceVersion
与 etcd revision 对应,保证读取的一致性快照。
数据写入流程
以 kubectl apply -f pod.yaml
为例:
客户端提交
kubectl
把 YAML 转成 Kubernetes API 对象,通过 REST 调用 API Server。API Server 流程
- 认证/鉴权:验证请求是否合法。
- 准入控制:MutatingAdmissionWebhook 可能修改对象(加默认值),ValidatingAdmissionWebhook 校验对象合法性。
- 序列化:将对象编码为 Protobuf。
- 存储层调用:通过 Kubernetes 的
storage.Interface
调用 etcd v3 gRPC API。
etcd 写入
- etcd leader 接收
Put
请求。 - Leader 将写请求通过 Raft 共识协议 复制到多数派 Follower 节点。
- 多数节点写入成功(持久化到本地 BoltDB WAL + B+Tree)后,Leader 提交事务并返回成功。
- 此时
mod_revision
增加,触发 Watch 事件。
- etcd leader 接收
事件分发
- API Server Watch 机制检测到新 revision,通知各 Controller、Scheduler、kubelet 等。
- 各组件据此执行调度、创建容器等后续动作。
总结
维度 | 说明 |
---|---|
角色 | k8s 的唯一持久化存储,保存集群所有 API 对象状态 |
存储结构 | Key-Value,Key 为 /registry/... 逻辑路径,Value 为 Protobuf 序列化对象 |
一致性保障 | Raft 共识,强一致性,顺序提交 |
写入流程关键点 | API Server → 序列化 → etcd Leader → Raft 复制 → 多数派确认 → 更新 revision → 触发 Watch |
附件
etcd数据交互
K8s 核心组件调用关系 + etcd 交互点 + Endpoints 数据流
- etcd 只与 API Server 通信
- API Server 如何向 Controller、Scheduler、kubelet、Endpoints Controller 分发事件
- Endpoints / EndpointSlice Controller 如何生成数据并被 kube-proxy/CoreDNS 使用
- Node 上 kubelet 如何调用 CRI、CNI、CSI 执行实际操作