- kubernetes学习系列快捷链接
本文主要对etcd在kubernetes中的应用进行介绍,包括二者的关系、kubernetes对象存储路径、二者如何交互、生产环境如何部署、最佳实践 以及 一些故障案例分析
1.ETCD 与 Kubernetes 的关系
1.1.ETCD 是 Kubernetes的 默认存储后端

-
默认后端:ETCD 是 Kubernetes 默认的存储后端
-
对象映射 :
-
Kubernetes 中每个对象都有对应的 storage.go 实现与 ETCD 的交互逻辑(增删改查)
-
比如 Pod 的
pkg/registry/core/pod/storage/storage.go
-
CRD:API Server 根据 CRD 定义自动生成对应的 REST endpoint,统一存储接口 复用 apiserver/pkg/registry/generic/registry/store.go 的通用存储实现
go// 伪代码展示存储注册过程 crdStorage := registry.NewREST(scheme, opts) apiGroupInfo.VersionedResourcesStorageMap["v1"] = map[string]rest.Storage{ "customresources": crdStorage, }
-
-
能否替换kubernetes的后端存储
- 重写 storage 层成本极高
- 推荐优化 ETCD 底层存储(如更换 BoltDB)
1.2.ETCD在Kubernetes集群中的位置

- etcd属于 Kubernetes集群的 管控组件,apiserver是唯一与其交互的组件
2.API Server 在 ETCD 中对象存储路径

-
Key 结构:
shell/registry/<对象类型>/<namespace>/<name> # 示例 etcdctl get /registry/pods/default/myapp-pod
-
历史特性:
- 早期版本的 selfLink 字段与 ETCD key 路径一致
- 新版本已弃用该字段
-
特殊目录说明
/registry
:Kubernetes 主数据目录/events
:事件数据(可分离存储)
3.API Server 与 ETCD 的交互

3.1.连接配置
-
apiserver 启动参数-关于etcd的连接配置参数:
shell# API Server 启动参数示例 --etcd-servers=https://etcd1:2379,https://etcd2:2379 --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key
-
API Server 对 ETCD 的健康检查演进:
- 早期:通过端口探活的简单检测,但端口存活不代表etcd一定可用。不准确
- 现在:通过调用 ETCD 健康检查 API。准确
3.2.API Server 对 多 ETCD 实例支持
3.2.1.什么是 多ETCD的支持?
- 如果其他组件也想用ETCD,怎么办?
- 可以自己再启动一个,不要使用管控端的etcd,只要保证端口不冲突即可
- 防止有问题影响到kubernetes集群的稳定性
- 如果Kubernetes中有些数据,数据量大,频繁写,怎么办
- 可以使用 API Server 的多实例分流机制
- 可以使用 API Server 的多实例分流机制
3.2.2.什么是多实例分流?
- 多实例分流概念
- 在多实例分流模式下,Kubernetes 可以将不同类型的对象存储到不同的 ETCD 实例中。
- 通过这种分离,可以减少主 ETCD 集群的压力,提高整体性能和稳定性。
- 为什么需要多实例分流?
- 性能优化:高频变更对象(如 Events)会占用大量资源,影响主 ETCD 性能。
- 故障隔离:将非核心数据(如审计日志)分离到独立 ETCD,避免影响核心业务。
- 扩展性:支持大规模集群(如 10万+ Pods)的场景。
3.2.3.如何配置多实例分流?
-
在 API Server 的启动参数中,通过
--etcd-servers-overrides
指定特定对象的存储位置。 -
示例配置:
shell# 主 ETCD 集群 --etcd-servers=https://etcd-main:2379 # 将 events 对象存储到独立 ETCD 集群 --etcd-servers-overrides=events#https://etcd-events:2379
3.2.4.支持分流的对象类型

3.2.5.分流后的架构
text
┌───────────┐ ┌──────────────┐
│ API Server├──────►│ 主 ETCD 集群 │
└───────────┘ └──────────────┘
│
│ 分流
▼
┌──────────────┐
│ 独立 ETCD 集群│
└──────────────┘
3.2.6.实际应用场景

- 大规模集群:
- 分离 Events 和 CRD 数据
- 减轻主 ETCD 压力
- 审计日志:
- 将审计日志存储到独立 ETCD
- 避免日志写入影响核心业务
- 多租户环境:
- 不同租户使用不同 ETCD 集群
- 实现资源隔离
3.2.7.注意事项
- 数据一致性:分流后需确保跨集群数据一致性
- 运维复杂度:增加独立 ETCD 集群的运维成本
- 监控报警:需单独监控每个 ETCD 集群的健康状态
3.3.API Server无法实现对象的批处理
- kubernetes的资源锁resourceVersion,是对象级别的,因此做不到很多对象的批处理
- 如果自己编写Operator,注意不能在短时间内 进行大量写操作,会影响etcd响应速度
3.4.API Server 与 ETCD 交互原理

