用途
该技能面向规划与实施 Kubespray 高可用 Kubernetes 集群的场景,帮助理解 HA 架构并完成控制平面冗余、etcd quorum 规划与 API Server 负载均衡配置。资料明确其不适用于单节点部署(应使用 kubespray-deployment)以及 HA 故障排查(应使用 kubespray-troubleshooting)。
核心架构原则
- API Server:主动-主动,所有实例均处理请求。
- Controller-Manager 与 Scheduler:主动-备用,通过 leader election 选主。
- etcd:基于 Raft 共识,需要多数派(quorum)。
集群由多个控制节点(同时承载 API Server、Controller-Manager、Scheduler、etcd)、worker 节点(kubelet、kube-proxy,默认含 nginx-proxy)及可选的外部负载均衡器组成。
etcd Quorum 规模
资料给出对照表:1 节点 quorum 为 1、容错 0;3 节点 quorum 为 2、容错 1;5 节点 quorum 为 3、容错 2;7 节点 quorum 为 4、容错 3。强调应始终使用奇数节点:4 节点时 quorum 仍为 3,只能容忍 1 个节点故障,与 3 节点相同,多出的节点只增加复杂度而不提升容错。
高可用 Inventory 写法
在 [all] 中列出各节点及其 ansible_host、ip;[kube_control_plane] 列出控制节点;[etcd] 列出 etcd 节点;[kube_node] 列出工作节点;[k8s_cluster:children] 包含 kube_control_plane 与 kube_node。资料中的示例为堆叠 etcd(etcd 运行在控制平面节点上);若使用外部 etcd,则在 [etcd] 组中使用独立节点。
API Server 负载均衡:三种方案
方案一:Worker 节点 NGINX 静态 Pod(默认)
Kubespray 默认在每个 worker 节点以静态 Pod 部署 NGINX 反向代理,kubelet 指向 https://localhost:6443,由本机代理转发到所有控制平面 API Server。
相关配置(group_vars/all/all.yml):
loadbalancer_apiserver_localhost: true
loadbalancer_apiserver_type: nginx # 或 haproxy
NGINX 配置要点:
- 使用
stream块做 L4 TCP 代理,而非http块。 least_conn:将连接分发给活跃连接最少的服务器。proxy_connect_timeout 1s:快速故障转移。proxy_timeout 10m:支持长时间 watch 流。- 仅监听
127.0.0.1:6443,不对外暴露。
静态 Pod 要点:hostNetwork: true 以便绑定回环地址;priorityClassName: system-node-critical 防止被驱逐;控制平面节点不运行 nginx-proxy(本机已有 API Server 占用 6443)。
优点:无需外部基础设施;1 秒级故障转移;每个 worker 独立容错;内部流量无额外网络跳数。缺点:没有供集群外 kubectl 使用的单一外部端点;外部客户端需直连某个控制节点 IP。控制节点增删时 worker 上的 NGINX 配置需更新(Kubespray 会自动处理)。
方案二:外部 HAProxy + 客户端侧代理(生产推荐)
外部客户端经 HAProxy 访问,worker 内部仍使用 nginx-proxy,形成两条独立故障转移路径。
group_vars/all/all.yml保持loadbalancer_apiserver_localhost: true。- 关键:在
group_vars/k8s_cluster/k8s-cluster.yml的supplementary_addresses_in_ssl_keys中加入 HAProxy 地址与 DNS 名,否则经 HAProxy 的 TLS 连接会因证书错误失败。 - 更新证书可用:
ansible-playbook cluster.yml --tags "control-plane" --limit kube_control_plane,并用openssl x509 -in /etc/kubernetes/ssl/apiserver.crt -noout -text检查 SAN。
HAProxy 示例配置使用 mode tcp、option tcp-check、balance roundrobin,后端各控制节点 check fall 3 rise 2。外部 kubeconfig 可指向 HAProxy 地址:kubectl config set-cluster cluster.local --server=https://k8s-api-srv.admin-lb.com:6443。
优点:外部访问有单一稳定端点;内部流量独立容错;HAProxy 故障不影响集群内部;两个独立故障域。缺点:需要额外的 HAProxy 基础设施(理想情况配合 keepalived 实现 HAProxy 自身高可用);需记得更新证书 SAN;需维护两层负载均衡。
方案三:外部 LB 作为单一端点(所有组件)
所有流量(外部客户端与内部组件 kubelet、kube-proxy)均经过单一外部负载均衡器,worker 上的 NGINX 静态 Pod 被移除。资料在此处内容截断,后续细节暂未提供。
故障演练要点
- 验证基线:
crictl ps | grep nginx-proxy查看代理;curl -k https://localhost:6443/healthz应返回 ok。 - 停止某控制节点 kubelet 后,worker 侧应在约 1 秒内完成故障转移,kubectl 仍可用。
- 3 节点 etcd 停 1 个仍满足 quorum,读写正常;再停第 2 个则丢失 quorum,读可能可用但写入失败(如
etcdserver: request timed out)。 - 方案二下停止 HAProxy 会使外部访问失败,但集群内部经 nginx-proxy 不受影响;HAProxy 依据
fall 3移除故障后端。 - 恢复后应启动 etcd 与 kubelet 并验证节点回到 Ready。
适用场景与限制
适用于需要可用性保障的生产集群部署、etcd 规模规划、API Server 负载均衡配置与故障转移行为理解。不适用于单节点部署与 HA 故障排查。方案三的具体配置细节在资料中未完整给出,暂未提供。