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 节点与压测工具的交互关系。
4.6 验证 etcd 集群健康与一致性
搭建完成后,必须执行以下验证步骤,确保 etcd 集群满足压测前置条件:
- 成员列表检查: 使用
etcdctl member list确认所有节点已加入集群。 - 端点健康检查: 使用
etcdctl endpoint health确认所有端点状态为healthy。 - 一致性检查: 在多个节点上执行
etcdctl get /registry/namespaces/default,确认返回结果一致。 - 压测前置检查: 确认
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 |