K8s 运维系列 | 第 17 天:高可用集群——etcd 与控制平面 HA 部署

K8s 运维 第17天

在生产环境中,单台 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 上也能”睡得安稳”。

微信二维码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片快捷回复

    暂无评论内容