4. 压测沙盘环境搭建:Docker Compose部署多集群etcd、网络拓扑模拟、证书配置
压测沙盘的核心目标是复现真实生产环境中的多集群etcd拓扑与网络条件。本章将指导你使用Docker Compose完成三集群九节点的etcd部署,并通过Linux tc/netem模拟跨AZ延迟与丢包,同时配置双向TLS证书确保通信安全。
4.1 整体架构与网络拓扑
沙盘采用三集群(Cluster-A / Cluster-B / Cluster-C)拓扑,每个集群包含3个etcd节点,共9个容器。集群间通过独立的Docker网络隔离,模拟不同可用区(AZ)或数据中心。
拓扑设计要点:
- 集群内延迟:同一集群节点间延迟 < 1ms(同一Docker bridge网络)。
- 集群间延迟:跨集群节点间延迟 10ms-50ms(通过tc netem注入)。
- 丢包模拟:可选注入 0.1%-1% 丢包率,模拟不稳定链路。
4.2 Docker Compose 服务编排
使用Docker Compose定义三个独立的etcd集群服务。每个集群使用独立的网络和节点配置。
4.2.1 目录结构
etcd-bench-sandbox/
├── docker-compose.yml
├── certs/
│ ├── ca.pem
│ ├── ca-key.pem
│ ├── server.pem
│ ├── server-key.pem
│ ├── client.pem
│ └── client-key.pem
├── scripts/
│ ├── setup-tc.sh
│ └── health-check.sh
└── data/
├── cluster-a/
├── cluster-b/
└── cluster-c/
4.2.2 docker-compose.yml 核心配置
version: '3.8'
networks:
net-a:
driver: bridge
ipam:
config:
- subnet: 10.0.1.0/24
net-b:
driver: bridge
ipam:
config:
- subnet: 10.0.2.0/24
net-c:
driver: bridge
ipam:
config:
- subnet: 10.0.3.0/24
services:
etcd-a1:
image: quay.io/coreos/etcd:v3.5.9
container_name: etcd-a1
networks:
net-a:
ipv4_address: 10.0.1.2
volumes:
- ./certs:/etc/etcd/certs:ro
- ./data/cluster-a/etcd-a1:/var/lib/etcd
environment:
ETCD_NAME: etcd-a1
ETCD_INITIAL_CLUSTER: etcd-a1=http://10.0.1.2:2380,etcd-a2=http://10.0.1.3:2380,etcd-a3=http://10.0.1.4:2380
ETCD_INITIAL_CLUSTER_STATE: new
ETCD_INITIAL_CLUSTER_: cluster-a-
ETCD_LISTEN_PEER_URLS: https://0.0.0.0:2380
ETCD_LISTEN_CLIENT_URLS: https://0.0.0.0:2379
ETCD_ADVERTISE_CLIENT_URLS: https://10.0.1.2:2379
ETCD_TRUSTED_CA_FILE: /etc/etcd/certs/ca.pem
ETCD_CERT_FILE: /etc/etcd/certs/server.pem
ETCD_KEY_FILE: /etc/etcd/certs/server-key.pem
ETCD_PEER_TRUSTED_CA_FILE: /etc/etcd/certs/ca.pem
ETCD_PEER_CERT_FILE: /etc/etcd/certs/server.pem
ETCD_PEER_KEY_FILE: /etc/etcd/certs/server-key.pem
ETCD_CLIENT_CERT_AUTH: "true"
ETCD_PEER_CLIENT_CERT_AUTH: "true"
ports:
- "23791:2379"
- "23801:2380"
# etcd-a2, etcd-a3 类似配置,IP分别为10.0.1.3, 10.0.1.4
# etcd-b1~b3, etcd-c1~c3 类似配置,使用对应网络和IP
配置要点:
- 每个集群使用独立的Docker bridge网络,IP段不重叠。
- 所有节点启用双向TLS认证(client-cert-auth 和 peer-client-cert-auth 均设为 true)。
- 数据目录映射到宿主机,便于持久化和事后分析。
4.3 证书配置与生成
沙盘使用自签名CA证书体系,包含CA根证书、服务端证书和客户端证书。以下使用cfssl工具生成证书。
4.3.1 CA证书生成
# 生成CA配置文件
cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"server": {
"usages": ["signing", "key encipherment", "server auth"],
"expiry": "87600h"
},
"client": {
"usages": ["signing", "key encipherment", "client auth"],
"expiry": "87600h"
},
"peer": {
"usages": ["signing", "key encipherment", "server auth", "client auth"],
"expiry": "87600h"
}
}
}
}
EOF
# 生成CA证书和私钥
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
4.3.2 服务端与客户端证书
# 服务端证书(包含所有节点IP作为SAN)
cat > server-csr.json <<EOF
{
"CN": "etcd-server",
"hosts": [
"10.0.1.2", "10.0.1.3", "10.0.1.4",
"10.0.2.2", "10.0.2.3", "10.0.2.4",
"10.0.3.2", "10.0.3.3", "10.0.3.4",
"127.0.0.1", "localhost"
],
"key": {
"algo": "rsa",
"size": 2048
}
}
EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem \
-config=ca-config.json -profile=server server-csr.json | cfssljson -bare server
# 客户端证书
cat > client-csr.json <<EOF
{
"CN": "etcd-client",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
}
}
EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem \
-config=ca-config.json -profile=client client-csr.json | cfssljson -bare client
证书配置注意事项:
- 服务端证书的hosts字段必须包含所有etcd节点的IP地址,否则TLS握手会失败。
- 生产环境建议使用更短的证书有效期,沙盘环境设为10年(87600h)减少维护成本。
- 证书文件权限应设为600,防止私钥泄露。
4.4 网络拓扑模拟(tc netem)
使用Linux tc命令在容器内注入延迟和丢包,模拟跨AZ网络条件。通过自定义脚本在容器启动后自动配置。
4.4.1 setup-tc.sh 脚本
#!/bin/bash
# 用于在etcd容器启动后配置网络模拟
# 参数: $1 = 目标IP, $2 = 延迟(ms), $3 = 丢包率(%)
TC_DELAY=${2:-10}
TC_LOSS=${3:-0.1}
# 添加根qdisc
tc qdisc add dev eth0 root handle 1: htb default 30
# 创建分类
tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 100mbit
tc class add dev eth0 parent 1:1 classid 1:20 htb rate 100mbit
# 对目标IP应用延迟和丢包
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
match ip dst $1 flowid 1:10
tc qdisc add dev eth0 parent 1:10 handle 10: netem \
delay ${TC_DELAY}ms loss ${TC_LOSS}%
# 对其他流量应用较小延迟
tc filter add dev eth0 protocol ip parent 1:0 prio 2 u32 \
match ip dst 0.0.0.0/0 flowid 1:20
tc qdisc add dev eth0 parent 1:20 handle 20: netem delay 1ms
4.4.2 网络模拟参数对照表
| 链路类型 | 延迟 | 丢包率 | 带宽限制 | 模拟场景 |
|---|---|---|---|---|
| 集群内(同AZ) | < 1ms | 0% | 1Gbps | 同机房内网 |
| 集群间(跨AZ) | 10ms | 0.1% | 100Mbps | 同区域多可用区 |
| 集群间(跨Region) | 50ms | 0.5% | 50Mbps | 异地多活场景 |
| 恶劣链路 | 100ms | 1% | 10Mbps | 边缘节点/跨国 |
4.5 启动与验证
4.5.1 启动沙盘
# 启动所有集群
docker-compose up -d
# 检查容器状态
docker-compose ps
# 验证集群健康(以Cluster-A为例)
docker exec etcd-a1 etcdctl \
--endpoints=https://10.0.1.2:2379 \
--cacert=/etc/etcd/certs/ca.pem \
--cert=/etc/etcd/certs/client.pem \
--key=/etc/etcd/certs/client-key.pem \
endpoint health --cluster
4.5.2 验证网络模拟
# 从Cluster-A节点ping Cluster-B节点,验证延迟
docker exec etcd-a1 ping -c 5 10.0.2.2
# 使用mtr查看路由路径
docker exec etcd-a1 mtr -r -c 10 10.0.2.2
# 验证TLS连接
docker exec etcd-a1 openssl s_client \
-connect 10.0.2.2:2379 \
-CAfile /etc/etcd/certs/ca.pem \
-cert /etc/etcd/certs/client.pem \
-key /etc/etcd/certs/client-key.pem
验证清单:
- 所有9个etcd容器均处于Up状态。
- 每个集群的3个节点形成raft group,leader选举正常。
- 跨集群ping延迟符合tc配置值(10ms/50ms)。
- TLS双向认证连接成功,无证书错误。
4.6 沙盘环境参数总览
| 参数项 | 配置值 | 说明 |
|---|---|---|
| etcd版本 | v3.5.9 | 当前最新稳定版 |
| 集群数量 | 3 | Cluster-A/B/C |
| 每集群节点数 | 3 | 满足raft多数派要求 |
| 总节点数 | 9 | 3 × 3 |
| 存储后端 | boltdb | etcd默认存储引擎 |
| TLS版本 | 1.3 | 双向认证 |
| 证书算法 | RSA 2048 | 兼容性优先 |
| 网络模拟工具 | tc netem | Linux内核原生 |
| 数据持久化 | 宿主机volume | ./data/ 目录 |