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% 丢包率,模拟不稳定链路。
多集群etcd压测沙盘网络拓扑 Cluster-A (AZ-1) etcd-1 (10.0.1.2) etcd-2 (10.0.1.3) etcd-3 (10.0.1.4) Cluster-B (AZ-2) etcd-4 (10.0.2.2) etcd-5 (10.0.2.3) etcd-6 (10.0.2.4) Cluster-C (AZ-3) etcd-7 (10.0.3.2) etcd-8 (10.0.3.3) etcd-9 (10.0.3.4) 网络模拟层 (tc netem) 跨集群延迟: 10ms-50ms | 丢包率: 0.1%-1% | 带宽限制: 100Mbps 图例: Cluster-A Cluster-B Cluster-C 跨集群链路(模拟延迟/丢包) 注:集群内节点通过同一Docker bridge网络直连,延迟 < 1ms

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/ 目录