Kubernetes控制平面负载均衡工具kube-vip

一、环境规划

角色 IP 说明
master01 192.168.200.151 首个控制平面节点,执行 kubeadm init
master02 192.168.200.152 后续加入的控制平面节点
master03 192.168.200.153 后续加入的控制平面节点
VIP 192.168.200.200 kube-vip 宣告的虚拟 IP,必须未被占用
网卡 ens33 以实际 ip a 为准,VIP 必须与节点 IP 同子网

kube-vip 采用 ARP(Layer 2)模式,要求三个控制平面节点位于同一二层网络,VIP 与节点管理 IP 同子网。

二、kube-vip 核心机制

kube-vip 在控制平面高可用场景中的核心职责是:让一个虚拟 IP 始终漂移在健康的控制平面节点上,客户端只需连接这个 VIP,而不关心当前是哪台 Master 在提供服务。

1. 领导者选举

每个控制平面节点上都运行一个 kube-vip 实例。这些实例通过 Kubernetes API Server 中的 Lease 对象进行领导者选举,同一时间只有一个实例成为 Leader,并由它持有并宣告 VIP。

故障发生时,Leader 无法续约 Lease,Lease 过期后其他实例重新竞争,新 Leader 接管 VIP。

2. ARP 模式如何宣告 VIP

在 ARP 模式下,Leader 节点会把 VIP 绑定到指定网卡,并通过 免费 ARP(Gratuitous ARP) 通知网络:“这个 VIP 现在在我这里”。故障切换时,免费 ARP 能加速网络设备更新 ARP 表,缩短中断时间。

ARP 模式简单、适合同子网场景,但同一时间只有 Leader 节点持有 VIP。若需要跨子网或与路由器集成,应改用 BGP 模式。

三、前置准备

三台节点均完成以下基础配置:

# 关闭 swap、加载内核模块、开启转发(略)
# 安装 containerd,并确保使用 systemd cgroup 驱动
# 配置 Kubernetes v1.36 yum 仓库并安装组件

ARP 模式关键防御:显式设置 kubelet 的 --node-ip。
kube-vip 会把 VIP 绑定到节点网卡,kubelet 有可能误把 VIP 选为节点 InternalIP。在 yum 系统上应写入 /etc/sysconfig/kubelet:

# master01
echo 'KUBELET_EXTRA_ARGS="--node-ip=192.168.200.151"' > /etc/sysconfig/kubelet
# master02
echo 'KUBELET_EXTRA_ARGS="--node-ip=192.168.200.152"' > /etc/sysconfig/kubelet
# master03
echo 'KUBELET_EXTRA_ARGS="--node-ip=192.168.200.153"' > /etc/sysconfig/kubelet

systemctl daemon-reload
systemctl restart kubelet

四、master01:生成 kube-vip 静态 Pod 清单

这一步必须在 kubeadm init 之前完成。kube-vip 需要先于 API Server 启动,才能为 kubeadm 提供可连接的 VIP。

export VIP=192.168.200.200
export INTERFACE=ens33
export KVVERSION=v1.2.4

mkdir -p /etc/kubernetes/manifests

ctr run --rm --net-host ghcr.io/kube-vip/kube-vip:${KVVERSION} vip \
  /kube-vip manifest pod \
  --interface $INTERFACE \
  --address $VIP \
  --controlplane \
  --arp \
  --leaderElection | tee /etc/kubernetes/manifests/kube-vip.yaml

核心参数:

参数 作用
--controlplane 声明 VIP 用于控制平面高可用
--arp 使用 ARP/Layer 2 模式宣告 VIP
--leaderElection ARP 模式下必须启用,确保同一时间只有一个节点持有 VIP

仅做控制平面高可用时,不需要添加 --services 或 --enableLoadBalancer。

确认清单已生成:

ls -l /etc/kubernetes/manifests/kube-vip.yaml

五、master01:执行 kubeadm init

kubeadm init \
  --kubernetes-version=v1.36.5 \
  --control-plane-endpoint="192.168.200.200:6443" \
  --upload-certs \
  --pod-network-cidr=10.244.0.0/16

初始化时的关键顺序:

  1. kubelet 解析 /etc/kubernetes/manifests/,启动 kube-vip 静态 Pod。
  2. kube-vip 参与 Leader 选举,当选者宣告 VIP 192.168.200.200。
  3. kubelet 继续启动 kube-apiserver 等控制平面组件。
  4. kubeadm 通过已生效的 VIP 完成初始化。

初始化成功后配置 kubectl:

mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config

保存终端输出的 kubeadm join 命令,后续 master02、master03 需要使用。

六、master02 与 master03:先复制清单,再 join

顺序不能颠倒:先复制 kube-vip 清单,再执行 kubeadm join --control-plane。

在 master02 和 master03 上分别执行:

mkdir -p /etc/kubernetes/manifests
scp root@192.168.200.151:/etc/kubernetes/manifests/kube-vip.yaml /etc/kubernetes/manifests/

然后执行 join 命令:

kubeadm join 192.168.200.200:6443 \
  --token <token> \
  --discovery-token-ca-cert-hash sha256:<hash> \
  --control-plane \
  --certificate-key <certificate-key>

--certificate-key 来自 master01 kubeadm init 的输出,因为初始化时使用了 --upload-certs。如果 token 过期,可在 master01 上重新生成:

kubeadm token create --print-join-command

加入完成后,master02、master03 上的 kube-vip 实例启动并参与选举,作为 VIP 的备用接管者。

七、验证与故障切换

1. 检查节点与 kube-vip Pod

kubectl get nodes -o wide
kubectl get pods -n kube-system -l k8s-app=kube-vip -o wide

三个节点应为 Ready,kube-vip Pod 应为 Running。

2. 确认 VIP 位置

在当前持有 VIP 的节点上:

ip a show ens33 | grep 192.168.200.200

VIP 应只出现在一个节点上。

3. 验证 API Server 通过 VIP 可达

curl -k https://192.168.200.200:6443/healthz

应返回 ok。

4. 故障切换测试

记录当前持有 VIP 的节点,然后关机或重启该节点。在另一台 Master 上观察:

watch -n 2 "ip a show ens33 | grep 192.168.200.200"

ARP 模式下,VIP 漂移依赖免费 ARP 更新网络 ARP 表,通常数秒到数十秒内完成。随后验证 kubectl 在短暂中断后恢复可用。

posted @ 2021-10-22 14:25  wanghongwei-dev  阅读(783)  评论(0)    收藏  举报