4. 压测沙盘环境搭建:使用 kind 或 kubeadm 搭建单/多节点 K8s 集群,配置 etcd 集群

压测沙盘是验证 etcd 与 K8s 一致性复核的基础设施。本章将指导你使用 kind(Kubernetes in Docker)和 kubeadm 两种方式搭建单/多节点集群,并重点配置 etcd 集群参数,确保后续压测数据可复现、可观测。

4.1 环境准备与工具选型对比

在开始搭建前,需要根据实验目标选择合适的工具。下表从资源消耗、etcd 可控性、网络复杂度三个维度进行对比:

工具 资源消耗 etcd 可控性 网络复杂度 推荐场景
kind 低(容器化节点) 中等(需额外挂载配置) 低(单机 Docker 网络) 快速原型、单节点压测、CI 环境
kubeadm 中高(虚拟机或裸机) 高(直接操作 etcd 二进制) 中(需配置 CNI 与负载均衡) 多节点压测、etcd 调优、生产级模拟
建议: 本章先使用 kind 快速搭建单节点沙盘,再使用 kubeadm 搭建 3 节点 etcd 集群,覆盖两种主流场景。

4.2 使用 kind 搭建单节点 K8s 集群

kind 将每个 K8s 节点运行在 Docker 容器中,适合在开发机上快速启动沙盘。以下步骤配置一个包含 1 个控制面节点、并暴露 etcd 端口的集群。

4.2.1 安装 kind 与创建集群配置

# 安装 kind(Linux / macOS)
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind

# 创建集群配置文件 kind-etcd.yaml
cat <<EOF > kind-etcd.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 2379
    hostPort: 2379
    protocol: TCP
  - containerPort: 2380
    hostPort: 2380
    protocol: TCP
  kubeadmConfigPatches:
  - |
    apiVersion: kubeadm.k8s.io/v1beta3
    kind: ClusterConfiguration
    etcd:
      local:
        extraArgs:
          "listen-metrics-urls": "http://0.0.0.0:2381"
          "quota-backend-bytes": "8589934592"
EOF

# 创建集群
kind create cluster --config kind-etcd.yaml --name etcd-sandbox

4.2.2 验证 etcd 端点可达性

集群创建后,etcd 监听在容器内 2379 端口,并通过 hostPort 映射到宿主机。使用 etcdctl 验证:

# 进入 kind 控制面容器
docker exec -it etcd-sandbox-control-plane sh

# 使用 etcdctl 检查成员列表
etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  member list

# 预期输出类似:
# 8e9e05c52164694d, started, etcd-sandbox-control-plane, https://172.18.0.2:2380, https://172.18.0.2:2379, false
关键参数说明: quota-backend-bytes 设置为 8GB,模拟生产环境 etcd 存储上限;listen-metrics-urls 暴露 metrics 端点,供后续压测采集。

4.3 使用 kubeadm 搭建多节点 K8s 集群(3 节点 etcd)

kubeadm 提供更精细的 etcd 控制能力,适合模拟多节点 etcd 集群的 Raft 行为。以下步骤在 3 台虚拟机(或裸机)上搭建 1 个控制面 + 2 个 worker 节点,etcd 以堆叠模式运行。

4.3.1 节点规划与前置条件

主机名 IP 地址 角色 etcd 成员
master-1 192.168.1.10 控制面 + etcd member-1
worker-1 192.168.1.20 Worker —
worker-2 192.168.1.30 Worker —

所有节点需安装 Docker、kubelet、kubeadm、kubectl,并关闭 swap。

4.3.2 初始化控制面节点并配置 etcd 集群

# 在 master-1 上执行初始化
sudo kubeadm init --control-plane-endpoint=192.168.1.10:6443 \
  --pod-network-cidr=10.244.0.0/16 \
  --apiserver-advertise-address=192.168.1.10 \
  --etcd-extra-args="quota-backend-bytes=8589934592,listen-metrics-urls=http://0.0.0.0:2381"

# 初始化完成后,复制 kubeconfig
mkdir -p $HOME/.kube
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 验证 etcd 集群状态
kubectl get pods -n kube-system -l component=etcd
# 预期输出:etcd-master-1   1/1   Running

4.3.3 加入 Worker 节点并验证集群