3.4.1.交互过程
gRPC over HTTP/2 复用TCP连接 Stream流式处理 API Server ETCD Cluster 客户端请求 资源对象
- 通信协议特性:
- 使用 gRPC 协议(基于 HTTP/2)
- 报文格式为 Protocol Buffers
- HTTP/2特性:连接复用
- 同一个Group下的所有资源,在API Server 与 ETCD 的通信中,都会复用同一个 TCP连接,即 TCP连接复用 特性
3.4.2.连接复用风险场景
shell
# 问题复现条件
集群规模:5000 Nodes
Pod数量:1万+
List操作频率:5000次/分钟(带 --no-cache 参数)
数据量:单次List约100MB
- Http2 连接复用特性 导致的故障链
- 同一个Group下的所有资源,在API Server 与 ETCD 的通信中,都会复用同一个 TCP连接
- 如果当前有Pod资源大量发起请求(比如DemonSet Pod 高频 List 操作占用连接通道),可能就会造成网络拥堵
- Node资源的请求就发不过去了,节点心跳超时被标记为 NotReady
- Eviction Controller 驱逐所有节点 Pod
- 集群服务大面积中断
3.5.什么时候需要到ETCD中查数据?
- 当我们怀疑apiserver的数据有问题,或者怀疑和etcd数据不一致时,就可以到etcd中查看数据
3.6.API Server中watch对象
- API Server中也可以watch一个对象,也可以指定resourceVersion来watch
- 不过我们控制器一般不带resourceVersion,默认是信任apiserver的
3.7.API Server支持分页查询

- 分页查询会返回一个token,将token提交到apiserver,就会自动帮我们返回下一页
4.生产环境部署注意事项
4.1.集群规模选择


- 生产上建议部署5个etcd节点
- 1个节点,一旦坏掉,数据就可能丢失了,服务也不可用了
- 3个节点,如果坏了一个,你需要立马人工介入处理,优先级会非常高。不然再坏一个的话raft投票就无法达到大多数了,etcd集群就变成只读集群了
- 5个节点,如果坏了一个,没关系,优先级还没有那么高,因为再坏一个raft协议的投票也能正常进行
- 一般来说,ETCD的节点数量要在规划阶段确定好,尽量避免后期扩冲节点数量
- 加节点一定是2个2个的加,因为要保证总节点是奇数个
- 而且扩充节点还需要重新生成证书,很麻烦
- 补充
- 节点数越多,就会越慢,因为协商的节点数变多了
4.2.存储优化实践
4.2.1.存储方案对比

- 不能直接全部使用remote storage,写的速度会比较慢,大量请求时可能造成请求积压,影响稳定性
- 也不能一部分节点用local ssd,一部分用远程,这样的话,远程存储的节点数据永远跟不上,leader要一直向其同步数据
4.2.2.存储配置最佳实践

bash
# 推荐配置参数
--quota-backend-bytes=8589934592 # 8GB存储配额
--auto-compaction-retention=72h # 72小时自动压缩
--snapshot-count=10000 # 每10000条日志做快照(修正:原文误作1000)
- 关键优化点:
- 使用 本地NVMe SSD(专有磁盘,不要其他进程使用,避免IO竞争)
- 通过 ionice 提升ETCD进程IO优先级
- 监控 etcd_debugging_mvcc_db_total_size_in_bytes 指标,如果发现etcd的存储快满了,就及时的压缩或整理碎片
- 补充:
- etcd节点的存储默认2GB,不过生产上一般拉满:8GB
4.3.备份与恢复策略
4.3.1.备份方案设计
每小时 流式采集 定时快照 Snapshot保存 实时日志 WAL记录 混合恢复方案
4.3.2.备份命令示例
bash
# 创建快照
ETCDCTL_API=3 etcdctl --endpoints=$ENDPOINTS snapshot save snapshot.db
# 恢复流程
etcdctl snapshot restore snapshot.db \
--data-dir=/var/lib/etcd-restore \
--initial-cluster-token=etcd-cluster-1
4.3.3.备份策略参数

