生产环境kubernetes高可用集群最低可行配置为3 master节点+堆叠etcd,必须搭配haproxy/clb与keepalived(或云厂商lb),且需提前对齐节点时间、存储路径及证书san;堆叠etcd因运维简洁、避免外部依赖而成为务实选择,但须用奇数节点、显式声明完整etcd拓扑、独立挂载/data/etcd并禁用atime,同时--control-plane-endpoint必须设为vip纯ip而非域名,健康检查应绕过tls直接探测端口。

生产环境部署 Kubernetes 高可用集群,不能只靠 kubeadm init 跑通就完事——控制平面单点故障、etcd 数据丢失、VIP 漂移失败、证书过期导致节点失联,这些才是真实压测或半夜告警时最常炸出来的点。核心判断就一条:3 Master 节点 + 堆叠 etcd 是最低可行配置,但必须配 HAProxy/CLB + Keepalived(或云厂商 LB),且所有节点时间、存储路径、证书 SAN 必须提前对齐。
为什么堆叠 etcd 是生产环境的务实选择
堆叠 etcd(即每个 Master 同时运行 etcd + kube-apiserver)不是妥协,而是权衡后的可靠方案。它避免了外部 etcd 集群带来的网络延迟、TLS 证书管理爆炸、跨组件升级顺序依赖等运维黑洞。但前提是:必须用奇数节点(3 或 5),且所有 etcd 成员必须在初始化前就通过 --initial-cluster 显式声明完整拓扑,否则后续 kubeadm join --control-plane 会卡在 etcd member add 阶段。
常见错误现象:kubeadm join 卡住,journalctl -u etcd 报 member X has already been bootstrapped 或 context deadline exceeded;根本原因是节点间无法建立 peer 连接,通常源于防火墙未放行 2379-2380,或 --initial-advertise-peer-urls 写成 localhost 而非实际内网 IP。
- etcd 数据目录必须独立于系统盘,例如统一挂载到
/data/etcd,并确保该路径在所有 Master 上存在且权限为600 - 每个节点的
--name必须唯一,且与--initial-cluster中的名称严格一致(大小写敏感) - 不要复用
kubeadm init生成的默认证书 —— 生产环境必须提前生成含全部 Master IP 和 VIP 的 SAN 证书,否则kube-apiserver启动后会拒绝来自其他 Master 的 TLS 连接
HAProxy + Keepalived 的健康检查必须绕过 kube-apiserver 的 TLS 终止
很多团队把 curl -k https://localhost:6443/healthz 直接塞进 Keepalived 的 vrrp_script,结果 VIP 频繁漂移。原因在于:HAProxy 默认不终止 TLS,它把加密流量原样转发给后端 apiserver;而 apiserver 的 /healthz 端点要求合法客户端证书(或 bearer token),裸 curl 会返回 401,被误判为服务宕机。
正确做法是让 HAProxy 自己做健康检查,或改用 TCP 层探测:
- HAProxy 配置中启用
option httpchk GET /readyz,并在bind *:6443 ssl crt /etc/haproxy/certs/apiserver.pem后加verify none(仅限内网可信环境) - Keepalived 的检测脚本应改为:
timeout 2 bash -c 'echo > /dev/tcp/127.0.0.1/6443' 2>/dev/null—— 只验证端口通不通,不碰 TLS 握手 - 务必关闭
haproxy的ssl-hello-chk(它会发 ClientHello 并等待 ServerHello,但 apiserver 不响应这种裸 TLS 探针)
kubeadm init --control-plane-endpoint 必须指向 VIP,且不能是域名
--control-plane-endpoint 是整个高可用链路的锚点。填 https://k8s-api.internal:6443 看起来整洁,但一旦 DNS 解析失败或缓存过期,新节点 join 就会永久卡住 —— 因为 kubeadm 在生成证书时会把该值写入 front-proxy-client.crt 的 SAN,而证书校验不走 DNSSEC。
实操要点:
- 该参数必须是 VIP 的纯 IP 地址,例如
10.0.0.100:6443,且该 IP 必须出现在所有 Master 的证书 SAN 列表中 - 所有节点的
/etc/hosts中禁止将该 VIP 解析为任何主机名(包括自身),否则kubelet启动时会尝试用主机名连接 API,触发证书 CN 不匹配错误 - 第一次
kubeadm init后,立即用kubeadm certs check-expiration验证所有证书是否含该 VIP —— 若缺失,需用kubeadm certs renew+ 自定义--certificate-renewal配置重签
最易被忽略的点是 etcd 数据目录的磁盘 I/O:哪怕用了 SSD,若未将 /data/etcd 单独挂载并禁用 atime(mount -o remount,noatime /data),在大规模节点注册或 ConfigMap 频繁更新时,etcd WAL 写入延迟会飙升至秒级,直接触发 leader 频繁切换。这不是配置问题,是存储层事实。