# 在 worker-1 和 worker-2 上分别执行 join 命令(从 init 输出获取)
sudo kubeadm join 192.168.1.10:6443 -- <> \
  --discovery--ca-cert-hash sha256:<hash>

# 在 master-1 上验证节点就绪
kubectl get nodes
# 预期输出:
# NAME       STATUS   ROLES           AGE   VERSION
# master-1   Ready    control-plane   5m    v1.28.0
# worker-1   Ready    <none>          2m    v1.28.0
# worker-2   Ready    <none>          2m    v1.28.0

4.4 etcd 集群配置关键参数

无论使用 kind 还是 kubeadm,etcd 的压测相关参数必须显式配置。下表列出核心参数及其压测影响:

参数 默认值 压测推荐值 说明
quota-backend-bytes 2GB 8GB 或更高 限制 etcd 数据库大小,超出后触发告警
max-txn-ops 128 512 单次事务最大操作数,影响批量写入吞吐
max-request-bytes 1.5MB 10MB 单次请求最大字节数,影响大对象存储
snapshot-count 100000 50000 触发快照的事务数,降低可减少 WAL 积压
heartbeat-interval 100ms 100ms Leader 心跳间隔,影响 Raft 选举灵敏度
election-timeout 1000ms 1000ms 选举超时,压测中不宜过低避免频繁选举
注意: 修改 quota-backend-bytes 后,如果已有数据超过新配额,etcd 将进入只读模式。建议在空集群或压测前设置。

4.5 压测沙盘架构总览

下图展示使用 kubeadm 搭建的 3 节点 etcd 集群在压测沙盘中的逻辑架构,包含控制面、etcd 成员、worker 节点与压测工具的交互关系。

压测沙盘架构图 - 3 节点 etcd 集群 压测沙盘架构图(kubeadm 3 节点 etcd) 压测客户端 kube-apiserver etcd 集群(3 节点堆叠模式) etcd-1 etcd-2 etcd-3 worker-1 worker-2 worker-3 说明 • 实线:直接请求 • 虚线:控制面下发 • 绿色:etcd 成员

4.6 验证 etcd 集群健康与一致性

搭建完成后,必须执行以下验证步骤,确保 etcd 集群满足压测前置条件:

  1. 成员列表检查: 使用 etcdctl member list 确认所有节点已加入集群。
  2. 端点健康检查: 使用 etcdctl endpoint health 确认所有端点状态为 healthy。
  3. 一致性检查: 在多个节点上执行 etcdctl get /registry/namespaces/default,确认返回结果一致。
  4. 压测前置检查: 确认 quota-backend-bytes 已生效,使用 etcdctl endpoint status --write-out=table 查看 DB 大小。
# 在 master-1 上执行完整验证脚本
echo "=== 1. 成员列表 ==="
etcdctl --endpoints=https://192.168.1.10:2379,https://192.168.1.20:2379,https://192.168.1.30:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  member list

echo "=== 2. 端点健康 ==="
etcdctl --endpoints=https://192.168.1.10:2379,https://192.168.1.20:2379,https://192.168.1.30:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  endpoint health

echo "=== 3. 一致性检查 ==="
for ep in https://192.168.1.10:2379 https://192.168.1.20:2379 https://192.168.1.30:2379; do
  echo "Endpoint: $ep"
  etcdctl --endpoints=$ep \
    --cacert=/etc/kubernetes/pki/etcd/ca.crt \
    --cert=/etc/kubernetes/pki/etcd/server.crt \
    --key=/etc/kubernetes/pki/etcd/server.key \
    get /registry/namespaces/default
done
验证通过标准: 所有成员状态为 started,所有端点健康为 true,且三个端点返回的 namespace 对象 revision 一致。

4.7 常见问题与避坑指南

问题 原因 解决方案
kind 集群创建后 etcd 端口无法访问 hostPort 未正确映射或防火墙拦截 检查 docker ps 确认端口映射;关闭宿主机防火墙或添加放行规则
kubeadm init 卡在 etcd 健康检查 节点间网络不通或 etcd 证书不匹配 确保 2379/2380 端口互通;重新生成 etcd 证书并分发
etcd 集群频繁选举 heartbeat-interval 与 election-timeout 比例不当 保持默认 100ms/1000ms 比例;检查网络延迟是否过高
压测时 etcd 写入延迟突增 磁盘 IO 成为瓶颈或快照频率过高 使用 SSD 存储;调大 snapshot-count 至 200000