本文最后更新于:February 1, 2023 pm
                
              
            
            
              本文主要介绍如何在calico集群彻底删除calico并重新安装配置cilium组件作为集群的cni。
为什么标题写着有损迁移呢,因为在迁移过程中集群的网络会中断,所有的pod都不能正常工作。关于无损的迁移方案,此前在jet stack上面看到过有位大神发了一篇文章 ,有兴趣的可以看看。其实测试环境的话无所谓有损无损,但是生产环境不建议这么操作,实际上估计也不会有这么操作的吧。
关于本次使用的calico集群的部署过程可以参考之前的文章k8s系列13-calico部署BGP模式的高可用k8s集群 。
此前写的一些关于k8s基础知识和集群搭建的一些方案 ,有需要的同学可以看一下。
 
1、集群信息 1.1 node信息 [root@k8s-calico-master-10 -31 -90 -1  ~]# kubectl get nodes -o wide NAME                                       STATUS   ROLES           AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION              CONTAINER-RUNTIME k8s-calico-master-10 -31 -90 -1 .tinychen.io   Ready    control-plane   24d   v1.26.0   10.31.90.1    <none>        CentOS Linux 7 (Core)   6.1.4-1 .el7.elrepo.x86_64   containerd://1.6.14 k8s-calico-master-10 -31 -90 -2 .tinychen.io   Ready    control-plane   24d   v1.26.0   10.31.90.2    <none>        CentOS Linux 7 (Core)   6.1.4-1 .el7.elrepo.x86_64   containerd://1.6.14 k8s-calico-master-10 -31 -90 -3 .tinychen.io   Ready    control-plane   24d   v1.26.0   10.31.90.3    <none>        CentOS Linux 7 (Core)   6.1.4-1 .el7.elrepo.x86_64   containerd://1.6.14 k8s-calico-worker-10 -31 -90 -4 .tinychen.io   Ready    <none>          24d   v1.26.0   10.31.90.4    <none>        CentOS Linux 7 (Core)   6.1.4-1 .el7.elrepo.x86_64   containerd://1.6.14 k8s-calico-worker-10 -31 -90 -5 .tinychen.io   Ready    <none>          24d   v1.26.0   10.31.90.5    <none>        CentOS Linux 7 (Core)   6.1.4-1 .el7.elrepo.x86_64   containerd://1.6.14 k8s-calico-worker-10 -31 -90 -6 .tinychen.io   Ready    <none>          24d   v1.26.0   10.31.90.6    <none>        CentOS Linux 7 (Core)   6.1.4-1 .el7.elrepo.x86_64   containerd://1.6.14
 
1.2 ip信息 
IP 
Hostname 
 
 
10.31.90.0 
k8s-calico-apiserver.tinychen.io 
 
10.31.90.1 
k8s-calico-master-10-31-90-1.tinychen.io 
 
10.31.90.2 
k8s-calico-master-10-31-90-2.tinychen.io 
 
10.31.90.3 
k8s-calico-master-10-31-90-3.tinychen.io 
 
10.31.90.4 
k8s-calico-worker-10-31-90-4.tinychen.io 
 
10.31.90.5 
k8s-calico-worker-10-31-90-5.tinychen.io 
 
10.31.90.6 
k8s-calico-worker-10-31-90-6.tinychen.io 
 
10.33.0.0/17 
podSubnet 
 
10.33.128.0/18 
serviceSubnet 
 
10.33.192.0/18 
LoadBalancerSubnet 
 
1.3 变更目标 此次修改集群的目标是删除原有的calico,并重新安装cilium,同时开启kubeProxyReplacement和BGP路由可达。
2、删除calico 如果之前是使用yaml部署并且保留了原来的文件的,可以直接使用yaml进行卸载
kubectl delete -f tigera-operator.yaml --grace-period=0 --force kubectl delete -f custom-resources.yaml --grace-period=0 --force
 
CNI的部署可以参考官网的自建K8S部署教程 ,官网主要给出了两种部署方式 ,分别是通过Calico operator和Calico manifests来进行部署和管理calico,operator是通过deployment的方式部署一个calico的operator到集群中,再用其来管理calico的安装升级等生命周期操作。manifests则是将相关都使用yaml的配置文件进行管理,这种方式管理起来相对前者比较麻烦,但是对于高度自定义的K8S集群有一定的优势。
 
一般来说可能没卸载干净,这里我们再检查一下遗漏的资源
 kubectl get all --all-namespaces | egrep "calico|tigera"  kubectl api-resources --verbs=list --namespaced -o name | egrep "calico|tigera"  kubectl api-resources --verbs=list -o name  | egrep "calico|tigera" 
 
当出现资源无法删除的时候可以通过检查其finalizers字段来定位信息
 kubectl get serviceaccounts calico-node -n calico-system -o yaml
 
如果是finalizers中存在tigera.io/cni-protector导致资源无法被顺利删除,可以尝试修改为finalizers: []。这个问题看起来似乎是个Kubernetes上游的BUG,在github上面能找到相关的issue,主要集中在使用tigera-operator部署的calico。
This is an upstream Kubernetes (not AKS) issue. We can confirm this impacts 1.11.x - I believe this is the main upstream bug tracking this kubernetes/kubernetes#60807  however there are many bugs filed tracking this same behavior with the finalizers.
We will be unable to resolve this until a new upstream release which addresses this issue is released by the Kubernetes team. Marking as a known issue.
https://github.com/tigera/operator/issues/2031 
https://github.com/projectcalico/calico/issues/6629 
https://github.com/kubernetes/kubernetes/issues/60807 
 
