# Ubuntu 20.04安装Kubernetes高可用集群 很久没有折腾Kubernetes了,最近刚好手上有资源,可以够部署一个简单的集群,于是就利用起来了。这里采用的安装方式是通过Kubeadm来安装高可用集群。 ## 1 版本信息 首先,物理服务器条件: ``` Intel(R) Xeon(R) Gold 6138 CPU @ 2.00GHz x 2 Sockets 共80 vCPU: NUMA node0 CPU(s): 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78 NUMA node1 CPU(s): 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59,61,63,65,67,69,71,73,75,77,79 内存共196G,其中128G分配为1G大小的HugePage内存. 磁盘共786G. 主机操作系统版本:Ubuntu 18.04 5.4.0-42-generic #46~18.04.1-Ubuntu SMP Fri Jul 10 07:21:24 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux ``` 基于上述资源条件,创建虚机时做如下分配: | 虚机名称 | Controller-0 | Controller-1 | Controller-2 | Node-0 | Node-1 | Node-2 | | -- |:--:|:--:|:--:|:--:|:--:| --: | | `CPU` | 4 | 4 | 4 | 16 | 16 | 16 | | `内存` | 8G | 8G | 8G | 16G | 16G | 16G | | `磁盘` | 64G | 64G | 64G | 64G | 64G | 64G | | `角色` | Controller | Controller | Controller | Node | Node | Node | 虚机部署就是通过virt-install和virsh来安装的KVM QEMU虚机,所有虚机都用HugePage内存,并做了CPU静态绑定,这里不对细节做过多陈述。 虚机上安装的操作系统为: Ubuntu 20.04 5.8.0-55-generic #62~20.04.1-Ubuntu SMP Wed Jun 2 08:55:04 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux 安装的Kubernetes版本为v1.21.1. 使用的Docker版本为: Docker version 20.10.7, build f0df350. ## 2 安装过程 ### 2.1 Kubernetes集群网络规划 ![Local Picture](/images/k8s_network.jpg "Local Picture") - 高可用集群的Service地址使用10.164.128.x/24网段的地址,在3个Controller上部署haproxy和keepalived来实现Service的高可用。 - Kubernetes的默认k8s网络是192.168.100.x/24网段,基于Calico部署实施。跨worker node度Pod间通信是通过Calico网络进行的。 - Data Network是用于高性能数据网络的。基于Multus CNI配置Pod支持多网络平面,Data Network可以是Flannel,MACVLAN等普通网络,也可以是SRIOV的高性能网络。 ### 2.2 VM系统环境准备 #### 2.2.1 配置系统环境 首先,确认Ubuntu 20.04已经升级到最新版本。通过“sudo apt upgrade -y”之后,确认内核版本统一为一个版本,如: ```markdown cifangzi@controller-0:~$ uname -a Linux controller-0 5.8.0-55-generic #62~20.04.1-Ubuntu SMP Wed Jun 2 08:55:04 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux ``` 然后,在所有VM系统里修改/etc/hostname和/etc/hosts文件添加主机名,如: ```markdown cifangzi@controller-0:~$ cat /etc/hostname controller-0 cifangzi@controller-0:~$ cat /etc/hosts ... 10.164.128.188 vip.cluster.local 10.164.128.180 controller-0 10.164.128.181 controller-1 10.164.128.182 controller-2 10.164.128.183 node-0 10.164.128.184 node-1 10.164.128.185 node-2 10.164.128.187 node-3 ... ``` 这里10.164.128.188 vip.cluster.local作为API Server的高可用虚地址,后面安装时需要用到。修改后重启确认生效。 最后,设置环境依赖,kubeadm依赖br-netfilter以及对应设置,需要如下配置: ```markdown cat < /dev/null ``` 最后,安装Docker程序: ```markdown sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io ``` Docker安装完成之后,还需要进行配置,配置Docker使用systemd作为cgroup driver,具体如下: ```markdown sudo mkdir /etc/docker cat <&2 exit 1 } curl --silent --max-time 2 --insecure https://localhost:${APISERVER_DEST_PORT}/ -o /dev/null || errorExit "Error GET https://localhost:${APISERVER_DEST_PORT}/" if ip addr | grep -q ${APISERVER_VIP}; then curl --silent --max-time 2 --insecure https://${APISERVER_VIP}:${APISERVER_DEST_PORT}/ -o /dev/null || errorExit "Error GET https://${APISERVER_VIP}:${APISERVER_DEST_PORT}/" fi ``` 再创建haproxy的配置文件/etc/haproxy/haproxy.cfg: ```markdown # /etc/haproxy/haproxy.cfg #--------------------------------------------------------------------- # Global settings #--------------------------------------------------------------------- global log /dev/log local0 log /dev/log local1 notice daemon #--------------------------------------------------------------------- # common defaults that all the 'listen' and 'backend' sections will # use if not designated in their block #--------------------------------------------------------------------- defaults mode http log global option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.0/8 option redispatch retries 1 timeout http-request 10s timeout queue 20s timeout connect 5s timeout client 20s timeout server 20s timeout http-keep-alive 10s timeout check 10s #--------------------------------------------------------------------- # apiserver frontend which proxys to the control plane nodes #--------------------------------------------------------------------- frontend apiserver bind *:8443 mode tcp option tcplog default_backend apiserver #--------------------------------------------------------------------- # round robin balancing for apiserver #--------------------------------------------------------------------- backend apiserver option httpchk GET /healthz http-check expect status 200 mode tcp option ssl-hello-chk balance roundrobin server srv1 10.164.128.180:6443 check server srv2 10.164.128.181:6443 check server srv3 10.164.128.182:6443 check # [...] ``` 这里配置了backend apiserver地址为准备安装的3个Controller的地址。 然后通过如下命令安装Kubernetes: ```markdown sudo kubeadm init --upload-certs --config ./kubeadm_config.yml ``` P.S.因为Kubnertes不支持Swap,所以在安装Kubernetes之前关闭系统的Swap。 https://github.com/kubernetes/kubeadm/issues/610 可以通过修改/etc/fstab注释掉Swap相关配置后重启动方式来关闭Swap。 如果顺利的话,至此,第一个Controller节点基本安装完成。 ```markdown cifangzi@controller-0:~$ kubectl get pods -A NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-558bd4d5db-6zvpw 0/1 Pending 0 11m kube-system coredns-558bd4d5db-kb2bh 0/1 Pending 0 11m kube-system etcd-controller-0 1/1 Running 0 11m kube-system haproxy-controller-0 1/1 Running 0 11m kube-system keepalived-controller-0 1/1 Running 0 11m kube-system kube-apiserver-controller-0 1/1 Running 0 11m kube-system kube-controller-manager-controller-0 1/1 Running 0 11m kube-system kube-proxy-2tg9m 1/1 Running 0 11m kube-system kube-scheduler-controller-0 1/1 Running 0 11m ``` 在安装其它Controller节点和worker节点之前,需要先安装Calico才能打通跨节点Pod间的通信。这里选择使用Helm来安装Calico。所以,先安装Helm: ```markdown curl https://baltocdn.com/helm/signing.asc | sudo apt-key add - echo "deb https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list sudo apt-get update sudo apt-get install helm ``` 在如下链接下载Calico Helm安装包,然后安装Calico: ```markdown https://docs.projectcalico.org/getting-started/kubernetes/helm helm install calico tigera-operator-v3.19.1-2.tgz ``` 安装完Calico之后,会多出如下Pod: ```markdown calico-system calico-kube-controllers-7f58dbcbbd-blg4t 1/1 Running 0 20m calico-system calico-node-tfqdf 1/1 Running 0 20m calico-system calico-typha-8d6bdd5d5-fzjpn 1/1 Running 0 20m tigera-operator tigera-operator-86c4fc874f-g5t9d 1/1 Running 1 20m ``` ### 2.3.3 安装另外两个控制节点 第一个控制节点安装完成时,会打印一些信息,提示安装其它控制节点和worker节点的命令,如其它控制节点安装的命令: ```markdown kubeadm join vip.cluster.local:8443 --token llcqaz.lnhg7qwpyieb85y1 \ --discovery-token-ca-cert-hash sha256:3d057e4477f58e7f99cefcf3eeae39e19f9c7058ff7431742fda6c1910e7b3d8 \ --control-plane --certificate-key d2be6f1c641cd6244d3a62a57d4c6545dd89b9631a1ace54b57916fc5ebd4478 ``` 因为这里配置了haproxy和keepalived作为高可用的方式,所以,还需要添加haproxy和keepalived的Pod。 按照按照第一个控制节点的方式,先创建haproxy和keepalived的配置文件,修改keepalived的配置文件中VRRP的角色为SLAVE,创建keepalived用到的track脚本。然后再创建haproxy和keepalived的yaml文件,并拷贝到/etc/kubernetes/manifests/。通过如下命令重启kubelet后即可: ```markdown sudo systemctl restart kubelet ``` 查看节点状态,如下: ```markdown cifangzi@controller-0:~$ kubectl get nodes NAME STATUS ROLES AGE VERSION controller-0 Ready control-plane,master 22h v1.21.1 controller-1 Ready control-plane,master 21h v1.21.1 ``` 此时,coredns的状态应该都是running,如下: ```markdown kube-system coredns-558bd4d5db-k8h55 1/1 Running 0 20h kube-system coredns-558bd4d5db-svp75 1/1 Running 0 20h ``` 可以用相同方法,创建第三个控制节点。 ### 2.3.4 安装worker节点 worker节点比较容易安装,按照之前第一个节点按照时的提示命令,可以直接安装。如下: ```markdown kubeadm join vip.cluster.local:8443 --token llcqaz.lnhg7qwpyieb85y1 \ --discovery-token-ca-cert-hash sha256:3d057e4477f58e7f99cefcf3eeae39e19f9c7058ff7431742fda6c1910e7b3d8 ``` 按同样方法安装其它worker节点。安装后查看Pod和节点状态: ```markdown cifangzi@controller-0:~$ kubectl get pods -A NAMESPACE NAME READY STATUS RESTARTS AGE calico-system calico-kube-controllers-7f58dbcbbd-blg4t 1/1 Running 0 20h calico-system calico-node-d94vp 1/1 Running 2 20h calico-system calico-node-jt269 1/1 Running 2 20h calico-system calico-node-n2rjj 1/1 Running 2 20h calico-system calico-node-p49lm 1/1 Running 0 20h calico-system calico-node-pnq4z 1/1 Running 0 20h calico-system calico-node-tfqdf 1/1 Running 0 20h calico-system calico-typha-8d6bdd5d5-fzjpn 1/1 Running 0 20h calico-system calico-typha-8d6bdd5d5-gtbsw 1/1 Running 0 20h calico-system calico-typha-8d6bdd5d5-tnjcz 1/1 Running 0 20h kube-system coredns-558bd4d5db-k8h55 1/1 Running 0 20h kube-system coredns-558bd4d5db-svp75 1/1 Running 0 20h kube-system etcd-controller-0 1/1 Running 0 20h kube-system etcd-controller-1 1/1 Running 0 20h kube-system etcd-controller-2 1/1 Running 0 20h kube-system haproxy-controller-0 1/1 Running 0 20h kube-system haproxy-controller-1 1/1 Running 0 20h kube-system haproxy-controller-2 1/1 Running 0 20h kube-system keepalived-controller-0 1/1 Running 0 20h kube-system keepalived-controller-1 1/1 Running 0 20h kube-system keepalived-controller-2 1/1 Running 0 20h kube-system kube-apiserver-controller-0 1/1 Running 0 20h kube-system kube-apiserver-controller-1 1/1 Running 0 20h kube-system kube-apiserver-controller-2 1/1 Running 0 20h kube-system kube-controller-manager-controller-0 1/1 Running 1 20h kube-system kube-controller-manager-controller-1 1/1 Running 0 20h kube-system kube-controller-manager-controller-2 1/1 Running 0 20h kube-system kube-proxy-5pwws 1/1 Running 0 20h kube-system kube-proxy-b2qrg 1/1 Running 0 20h kube-system kube-proxy-c22tz 1/1 Running 0 20h kube-system kube-proxy-hnd7s 1/1 Running 0 20h kube-system kube-proxy-pkdkp 1/1 Running 0 20h kube-system kube-proxy-tnbmj 1/1 Running 0 20h kube-system kube-scheduler-controller-0 1/1 Running 1 20h kube-system kube-scheduler-controller-1 1/1 Running 0 20h kube-system kube-scheduler-controller-2 1/1 Running 0 20h tigera-operator tigera-operator-86c4fc874f-g5t9d 1/1 Running 1 20h cifangzi@controller-0:~$ kubectl get nodes NAME STATUS ROLES AGE VERSION controller-0 Ready control-plane,master 22h v1.21.1 controller-1 Ready control-plane,master 21h v1.21.1 controller-2 Ready control-plane,master 21h v1.21.1 node0 Ready 21h v1.21.1 node1 Ready 21h v1.21.1 node2 Ready 21h v1.21.1 ``` ## 2.4 安装Multus CNI 安装Multus CNI也比较简单,通过git clone Multus对应的源码,然后安装即可。 ```markdown git clone https://github.com/k8snetworkplumbingwg/multus-cni.git cd multus-cni cat ./images/multus-daemonset.yml | kubectl apply -f - ``` 至此,高可用的Kubernetes集群安装完成。