Kubernetes控制平面组件:Kubernetes如何使用etcd

云原生学习路线导航页(持续更新中)

本文主要对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 的多实例分流机制

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

  • 恢复快照:

    bash 复制代码
    etcdctl 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.特点

  • 每个节点同时运行 etcdKubernetes 控制平面组件
  • 通常用于小型或中等规模的集群。
  • 部署简单,资源利用率高。

5.1.3.优点

  • 部署和维护相对简单。
  • 节省硬件资源,适合资源有限的场景。

5.1.4.缺点

  • 耦合性较高,etcdKubernetes 控制平面组件共享资源,可能相互影响。
  • 扩展性较差,随着集群规模增大,性能可能成为瓶颈。

5.1.5.适用场景

  • 小型或测试环境。
  • 资源有限的场景。

5.2.外部ETCD集群的高可用拓扑-非堆叠式(External)

5.2.1.定义

在非堆叠式架构中,etcd 集群Kubernetes 控制平面组件分别部署在不同的节点上。

5.2.2.特点

  • etcd 集群独立运行,不与 Kubernetes 控制平面组件共享节点。
  • 通常用于大规模生产环境。

5.2.3.优点

  • 解耦 etcdKubernetes 控制平面组件,避免资源竞争。
  • 扩展性好,可以独立扩展 etcd 集群或 Kubernetes 控制平面。
  • 更高的可靠性和性能。

5.2.4.缺点

  • 需要更多的硬件资源。
  • 部署和维护复杂度较高。

5.2.5.适用场景

  • 大规模生产环境。
  • 对高可用性和性能要求较高的场景。

5.3.对比总结

特性 堆叠式(Stacked) 非堆叠式(External)
部署方式 etcd 和控制平面组件部署在同一节点 etcd 和控制平面组件分别部署在不同节点
资源占用 较少 较多
耦合性
扩展性 较差 较好
复杂度 简单 复杂
适用场景 小型集群、测试环境 大规模生产环境
  • 选择建议
    • 如果是 小型集群测试环境 ,可以选择 堆叠式,以节省资源并简化部署。
    • 如果是 大规模生产环境 ,建议选择 非堆叠式,以提高可靠性和性能。
    • 不过,如果你的资源并不紧缺,还是更推荐 堆叠式

6.经典故障案例分析

6.1.大规模 List 操作雪崩

  • 场景复现:

    • 5000 节点集群

    • 每个节点上的 DaemonSet 每分钟执行:

      bash 复制代码
      kubectl 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节点出现网络分区

相关推荐
A ?Charis1 小时前
k8s-对接NFS存储
linux·服务器·kubernetes
KTKong3 小时前
kubeadm拉起的k8s集群证书过期的做法集群已奔溃也可以解决
云原生·容器·kubernetes
运维开发王义杰11 小时前
Kubernetes:EKS 中 Istio Ingress Gateway 负载均衡器配置及常见问题解析
kubernetes·gateway·istio
成长的小牛23311 小时前
阿里云k8s服务部署操作一指禅
阿里云·kubernetes·云计算
仇辉攻防11 小时前
【云安全】云原生-Docker(六)Docker API 未授权访问
web安全·网络安全·docker·云原生·容器·kubernetes·安全威胁分析
Anna_Tong18 小时前
Kubernetes & 容器自动伸缩失败:解决方案及阿里云如何帮助
阿里云·云原生·容器·kubernetes·负载均衡·自动伸缩·弹性计算
好好学习之乘风破浪19 小时前
部署k8s 集群1.26.0(containerd方式)
kubernetes
Marcel1111 天前
WSL2使用Kind创建K8S集群时出现IPV6网络创建失败
云原生·kubernetes·kind
格桑阿sir1 天前
Kubernetes控制平面组件:etcd(二)
kubernetes·etcd·raft·mvcc·boltdb·watch机制·treeindex
{⌐■_■}1 天前
【etcd】ubuntu22安装,与redis对比的区别
服务器·数据库·chrome·redis·缓存·golang·etcd