
在生产环境中,单台 Master 节点往往是整个 Kubernetes 集群的致命单点。一旦这台节点宕机,kubectl 无法下发指令、调度器停止工作、整个集群陷入”失联”状态。本篇文章我们就从零开始,深入讲解如何构建一套高可用的 K8s 集群,重点聚焦 etcd 集群与控制平面(Control Plane)的 HA 部署。
为什么需要高可用集群
Kubernetes 的控制平面由多个组件组成:kube-apiserver、kube-controller-manager、kube-scheduler 以及 etcd。其中 etcd 是集群的”数据库”,保存了所有资源对象的状态;kube-apiserver 则是所有操作的唯一入口。当这些组件运行在单节点上时,任何硬件故障、内核崩溃或误操作都会导致整个集群不可用。
高可用集群的目标是:任意一台控制平面节点故障,集群仍然可以正常对外服务。实现这一目标的关键在于两点——etcd 的多数派仲裁(quorum)机制,以及 kube-apiserver 的无状态化与负载均衡。
etcd 的高可用原理
etcd 采用 Raft 一致性算法,一个 etcd 集群由多个成员组成,写入操作只有在超过半数成员确认后才算成功。这就是所谓的 quorum 机制。因此,一个高可用的 etcd 集群通常使用 3 个或 5 个成员:
- 3 节点:容忍 1 台故障
- 5 节点:容忍 2 台故障
需要注意的是,etcd 集群的成员数量必须是奇数,偶数成员不仅无法提升容错能力,反而会降低可用性。
控制平面组件的高可用
与 etcd 不同,kube-controller-manager 和 kube-scheduler 是通过选主(leader election)机制实现高可用的。多个副本同时启动,但只有获得锁的副本才会真正工作,其余副本处于待命状态。当主副本故障时,其他副本会通过 etcd 中的锁自动接管。
kube-apiserver 则是完全无状态的,可以水平扩展。只要将多个 apiserver 实例放在负载均衡器之后,即可实现请求的均匀分发与故障转移。
实战:使用 kubeadm 部署 HA 集群
下面我们以 3 台控制平面节点为例,演示完整的部署流程。假设节点规划如下:
| 主机名 | IP 地址 | 角色 |
|---|---|---|
| cp-1 | 10.0.0.11 | etcd + control plane |
| cp-2 | 10.0.0.12 | etcd + control plane |
| cp-3 | 10.0.0.13 | etcd + control plane |
| lb | 10.0.0.100 | 负载均衡器(VIP) |
1. 准备负载均衡器
kube-apiserver 需要前置一个负载均衡器,常见的做法是使用 HAProxy 或 Keepalived。下面是 HAProxy 的配置示例:
# 安装 haproxy
apt-get update && apt-get install -y haproxy
# 配置 /etc/haproxy/haproxy.cfg
# haproxy.cfg 关键配置
frontend k8s_api
bind 10.0.0.100:6443
mode tcp
option tcplog
default_backend k8s_apis
backend k8s_apis
mode tcp
balance roundrobin
server cp-1 10.0.0.11:6443 check
server cp-2 10.0.0.12:6443 check
server cp-3 10.0.0.13:6443 check
2. 初始化第一个控制平面节点
首先在 cp-1 上创建 kubeadm 配置文件,指定负载均衡器地址和 etcd 的堆叠部署方式:
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: v1.28.0
controlPlaneEndpoint: "10.0.0.100:6443"
networking:
podSubnet: "10.244.0.0/16"
etcd:
local:
dataDir: /var/lib/etcd
# 初始化第一个控制平面节点
kubeadm init --config kubeadm-config.yaml --upload-certs
初始化成功后,命令会输出加入其他控制平面节点的指令,其中包含 --control-plane 和 --certificate-key 参数,务必妥善保存。
3. 加入其余控制平面节点
在其他控制平面节点上执行类似命令:
kubeadm join 10.0.0.100:6443
--token <token>
--discovery-token-ca-cert-hash sha256:<hash>
--control-plane
--certificate-key <certificate-key>
4. 验证 etcd 集群状态
所有节点加入后,检查 etcd 集群健康状态:
# 在任意控制平面节点执行
kubectl -n kube-system get pods | grep etcd
ETCDCTL_API=3 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
endpoint health
# 查看 etcd 成员列表
ETCDCTL_API=3 etcdctl member list
常见问题
Q1:为什么 etcd 必须用奇数个节点?
Raft 算法要求写入获得多数派确认。3 节点集群的多数派是 2,容忍 1 台故障;而 2 节点集群的多数派也是 2,同样只能容忍 1 台故障,却多浪费了一台机器的资源。所以偶数节点没有性价比优势。
Q2:控制平面节点必须与 etcd 部署在一起吗?
不一定。etcd 可以独立部署在专用机器上(外部 etcd),也可以与控制平面堆叠部署(stacked etcd)。小规模生产环境通常采用堆叠方式以节省资源,大规模集群则推荐独立部署以便隔离故障域。
Q3:--upload-certs 参数有什么作用?
该参数会将控制平面证书上传到集群中,并通过 --certificate-key 加密传递,使新加入的控制平面节点无需手动拷贝证书即可完成认证,极大简化了多控制平面节点的加入流程。
总结
本文从原理到实践,完整梳理了 Kubernetes 高可用集群的部署思路:etcd 依靠 Raft 多数派仲裁保证数据一致性,控制平面组件依靠选主机制和无状态化实现故障转移,而负载均衡器则是多个 apiserver 的统一入口。掌握这些核心概念后,你就能在生产环境中构建出真正稳定可靠的 K8s 集群。
下期预告:第 18 天我们将深入存储进阶——CSI、动态供给与备份恢复,看看如何让有状态应用在 K8s 上也能”睡得安稳”。


















暂无评论内容