使用 kube-vip 管理K8S控制面高可用
(给Go开发大全
加星标)
【导读】kube-vip带你告别HAProxy、Keepallived,轻松实现k8s控制面高可用。
太长不看版
kube-vip提供了一个kubernetes原生的控制面节点高可用负载均衡,构建高可用集群时可以省去在集群外部搭建HAProxy和Keepalived的过程。
使用Kube-vip的动机
一天我读Vmware Tanzu release note时发现了这么一条:
kube-vip 替换了vSphere deployment的HAProxy负载均衡
(https://docs.vmware.com/en/VMware-Tanzu-Kubernetes-Grid/1.2/rn/VMware-Tanzu-Kubernetes-Grid-12-Release-Notes.html)
我非常好奇这个kube-vip是什么东西。我用了3节点控制面的kubeadmin自建集群验证了一下这个工具,本文是我的验证过程和结果记录。
kube-vip是什么
kube-vip(https://kube-vip.io/)是一个开源项目,它提供了kubernetes集群内部和外部的高可用和负载均衡。本文中只介绍kubernetes集群内的控制面负载均衡。
HA集群搭建
我们来对比HAProxy和kube-vip的高可用集群搭建方式。
如果不使用kube-vip、用比较传统的办法,当在一个非云环境中搭建k8s集群时,你需要预备一个硬件/软件的负载均衡,这个负载均衡后面对接多个控制面集群。开源的解决方案就是HAProxy+Keepalived。
一个典型方案是,准备两台负载均衡VM,为这两台VM配置一个VIP(virtual ip)保证冗余。在这两台机器上部署负载均衡服务,任意一台VM都可以做“负责把流量转发到k8s控制面节点上”。
这个方案所需的两台非k8s管理的VM,增加了运维成本。
再看看kube-vip的架构图:
kube-vip在控制面节点上、作为静态pod运行(也可以配置为DaemonSet),这些pod根据当前节点上的/etc/hosts
配置、使用ARP协议发现其他节点,因此我们需要在主机/etc/hosts
配置中配置好每个节点的IP地址。
你当然可以选择BGP/ARP协议构建负载均衡,但本文中我不会介绍和推荐BGP,因为这里我的目的是快速试用kube-vip功能,因此选只用了ARP协议和静态pod。
环境准备
3 控制面节点 3 工作节点
在主机上安装如下依赖:kubeadm, kubelet, kubectl和一个容器运行时。这里我用的容器运行时是containerd。
拉取kube-vip的docker镜像,在/etc/kubernetes/manifests
路径下配置好pod的yaml文件,这样k8s就能把kube-vip pod部署到每个控制面节点上。
export VIP=192.168.0.100
export INTERFACE=eth0 # 网卡
ctr image pull docker.io/plndr/kube-vip:0.3.1
ctr run --rm --net-host docker.io/plndr/kube-vip:0.3.1 vip \
/kube-vip manifest pod \
--interface $INTERFACE \
--vip $VIP \
--controlplane \
--services \
--arp \
--leaderElection | tee /etc/kubernetes/manifests/kube-vip.yaml
部署好kube-vip pod后部署kubeadm。下面是我的配置,供参考:
# 配置kubelet
cat > ~/init_kubelet.yaml <<EOF
apiVersion: kubeadm.k8s.io/v1beta2
kind: InitConfiguration
bootstrapTokens:
- token: "9a08jv.c0izixklcxtmnze7"
description: "kubeadm bootstrap token"
ttl: "24h"
nodeRegistration:
criSocket: "/var/run/containerd/containerd.sock"
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
controlPlaneEndpoint: "192.168.0.100:6443"
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: "systemd"
protectKernelDefaults: true
EOF
执行:
kubeadm init --config init_kubelet.yaml --upload-certs
安装CNI。这里使用了cilium安装,实际上用什么工具装都可以:
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
helm repo add cilium https://helm.cilium.io/
helm install cilium cilium/cilium --version 1.9.4 \
--namespace kube-system
安装完第一个控制面节点后,要让其他节点接入你这个集群。在其他的控制面节点上执行下面的命令:
kubeadm join 192.168.0.100:6443 --token hash.hash\
--discovery-token-ca-cert-hash sha256:hash \
--control-plane --certificate-key key
这样控制面节点就配置好了,对于其他工作节点,执行如下命令:
kubeadm join 192.168.0.100:6443 --token hash.hash\
--discovery-token-ca-cert-hash sha256:hash
用kubect查看节点,结果如下:
$ kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k8s-master-0 Ready control-plane,master 121m v1.20.2 192.168.0.201 <none> Ubuntu 20.04.2 LTS 5.4.0-45-generic containerd://1.4.3
k8s-master-1 Ready control-plane,master 114m v1.20.2 192.168.0.202 <none> Ubuntu 20.04.2 LTS 5.4.0-45-generic containerd://1.4.3
k8s-master-2 Ready control-plane,master 113m v1.20.2 192.168.0.203 <none> Ubuntu 20.04.2 LTS 5.4.0-45-generic containerd://1.4.3
k8s-worker-0 Ready <none> 114m v1.20.2 192.168.0.204 <none> Ubuntu 20.04.2 LTS 5.4.0-45-generic containerd://1.4.3
k8s-worker-1 Ready <none> 114m v1.20.2 192.168.0.205 <none> Ubuntu 20.04.2 LTS 5.4.0-45-generic containerd://1.4.3
k8s-worker-2 Ready <none> 112m v1.20.2 192.168.0.206 <none> Ubuntu 20.04.2 LTS 5.4.0-45-generic containerd://1.4.3
这时你的控制节点端口依然是192.168.0.100
,不依赖其他节点。
- EOF -
Go 开发大全
参与维护一个非常全面的Go开源技术资源库。日常分享 Go, 云原生、k8s、Docker和微服务方面的技术文章和行业动态。
关注后获取
回复 Go 获取6万star的Go资源库
分享、点赞和在看
支持我们分享更多好文章,谢谢!