如何使用 Helm 在 Kubernetes 上部署高可用 ETCD 集群?

摘要:# ETCD 集群部署指南 (v3.6.4) > 基于 Kubernetes + Helm 部署高可用 ETCD 集群 ## 目录 - [一、常规部署步骤](#一常规部署步骤) - [二、检查集群状态
# ETCD 集群部署指南 (v3.6.4) > 基于 Kubernetes + Helm 部署高可用 ETCD 集群 --- ## 目录 - [一、常规部署步骤](#一常规部署步骤) - [二、检查集群状态](#二检查集群状态) - [三、集群数据验证](#三集群数据验证) - [四、values.yaml 配置详解](#四valuesyaml-配置详解) - [五、LoadBalancer 创建](#五loadbalancer-创建) - [六、监控配置](#六监控配置) - [七、ArgoCD 管理](#七argocd-管理) --- ## 一、常规部署步骤 ### 1.1 添加 Helm 仓库 ```bash # 添加 Bitnami 仓库(维护最完善的 etcd Helm Chart) helm repo add bitnami https://charts.bitnami.com/bitnami # 更新仓库索引 helm repo update ``` ### 1.2 创建命名空间和 Secret ```bash # 创建命名空间 kubectl create ns etcd-dev # 创建密码 Secret(替代 values.yaml 中的明文密码) kubectl create secret generic etcd-rbac-secret -n etcd-dev \ --from-literal=password=运维配置 ``` ### 1.3 拉取 Chart 并部署 ```bash # 拉取 charts 至本地 helm pull bitnami/etcd --untar # 备份默认 values.yaml 文件,创建自定义 etcd-values.yaml # 建议在执行部署升级命令之前添加 --dry-run --debug 参数验证 values.yaml 文件正确性 # 部署命令 helm install etcd ./etcd -f ./etcd/values.yaml -n etcd-dev # 升级命令 helm upgrade etcd ./etcd -f ./etcd/values.yaml -n etcd-dev ``` --- ## 二、检查集群状态 ### 2.1 查看 Pod 和 Service 状态 ```bash # 查看 pod, svc 状态 kubectl get pods -n etcd-dev kubectl get svc -n etcd-dev ``` ### 2.2 进入 Pod 检查集群 ```bash # 进入 pod,使用 etcdctl 命令查看 kubectl exec -it etcd-0 -n etcd-dev -- /bin/sh # 查看集群成员 etcdctl member list # 检查集群健康状态(高可用核心验证) etcdctl --user=root:认证密码 endpoint health \ --endpoints=http://etcd-0.etcd-headless.etcd-dev.svc.cluster.local:2379,http://etcd-1.etcd-headless.etcd-dev.svc.cluster.local:2379,http://etcd-2.etcd-headless.etcd-dev.svc.cluster.local:2379 ``` --- ## 三、集群数据验证 ### 3.1 写入测试数据 ```bash # 在 etcd-0 POD 节点创建数据 etcdctl --user root:认证密码 put a 1 ``` ### 3.2 在所有节点验证 ```bash # 在所有 POD 节点查询,都能查询到说明集群正常 etcdctl --user root:认证密码 get a # 预期输出 # a # 1 ``` --- ## 四、values.yaml 配置详解 ### 4.1 镜像配置 ```yaml # 1. 镜像仓库修改,原 docker.io 镜像地址不可用 image: registry: public.ecr.aws repository: bitnami/etcd tag: 3.6.4-debian-12-r3 ``` ### 4.2 RBAC 认证配置 ```yaml # 2. rbac 认证账号密钥配置 auth: rbac: create: true allowNoneAuthentication: false rootPassword: "" existingSecret: "etcd-rbac-secret" existingSecretPasswordKey: "password" ``` ### 4.3 资源配置 ```yaml # 3. etcd 容器资源配置 resources: requests: cpu: 500m memory: 512Mi limits: cpu: 2000m memory: 4Gi ``` ### 4.4 持久化存储配置 ```yaml # 4. PVC 持久卷配置 persistence: storageClass: "gp3" annotations: {} labels: {} accessModes: - ReadWriteOnce size: 20Gi ``` ### 4.5 监控指标配置 ```yaml # 5. 开启 metrics 监控指标推送 metrics: enabled: true useSeparateEndpoint: true podAnnotations: prometheus.io/scrape: "true" prometheus.io/port: "{{ .Values.metrics.useSeparateEndpoint | ternary .Values.containerPorts.metrics .Values.containerPorts.client }}" ``` ### 4.6 安全配置 ```yaml # 6. 开启容器镜像安全限制,解决第1步修改导致报错 global: security: allowInsecureImages: true ``` --- ## 五、LoadBalancer 创建 ### 5.1 创建外部访问 Service ```yaml # etcd 通过 grpc 协议通讯,创建 LoadBalancer 类型 SVC 允许外部访问 apiVersion: v1 kind: Service metadata: name: etcd-lb-service namespace: etcd-dev annotations: service.beta.kubernetes.io/aws-load-balancer-type: "nlb" service.beta.kubernetes.io/aws-load-balancer-scheme: "internal" service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip" spec: type: LoadBalancer ports: - name: etcd-client port: 2379 # Service 端口(外部访问端口) targetPort: 2379 # etcd Pod 端口 protocol: TCP # etcd 基于 TCP 通信 appProtocol: grpc # 标识为 gRPC 协议(AWS NLB 可优化转发) selector: app.kubernetes.io/component: etcd app.kubernetes.io/name: etcd app.kubernetes.io/instance: etcd-cluster-dev # 不同环境需区分 ``` --- ## 六、监控配置 ### 6.1 Prometheus 采集配置 ```yaml # 生产修改 job_name, env 即可,看板 setting 中修改 cluster 变量即可 - job_name: 'ltp_dev_etcd_cluster' metrics_path: /metrics scrape_interval: 15s scrape_timeout: 15s static_configs: - targets: ['etcd-0.etcd-headless.etcd-dev.svc.cluster.local:9090'] labels: instance: etcd-0 env: dev - targets: ['etcd-1.etcd-headless.etcd-dev.svc.cluster.local:9090'] labels: instance: etcd-1 env: dev - targets: ['etcd-2.etcd-headless.etcd-dev.svc.cluster.local:9090'] labels: instance: etcd-2 env: dev ``` ### 6.2 Grafana 看板 看板 URL: ``` https://grafana.ltpin.com/d/655de576-0806-4a29-b04f-84bf4984a2d9/etcd-cluster-nonprod?orgId=1&from=now-3h&to=now&timezone=browser&var-cluster=ltp_nonprod_etcd_cluster ``` ### 6.3 关键监控指标 | 指标 | 说明 | |------|------| | **Etcd has a leader?** | 集群是否有 Leader(YES/NO) | | **Leader changes seen** | Leader 切换次数 | | **Failed proposals** | 失败提案数 | | **RPC Rate** | RPC 请求速率 | | **Active Streams** | 活跃连接数 | | **DB Size** | 数据库大小 | | **Disk Sync Duration** | 磁盘同步耗时 | | **Memory** | 内存使用 | --- ## 七、ArgoCD 管理 ### 7.1 Helm Chart 仓库地址 ``` https://github.com/LiquidityTech/devops-infra-deploy-manifests/tree/main/etcd ``` ### 7.2 不同环境配置 | 环境 | values 文件 | |------|-------------| | dev | `values-dev.yaml` | | qa | `values-qa.yaml` | ### 7.3 ArgoCD 应用配置 ```yaml fullnameOverride: "etcd" namespaceOverride: "etcd-dev" podMonitor: enabled: true namespace: etcd-dev # podmonitor 指定创建命名空间,需随环境修改 ``` ### 7.4 部署流程 1. 同步前需手动按步骤1创建 Secret 2. 同步完成后按步骤5创建外部访问 LB --- ## 八、架构图 ``` ┌─────────────────────────────────────────────────────────────────┐ │ Kubernetes Cluster │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ etcd-0 │ │ etcd-1 │ │ etcd-2 │ │ │ │ (Leader) │◄──►│ (Follower) │◄──►│ (Follower) │ │ │ │ :2379 │ │ :2379 │ │ :2379 │ │ │ │ :9090 │ │ :9090 │ │ :9090 │ │ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │ │ │ │ │ │ └────────────────┬┴─────────────────┘ │ │ │ │ │ ┌────────▼────────┐ │ │ │ etcd-headless │ │ │ │ (Service) │ │ │ └────────┬────────┘ │ │ │ │ │ ┌────────▼────────┐ │ │ │ etcd-lb-svc │ │ │ │ (LoadBalancer) │ │ │ │ :2379 │ │ │ └────────┬────────┘ │ │ │ │ └───────────────────────────┼──────────────────────────────────────┘ │ ┌────────▼────────┐ │ AWS NLB │ │ (Internal) │ └────────┬────────┘ │ ┌────────▼────────┐ │ External Apps │ └─────────────────┘ ``` --- ## 九、最佳实践 | 场景 | 建议 | |------|------| | **生产环境** | 使用 3 节点集群,配置 gp3 存储 | | **密码管理** | 使用 Secret 而非明文配置 | | **监控告警** | 配置 Leader 切换、RPC 延迟告警 | | **备份** | 定期执行 etcdctl snapshot save | | **升级** | 使用滚动升级,先升级 Follower | ---