基本参数
- 系统版本: Ubuntu 16.04.5
- 执行用户: root
- 必须的软件包及版本
ii kubeadm 1.20.4-00 amd64 Kubernetes Cluster Bootstrapping Tool
ii kubectl 1.20.4-00 amd64 Kubernetes Command Line Tool
ii kubelet 1.20.4-00 amd64 Kubernetes Node Agent
ii kubernetes-cni 0.8.7-00 amd64 Kubernetes CNI
ii docker-ce 5:18.09.9~3-0~ubuntu-xenial amd64 Docker: the open-source application container engine
ii docker-ce-cli 5:18.09.9~3-0~ubuntu-xenial amd64 Docker CLI: the open-source application container engine
ii containerd.io 1.2.6-3 前提条件
参考连接:https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/high-availability/
- 至少3个控制平面节点
- 至少3个worker节点
- 禁用所有节点的swap
- 所有节点间能互相ssh
- 所有节点有sudo权限
安装基础组件
在集群的所有节点上都要安装
- 安装docker(参考官方文档: https://docs.docker.com/engine/install/ubuntu/)
主要是安装这三个组件: docker-ce, docker-ce-cli, containerd.io - 安装k8s组件(参考官方文档: https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/)
主要是安装这三个组件: kubelet kubeadm kubectl
高可用集群拓扑选择
拓扑有两种选择,笔者认为选择第一种方案即可,部署方便,节省资源, 参考连接:https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/ha-topology/:
- 一种是“stacked etcd”, 用大白话说就是在每个控制平面节点上都起一个etcd,组成etcd集群,拓扑如下:

- 一种是“external etcd”, 用大白话说就是etcd集群是独立的,不在控制平面节点上, 拓扑如下:

负载均衡器设置
如上图所示,k8s高可用集群必须有一个负载均衡器,且需要在运行kubeadm init时就指定,有三种设置方法, 参考连接:https://github.com/kubernetes/kubeadm/blob/master/docs/ha-considerations.md#options-for-software-load-balancing
- 在控制平面节点上直接安装keepalived和haproxy服务;
- 将keepalived和haproxy作为两个容器,在控制平面节点上启动;
- 拉起一个kube-vip的容器,里面包含了keepalived和haproxy服务;
第一种方式在纯容器化部署的前提下显得不甚优雅,且当服务故障时,不如以容器的方式部署更加容易恢复,因此放弃第一种方式;
第二种方式与第一种相比,并未简便很多,还需要在/etc/kubernets/mainfest/目录下为keepalived和haproxy编写yaml文件;
第三种方式只需要拉起一个容器,且不需要写keepalived和haproxy的配置文件,看起来简便许多;
笔者首选了第三种方式,然而发现在后续步骤中(kubeadm join)会出现问题,导致别的控制平面节点无法加入集群.
因此,笔者最终选择了第二种方式
配置文件中的参数说明:
${APISERVER_DEST_PORT}负载均衡器的监听端口,需设置一个6443端口以外的端口,笔者使用16443${APISERVER_SRC_PORT}kube-apiserver的监听端口,即6443${HOST1_ID}第一个控制平面节点的主机代号${HOST1_ADDRESS}第一个控制平面节点的主机名或ip地址
在按照参考链接中的第二种方法设置好各个配置文件后,继续下面的步骤(kube init)
初始化集群
在第一个控制平面节点上运行kube init命令来初始化集群
# --control-plane-endpoint kube-vip:16443 这个选项就是负载均衡器的监听地址:端口
# --upload-certs 加上这个选项,别的控制平面节点加入集群时才能自动获取证书,否则就要手动分发证书
# kube-vip是keepalived设置的vip对应的hostname, 需要加到每个节点的/etc/hosts文件中
kubeadm init --control-plane-endpoint kube-vip:16443 --upload-certs运行成功后,记录下提示的后续步骤(kubeamd join需要的token certs等信息),并且根据提示,运行下面的命令:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
export KUBECONFIG=/etc/kubernetes/kubelet.conf然后需要安装POD CNI插件(用于k8s pod之间的通信网络),有很多种插件可选,此处用官网文档里的插件weave
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
然后查看各个pod的状态,等到所有都完全运行了再继续后面的步骤
kubectl get pod -n kube-system -w将其他控制平面节点加入集群
在其他控制平面节点上运行下面的命令,使其加入到高可用集群中去。
# --ignore-preflight-errors="DirAvailable--etc-kubernetes-manifests" 这个选项可以使/etc/kubernets/mainfest/ 目录中已有内容的节点也能通过preflight检查,运行kubeadm join命令, 因为在此目录下可能已存在负载均衡器相关的配置文件,所以需要加上该选项
kubeadm join kube-vip:16443 --token r2ni2o.y0uwovy9v2f6kgkc \
--discovery-token-ca-cert-hash sha256:709842eda6666263a9f9c9f93fe48623f85d7a94cb766b372686de12e4d5cdc9 \
--control-plane \
--certificate-key 1b587ef8f4a6a187430583e3cca23557e3781d8a9d8fa24478eee5c3858b0bf6 \
--ignore-preflight-errors="DirAvailable--etc-kubernetes-manifests"加入过程中,kube-apiserver可能多次重启,也可能导致第一个控制平面节点上的kube-apiserver多次重启, 需要多等待一会。如果运行失败的话,需要运行kubeadm reset重置该节点,如果该节点上有负载均衡器,还需要在/etc/kubernets/mainfest/目录下恢复keepalived和haproxy的yaml配置,再运行上面的kubeadm join命令重试。
加入成功后,在第一个控制平面节点上查看kube-system的pod
root@devops1ar01n01:~# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-74ff55c5b-46tgs 1/1 Running 0 20h
coredns-74ff55c5b-wc45m 1/1 Running 0 20h
etcd-devops1ar01n01 1/1 Running 2 20h
etcd-devops1ar01n02 1/1 Running 0 20h
etcd-devops1ar01n03 1/1 Running 0 20h
haproxy-devops1ar01n01 1/1 Running 4 20h
haproxy-devops1ar01n02 1/1 Running 3 20h
keepalived-devops1ar01n01 1/1 Running 0 20h
keepalived-devops1ar01n02 1/1 Running 0 20h
kube-apiserver-devops1ar01n01 1/1 Running 6 20h
kube-apiserver-devops1ar01n02 1/1 Running 6 20h
kube-apiserver-devops1ar01n03 1/1 Running 0 20h
kube-controller-manager-devops1ar01n01 1/1 Running 1 20h
kube-controller-manager-devops1ar01n02 1/1 Running 0 20h
kube-controller-manager-devops1ar01n03 1/1 Running 0 20h
kube-proxy-4br4v 1/1 Running 0 20h
kube-proxy-5p7xb 1/1 Running 0 20h
kube-proxy-wx7t9 1/1 Running 0 20h
kube-scheduler-devops1ar01n01 1/1 Running 1 20h
kube-scheduler-devops1ar01n02 1/1 Running 0 20h
kube-scheduler-devops1ar01n03 1/1 Running 0 20h
weave-net-bctkh 2/2 Running 0 20h
weave-net-nrdpj 2/2 Running 0 20h
weave-net-qc9bw 2/2 Running 0 20h
再查看集群中的节点状态
root@devops1ar01n01:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
devops1ar01n01 Ready control-plane,master 20h v1.20.4
devops1ar01n02 Ready control-plane,master 20h v1.20.4
devops1ar01n03 Ready control-plane,master 20h v1.20.4
如上输出,则控制平面节点已成功加入高可用集群。