4.4.证书管理与监控
- 证书管理:使用自动轮换工具(如 cert-manager)
- 监控指标:重点关注 etcd_server_leader_changes(Leader 切换次数)
4.5.ETCD 数据操作与恢复
4.5.1.危险操作示例
bash
# 删除所有 Pod 数据(慎用!)
etcdctl del /registry/pods --prefix
4.5.2.灾难恢复流程
-
停止所有 API Server
-
恢复快照:
bashetcdctl snapshot restore /backup/etcd.db
-
重启 ETCD 集群
-
验证数据一致性
4.6.生产环境调优

4.6.1.关键性能参数
bash
# Raft协议参数调优(跨地域部署示例)
--heartbeat-interval=300ms # 心跳间隔(默认100ms)
--election-timeout=3000ms # 选举超时(默认1000ms)
4.6.2.网络优化措施

- 使用 tc 命令优先保障 ETCD 流量
bash
tc qdisc add dev eth0 root handle 1: prio bands 3
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dport 2379 0xffff flowid 1:1
- 跨地域部署保持 RTT < 50ms
- 禁用 swap 确保内存稳定性
4.7.安全增强方案

4.7.1.数据加密层级
应用层 KMS加密Secret 传输层 mTLS双向认证 存储层 LUKS磁盘加密
4.7.2.审计日志配置
yaml
# 审计策略示例
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
resources:
- group: ""
resources: ["secrets"]
5.Kubernetes生产集群中如何搭建ETCD集群
5.1.堆叠式etcd集群的高可用拓扑

5.1.1.定义
- 在堆叠式架构中,etcd 集群 与 Kubernetes 控制平面组件部署在同一组节点上。
- apiserver 到 etcd 的调用,变成本地调用,速度和稳定性很好
5.1.2.特点
- 每个节点同时运行 etcd 和 Kubernetes 控制平面组件。
- 通常用于小型或中等规模的集群。
- 部署简单,资源利用率高。
5.1.3.优点
- 部署和维护相对简单。
- 节省硬件资源,适合资源有限的场景。
5.1.4.缺点
- 耦合性较高,etcd 和 Kubernetes 控制平面组件共享资源,可能相互影响。
- 扩展性较差,随着集群规模增大,性能可能成为瓶颈。
5.1.5.适用场景
- 小型或测试环境。
- 资源有限的场景。
5.2.外部ETCD集群的高可用拓扑-非堆叠式(External)

5.2.1.定义
在非堆叠式架构中,etcd 集群 与 Kubernetes 控制平面组件分别部署在不同的节点上。
5.2.2.特点
- etcd 集群独立运行,不与 Kubernetes 控制平面组件共享节点。
- 通常用于大规模生产环境。
5.2.3.优点
- 解耦 etcd 和 Kubernetes 控制平面组件,避免资源竞争。
- 扩展性好,可以独立扩展 etcd 集群或 Kubernetes 控制平面。
- 更高的可靠性和性能。
5.2.4.缺点
- 需要更多的硬件资源。
- 部署和维护复杂度较高。
5.2.5.适用场景
- 大规模生产环境。
- 对高可用性和性能要求较高的场景。
5.3.对比总结
特性 | 堆叠式(Stacked) | 非堆叠式(External) |
---|---|---|
部署方式 | etcd 和控制平面组件部署在同一节点 | etcd 和控制平面组件分别部署在不同节点 |
资源占用 | 较少 | 较多 |
耦合性 | 高 | 低 |
扩展性 | 较差 | 较好 |
复杂度 | 简单 | 复杂 |
适用场景 | 小型集群、测试环境 | 大规模生产环境 |
- 选择建议
- 如果是 小型集群 或 测试环境 ,可以选择 堆叠式,以节省资源并简化部署。
- 如果是 大规模生产环境 ,建议选择 非堆叠式,以提高可靠性和性能。
- 不过,如果你的资源并不紧缺,还是更推荐 堆叠式
6.经典故障案例分析

6.1.大规模 List 操作雪崩
-
场景复现:
-
5000 节点集群
-
每个节点上的 DaemonSet 每分钟执行:
bashkubectl get pods --all-namespaces --watch
-
-
后果:
- ETCD 连接数暴增
- 节点心跳更新阻塞
- 集群误判节点离线
-
解决方案:
- 优化 List 操作使用缓存
- 分离高频访问对象到独立 ETCD
6.2.证书过期故障
- 典型现象:
- API Server 日志报错 "x509: certificate has expired"
- 集群突然不可写
- 处理步骤:
- 紧急更新 ETCD 证书
- 滚动重启 API Server
6.3.ETCD分裂
- 5个节点,4个local storage,1个remote storage
- 导致这个节点数据一直跟不上
6.4.少数ETCD 出现 成员DOWN

6.5.Master节点出现网络分区
