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
初始化时的关键顺序:
- kubelet 解析
/etc/kubernetes/manifests/,启动 kube-vip 静态 Pod。 - kube-vip 参与 Leader 选举,当选者宣告 VIP
192.168.200.200。 - kubelet 继续启动
kube-apiserver等控制平面组件。 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 在短暂中断后恢复可用。

浙公网安备 33010602011771号