最后删除所有节点上面残留的cni配置文件,然后重启集群的所有机器
 
重启机器之后会把此前calico创建的路由信息、iptables规则和cni网卡删除,当然不想重启也可以手动删除干净
 $ ip route flush proto bird $ ip link  list | grep cali | awk '{print $2}'  | cut  -c 1-15 | xargs -I {} ip link  delete {} $ modprobe -r ipip $ iptables-save | grep -i cali | iptables -F $ iptables-save | grep -i cali | iptables -X $ ipvsadm -C
 
3、部署cilium cilium的部署此前在博客里面介绍过多次了,包括overlay模式的部署、bgp模式的部署、kubeProxyReplacement模式的部署,以及eBPF的参数优化等,可以参考之前的汇总链接 。这里我们直接使用kubeProxyReplacement模式+kube-routerBGP路由可达,另外eBPF的参数优化等也在部署cilium的时候一并部署上去。
3.1 kube-proxy 因为我们这里使用cilium的kubeProxyReplacement模式,所以先删除kube-proxy
 $ kubectl get ds -n kube-system kube-proxy -o yaml > kube-proxy-ds.yaml $ kubectl get cm -n kube-system kube-proxy -o yaml > kube-proxy-cm.yaml $ kubectl -n kube-system delete ds kube-proxy daemonset.apps "kube-proxy"  deleted $ kubectl -n kube-system delete cm kube-proxy configmap "kube-proxy"  deleted $ iptables-save | grep -v KUBE | iptables-restore $ ipvsadm -C $ ip link  del kube-ipvs0
 
3.2 cilium 首先部署helm
$ wget https://get.helm.sh/helm-v3.11.0-linux-amd64.tar.gz $ tar -zxvf helm-v3.11.0-linux-amd64.tar.gz $ cp  -rp linux-amd64/helm /usr/local/bin/ $ helm version version.BuildInfo{Version:"v3.11.0" , GitCommit:"472c5736ab01133de504a826bd9ee12cbe4e7904" , GitTreeState:"clean" , GoVersion:"go1.18.10" }
 
然后添加repo
$ helm repo add cilium https://helm.cilium.io/"cilium"  has been added to your repositories $ helm repo list NAME    URL cilium  https://helm.cilium.io/
 
最后安装cilium和hubble
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 SEED=$(head  -c12 /dev/urandom | base64  -w0) helm install cilium cilium/cilium --version 1.12.6 \ 	--namespace kube-system \ 	--set  k8sServiceHost=10.31.90.0 \ 	--set  k8sServicePort=8443 \ 	--set  kubeProxyReplacement=strict \ 	--set  tunnel=disabled \ 	--set  ipam.mode=kubernetes \ 	--set  ipv4NativeRoutingCIDR=10.33.0.0/17 \ 	--set  lbExternalClusterIP=true  \ 	--set  enableIPv4Masquerade=false  \ 	--set  enableIPv6Masquerade=false  \ 	--set  ipam.operator.clusterPoolIPv4PodCIDRList=10.33.0.0/17 \ 	--set  ipam.operator.clusterPoolIPv4MaskSize=24 \ 	--set  hubble.relay.enabled=true  \ 	--set  hubble.ui.enabled=true  \ 	--set  loadBalancer.algorithm=maglev \ 	--set  maglev.tableSize=65521 \ 	--set  maglev.hashSeed=$SEED  \ 	--set  loadBalancer.mode=hybrid \ 	--set  socketLB.hostNamespaceOnly=true  \ 	--set  loadBalancer.acceleration=native 
 
部署完成后记得检查cilium相关的各个pod是否正常,与此同时集群中因为缺少cni而变为pending或者是unknown状态的pod也会重新分配IP并变回running。
3.3 kube-router kube-router主要是用来发布BGP路由,实现podIP和loadbalancerIP的路由可达,我们先下载部署kube-router的yaml文件。
$ curl -LO https://raw.githubusercontent.com/cloudnativelabs/kube-router/v1.2/daemonset/generic-kuberouter-only-advertise-routes.yaml
 
在参数中配置bgp的peer信息,这里我添加了两个peer,分别为10.31.254.253和10.31.100.100。下面的peer-router-ips、peer-router-asns、cluster-asn需要根据自己的实际情况进行修改。
- --run-router =true  - --run-firewall =false  - --run-service-proxy =false  - --enable-cni =false  - --enable-pod-egress =false  - --enable-ibgp =true  - --enable-overlay =true  - --advertise-pod-cidr =true  - --advertise-cluster-ip =true  - --advertise-external-ip =true  - --advertise-loadbalancer-ip =true  - --bgp-graceful-restart =true  - --peer-router-ips =10.31.254.253,10.31.100.100 - --peer-router-asns =64512,64516 - --cluster-asn =64517
 
最后部署kube-router,注意带上namespace参数
$ kubectl apply -f generic-kuberouter-only-advertise-routes.yaml -n kube-system
 
部署完成后检查各节点和对应的BGP Peer路由信息是否正确。
 $ kubectl -n kube-system exec  ds/cilium -- cilium status $ kubectl -n kube-system exec  ds/cilium -- cilium node list $ kubectl -n kube-system exec  ds/cilium -- cilium service list $ kubectl -n kube-system exec  ds/cilium -- cilium endpoint list
 
cilium的各项参数检测完成之后,基本可以确定集群的网络处于正常。