3. etcd 集群部署:架构设计、Operator 部署与健康验证
在云原生日志平台中,etcd 集群承担着 Prometheus 远端写入数据的持久化存储与水位复核的关键职责。本章聚焦于 etcd 集群的架构设计原则、基于 Kubernetes Operator 的自动化部署流程,以及集群健康状态的验证方法。一个高可用、可扩展的 etcd 集群是保障日志平台数据一致性与查询性能的基石。
3.1 etcd 集群架构设计
etcd 使用 Raft 共识算法保证数据强一致性。集群节点数量直接影响容错能力和写入性能。生产环境推荐使用奇数节点(3、5 或 7),以在容错与性能间取得平衡。
| 集群规模 | 节点数 | 最大容忍故障节点 | 适用场景 |
|---|---|---|---|
| 最小高可用 | 3 | 1 | 开发/测试环境,小规模日志平台 |
| 标准生产 | 5 | 2 | 生产环境,中等写入负载 |
| 大规模集群 | 7 | 3 | 高并发写入,跨可用区部署 |
--quota-backend-bytes 参数调整存储配额。
以下为 3 节点 etcd 集群的典型架构示意图,展示节点间通过 Raft 协议进行 Leader 选举与日志复制:
3.2 基于 Kubernetes 的 etcd Operator 部署
etcd Operator 是 Kubernetes 上管理 etcd 集群生命周期的最佳实践。它自动化了集群的创建、扩缩容、备份、升级和故障恢复。推荐使用 etcd-operator(由 CoreOS/Red Hat 维护)或 bitnami/etcd Helm Chart。
3.2.1 部署 etcd Operator
以下步骤演示如何使用 Helm 部署 etcd Operator 并创建一个 3 节点集群:
- 添加 Helm 仓库并安装 Operator:
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
kubectl create namespace etcd-system
helm install etcd-operator bitnami/etcd --namespace etcd-system \
--set replicaCount=3 \
--set persistence.enabled=true \
--set persistence.size=10Gi \
--set auth.rbac.enabled=false
- 验证 Operator Pod 运行状态:
kubectl get pods -n etcd-system -l app.kubernetes.io/name=etcd
# 预期输出:3/3 Running
- 检查 etcd 集群成员列表:
kubectl exec -n etcd-system etcd-0 -- etcdctl member list
# 预期输出:显示 3 个成员及其端点地址
3.2.2 自定义资源定义(CRD)配置
etcd Operator 通过 CRD 定义集群规格。以下是一个典型的 EtcdCluster 资源示例:
apiVersion: etcd.database.coreos.com/v1beta2
kind: EtcdCluster
metadata:
name: prometheus-etcd
namespace: etcd-system
spec:
size: 3
version: "3.5.9"
pod:
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "2379"
storage:
volumeClaimTemplate:
spec:
storageClassName: standard
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
应用该配置:
kubectl apply -f etcd-cluster.yaml
3.3 etcd 集群健康检查与验证
部署完成后,必须执行全面的健康检查,确保集群能够正常处理 Prometheus 远端写入请求。检查分为三个层次:节点状态、Raft 一致性、读写功能。
3.3.1 节点级健康检查
| 检查项 | 命令/方法 | 健康标准 |
|---|---|---|
| 端点健康 | etcdctl endpoint health |
所有节点返回 "healthy" |
| 成员状态 | etcdctl member list |
3 个成员,均为 "unstarted" 或 "started" |
| Leader 存在 | etcdctl endpoint status |
至少一个节点为 Leader |
| 存储配额 | etcdctl alarm list |
无 NOSPACE 告警 |
3.3.2 Raft 一致性验证
通过检查 Raft 索引和提交索引的一致性,确认数据复制正常:
# 查看各节点 Raft 状态
kubectl exec -n etcd-system etcd-0 -- etcdctl endpoint status --write-out=table
+------------------+---------+---------+---------+-----------+-----------+-----------+------------+-----------------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX | RAFT APPLIED | ERRORS |
+------------------+---------+---------+---------+-----------+-----------+-----------+------------+-----------------+
| 10.0.1.10:2379 | 8e9e05c | 3.5.9 | 25 kB | true | 2 | 1024 | 1024 | |
| 10.0.1.11:2379 | 8e9e05d | 3.5.9 | 25 kB | false | 2 | 1024 | 1024 | |
| 10.0.1.12:2379 | 8e9e05e | 3.5.9 | 25 kB | false | 2 | 1024 | 1024 | |
+------------------+---------+---------+---------+-----------+-----------+-----------+------------+-----------------+
关键指标:RAFT INDEX 和 RAFT APPLIED 在所有节点上应保持一致,差值不超过 1。
3.3.3 读写功能验证
模拟 Prometheus 远端写入的数据操作:
# 写入测试数据
kubectl exec -n etcd-system etcd-0 -- etcdctl put /prometheus/metrics/test "{\"value\": 42}"
# 读取验证
kubectl exec -n etcd-system etcd-0 -- etcdctl get /prometheus/metrics/test
# 预期输出:/prometheus/metrics/test\n{"value": 42}
# 从 Follower 节点读取(确保一致性)
kubectl exec -n etcd-system etcd-1 -- etcdctl get /prometheus/metrics/test
# 预期输出:与 Leader 一致
- 所有节点健康检查通过
- Raft 索引一致,无复制延迟
- 存储配额充足(建议保留 20% 余量)
- 网络延迟 < 10ms(节点间)
- Prometheus 已配置正确的 etcd 端点
以下流程图总结了 etcd 集群部署与验证的完整步骤:
3.4 常见问题与排障
- 节点无法加入集群: 检查网络策略和防火墙,确保 2379(客户端端口)和 2380(peer 端口)互通。
- Leader 频繁切换: 检查节点间网络延迟和磁盘 I/O,Raft 心跳超时可能导致不稳定。
- 存储空间不足: 使用
etcdctl alarm disarm解除告警,并扩容 PVC 或启用自动压缩(--auto-compaction-retention)。 - Operator 无法创建集群: 检查 CRD 版本兼容性,确保 etcd-operator 镜像与 Kubernetes 版本匹配。
etcd_server_leader_changes_seen_total、etcd_disk_wal_fsync_duration_seconds),并设置告警规则。这将为后续压测水位复核提供基线数据。