4. 压测沙盘环境搭建:Docker Compose 与 Kubernetes Operator 部署 etcd 集群
压测沙盘环境是进行性能瓶颈分析与参数调优的基础。本章将指导你使用两种主流方式部署 etcd 集群:Docker Compose(适用于本地开发与快速原型验证)与 Kubernetes Operator(适用于生产级、可自愈的集群管理)。两种方式均会构建一个 3 节点 etcd 集群,并配置必要的监控与压测工具。
环境前提: 确保宿主机已安装 Docker Engine 24+、Docker Compose v2+、kubectl 1.28+ 以及 kind 或 minikube(用于本地 K8s 环境)。
4.1 部署架构概览
下图展示了两种部署模式下的组件关系与数据流。左侧为 Docker Compose 模式,右侧为 Kubernetes Operator 模式,两者均包含 etcd 节点、负载均衡器(或 Service)以及压测客户端。
4.2 方式一:Docker Compose 部署
Docker Compose 适合在单机或开发环境中快速拉起一个完整的 etcd 集群。以下配置包含 3 个 etcd 成员、一个 HAProxy 负载均衡器以及一个用于压测的客户端容器。
4.2.1 docker-compose.yml 核心配置
version: '3.8'
services:
etcd-1:
image: quay.io/coreos/etcd:v3.5.15
container_name: etcd-1
environment:
- ETCD_NAME=etcd-1
- ETCD_INITIAL_CLUSTER=etcd-1=http://etcd-1:2380,etcd-2=http://etcd-2:2380,etcd-3=http://etcd-3:2380
- ETCD_INITIAL_CLUSTER_STATE=new
- ETCD_INITIAL_CLUSTER_=etcd-cluster-
- ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380
- ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379
- ETCD_ADVERTISE_CLIENT_URLS=http://etcd-1:2379
- ETCD_INITIAL_ADVERTISE_PEER_URLS=http://etcd-1:2380
- ETCD_DATA_DIR=/etcd-data
volumes:
- etcd-1-data:/etcd-data
networks:
- etcd-net
etcd-2:
image: quay.io/coreos/etcd:v3.5.15
container_name: etcd-2
environment:
- ETCD_NAME=etcd-2
- ETCD_INITIAL_CLUSTER=etcd-1=http://etcd-1:2380,etcd-2=http://etcd-2:2380,etcd-3=http://etcd-3:2380
- ETCD_INITIAL_CLUSTER_STATE=new
- ETCD_INITIAL_CLUSTER_=etcd-cluster-
- ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380
- ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379
- ETCD_ADVERTISE_CLIENT_URLS=http://etcd-2:2379
- ETCD_INITIAL_ADVERTISE_PEER_URLS=http://etcd-2:2380
- ETCD_DATA_DIR=/etcd-data
volumes:
- etcd-2-data:/etcd-data
networks:
- etcd-net
etcd-3:
image: quay.io/coreos/etcd:v3.5.15
container_name: etcd-3
environment:
- ETCD_NAME=etcd-3
- ETCD_INITIAL_CLUSTER=etcd-1=http://etcd-1:2380,etcd-2=http://etcd-2:2380,etcd-3=http://etcd-3:2380
- ETCD_INITIAL_CLUSTER_STATE=new
- ETCD_INITIAL_CLUSTER_=etcd-cluster-
- ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380
- ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379
- ETCD_ADVERTISE_CLIENT_URLS=http://etcd-3:2379
- ETCD_INITIAL_ADVERTISE_PEER_URLS=http://etcd-3:2380
- ETCD_DATA_DIR=/etcd-data
volumes:
- etcd-3-data:/etcd-data
networks:
- etcd-net
haproxy:
image: haproxy:2.8-alpine
container_name: haproxy
ports:
- "2379:2379"
volumes:
- ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
depends_on:
- etcd-1
- etcd-2
- etcd-3
networks:
- etcd-net
benchmark:
image: quay.io/coreos/etcd:v3.5.15
container_name: benchmark
entrypoint: ["/bin/sh"]
stdin_open: true
tty: true
networks:
- etcd-net
volumes:
etcd-1-data:
etcd-2-data:
etcd-3-data:
networks:
etcd-net:
driver: bridge
4.2.2 HAProxy 配置(haproxy.cfg)
global
log stdout format raw local0
maxconn 4096
defaults
log global
mode tcp
option tcplog
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend etcd_front
bind *:2379
default_backend etcd_back
backend etcd_back
balance roundrobin
server etcd-1 etcd-1:2379 check inter 2s fall 3 rise 2
server etcd-2 etcd-2:2379 check inter 2s fall 3 rise 2
server etcd-3 etcd-3:2379 check inter 2s fall 3 rise 2
4.2.3 启动与验证
- 启动集群:
docker compose up -d - 检查成员状态:
docker exec etcd-1 etcdctl member list - 验证写入:
docker exec etcd-1 etcdctl put /test/key "hello" - 验证读取:
docker exec etcd-1 etcdctl get /test/key - 进入压测容器:
docker exec -it benchmark sh
关键参数说明:
ETCD_INITIAL_CLUSTER:必须列出所有成员的 peer URL,顺序无关。ETCD_INITIAL_CLUSTER_STATE=new:首次启动必须为new,后续重启需改为existing。ETCD_LISTEN_CLIENT_URLS:绑定0.0.0.0:2379以接受外部连接。
4.3 方式二:Kubernetes Operator 部署
在生产环境或需要自动故障恢复的场景下,推荐使用 etcd-operator。Operator 负责管理 etcd 集群的生命周期,包括创建、扩缩容、备份与恢复。
4.3.1 安装 etcd-operator
# 创建命名空间
kubectl create namespace etcd-cluster
# 部署 operator
kubectl apply -f https://raw.githubusercontent.com/coreos/etcd-operator/master/example/deployment.yaml -n etcd-cluster
# 验证 operator 运行
kubectl get pods -n etcd-cluster -l name=etcd-operator
4.3.2 创建 etcd 集群 CR(Custom Resource)
apiVersion: "etcd.database.coreos.com/v1beta2"
kind: "EtcdCluster"
metadata:
name: "etcd-cluster"
namespace: "etcd-cluster"
spec:
size: 3
version: "3.5.15"
pod:
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
etcdEnv:
- name: ETCD_QUOTA_BACKEND_BYTES
value: "8589934592" # 8GB
- name: ETCD_AUTO_COMPACTION_RETENTION
value: "1"
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: etcd_cluster
operator: In
values:
- "etcd-cluster"
topologyKey: kubernetes.io/hostname
4.3.3 应用 CR 并验证
# 应用 CR
kubectl apply -f etcd-cluster.yaml
# 查看集群状态
kubectl get etcdcluster -n etcd-cluster
# 查看 Pod 列表
kubectl get pods -n etcd-cluster -l app=etcd
# 查看 Service
kubectl get svc -n etcd-cluster
# 测试连接(从集群内)
kubectl run -it --rm --image=quay.io/coreos/etcd:v3.5.15 test-client --restart=Never -- \
etcdctl --endpoints=http://etcd-cluster-client:2379 put /test/key "hello"
4.4 两种部署方式对比
| 维度 | Docker Compose | Kubernetes Operator |
|---|---|---|
| 部署复杂度 | 低,单机即可运行 | 中,需要 K8s 集群 |
| 故障自愈 | 无,需手动重启 | 自动重建故障 Pod |
| 扩缩容 | 手动修改 compose 文件 | 修改 CR 中 size 字段 |
| 持久化 | Docker Volume | PVC + PV |
| 网络模型 | Docker 网络 | K8s Service + DNS |
| 适用场景 | 本地开发、快速原型 | 生产环境、CI/CD |
4.5 压测沙盘初始化检查清单
在开始压测之前,请确认以下项目均已就绪:
- 集群健康:所有 etcd 成员处于
started状态,leader 选举正常。 - 网络连通:压测客户端可通过负载均衡器或 Service 访问 etcd 的 2379 端口。
- 资源预留:CPU 和内存限制已设置,避免压测时资源争抢。
- 数据目录:持久化卷已挂载,且具有足够的 IOPS 能力(建议 SSD)。
- 监控接入:Prometheus 或 etcd 内置 metrics 端点可访问(
/metrics)。
注意: 在 Kubernetes 环境中,如果使用
kind 或 minikube,请确保为 etcd Pod 分配了足够的节点资源。建议为每个 etcd 实例预留至少 1 个 CPU 核心和 1GB 内存,以避免压测过程中出现 OOMKill 或 CPU Throttling。
4.6 快速验证脚本
以下脚本可用于验证集群是否具备压测条件:
#!/bin/bash
# etcd 压测前健康检查脚本
ENDPOINT=${1:-"http://localhost:2379"}
echo "=== 检查集群健康 ==="
etcdctl --endpoints=$ENDPOINT endpoint health --cluster
echo "=== 检查成员列表 ==="
etcdctl --endpoints=$ENDPOINT member list
echo "=== 检查 leader 状态 ==="
etcdctl --endpoints=$ENDPOINT endpoint status --cluster -w table
echo "=== 写入测试键值 ==="
etcdctl --endpoints=$ENDPOINT put /health-check "ok"
echo "=== 读取测试键值 ==="
etcdctl --endpoints=$ENDPOINT get /health-check
echo "=== 删除测试键值 ==="
etcdctl --endpoints=$ENDPOINT del /health-check
echo "=== 检查 metrics 端点 ==="
curl -s $ENDPOINT/metrics | head -20
echo "=== 完成 ==="
执行 bash check_etcd.sh http://etcd-cluster-client:2379(K8s 环境)或 bash check_etcd.sh http://localhost:2379(Docker Compose 环境),输出应显示所有端点均为 healthy,且 leader 唯一。