在之前的文章使用kubeadm搭建k8s集群介绍了如何搭建一个简单的单master
的k8s集群,但是在实际应用中很少使用单个master
的集群。毕竟单一master
节点挂掉整个集群也就挂掉了,因此今天就来尝试一下搭建一个高可用的k8s集群。
官方提供了2种高可用的部署方式,一种是外部ETCD
的方式,即部署一个单独的ETCD
集群,另一种就是混合部署,ETCD
和apiserver
一起部署。我们采用第二种方式部署,一是部署简单,不需要在单独部署ETCD
,另一个因素就是节约服务器。
一、 服务器规划
首先准备几台服务器,计划部署3台master
,3台keepalived
和haproxy
,为了节约服务器,我将keepalived
和haproxy
和master
一起部署,另外准备一台服务器作为VIP
。服务器规划如下:
角色 | ip地址 |
---|---|
k8s-vip | 172.27.0.15 |
k8s-master01 | 172.27.0.17 |
k8s-master02 | 172.27.0.9 |
k8s-master03 | 172.27.0.8 |
二、 环境准备
这部分在每台服务器上都执行,当然有部分是没必要的,不过为了统一就都处理了。
1 设置hostname
1hostnamectl set-hostname <hostname>
2 修改hosts文件
1vi /etc/hosts
2## 添加内容
3172.27.0.17 k8s-master01
4172.27.0.9 k8s-master02
5172.27.0.8 k8s-master03
6172.27.0.15 k8s-vip
3 关闭防火墙等
1## 配置内核参数,将桥接的IPv4流量传递到iptables的链
2cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
3net.bridge.bridge-nf-call-ip6tables = 1
4net.bridge.bridge-nf-call-iptables = 1
5EOF
6## 手动加载配置文件
7sysctl --system
8## 防火墙关闭
9systemctl stop firewalld
10systemctl disable firewalld
11## 将 SELinux 设置为 permissive 模式(相当于将其禁用)
12setenforce 0
13sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
14## 关闭交换空间
15swapoff -a
16sed -i 's/.*swap.*/#&/' /etc/fstab
17## ip转发
18echo '1' > /proc/sys/net/ipv4/ip_forward
三、 安装keepalived 和 haproxy
1 安装keepalived 和 haproxy
1yum install keepalived haproxy -y
2 配置 keepalived
1cat <<EOF > /etc/keepalived/keepalived.conf
2! /etc/keepalived/keepalived.conf
3! Configuration File for keepalived
4global_defs {
5 router_id LVS_DEVEL
6}
7vrrp_script check_apiserver {
8 script "/etc/keepalived/check_apiserver.sh"
9 interval 3
10 weight -2
11 fall 10
12 rise 2
13}
14
15vrrp_instance VI_1 {
16 state ${STATE}
17 interface ${INTERFACE}
18 virtual_router_id ${ROUTER_ID}
19 priority ${PRIORITY}
20 authentication {
21 auth_type PASS
22 auth_pass ${AUTH_PASS}
23 }
24 virtual_ipaddress {
25 ${APISERVER_VIP}
26 }
27 track_script {
28 check_apiserver
29 }
30}
31
32EOF
在上面的文件中替换自己相应的内容:${STATE}
如果是主节点 则为MASTER
其他则为 BACKUP
。我这里选择k8s-master01
为MASTER
;k8s-master02
、k8s-master02
为BACKUP
;${INTERFACE}
是网络接口,即服务器网卡的,我的服务器均为eth0
;${ROUTER_ID}
这个值只要在keepalived
集群中保持一致即可,我使用的是默认值51;${PRIORITY}
优先级,在master
上比在备份服务器上高就行了。我的master
设为100,备份服务50;${AUTH_PASS}
这个值只要在keepalived
集群中保持一致即可;${APISERVER_VIP}
就是VIP
的地址,我的为:172.27.0.15。
3 配置 keepalived健康检查
在上面的配置中我们也配置健康检查的参数,比如检查间隔时间,权重等等。
创建脚本
1vi /etc/keepalived/check_apiserver.sh
2### 添加内容
3#!/bin/sh
4
5errorExit() {
6 echo "*** $*" 1>&2
7 exit 1
8}
9
10curl --silent --max-time 2 --insecure https://localhost:${APISERVER_DEST_PORT}/ -o /dev/null || errorExit "Error GET https://localhost:${APISERVER_DEST_PORT}/"
11if ip addr | grep -q ${APISERVER_VIP}; then
12 curl --silent --max-time 2 --insecure https://${APISERVER_VIP}:${APISERVER_DEST_PORT}/ -o /dev/null || errorExit "Error GET https://${APISERVER_VIP}:${APISERVER_DEST_PORT}/"
13fi
${APISERVER_VIP}
就是VIP
的地址,172.27.0.15;${APISERVER_DEST_PORT}
这个是和apiserver
交互的端口号,其实就是HAProxy
绑定的端口号,因为HAProxy
和k8s一起部署,这里做一个区分,我使用了16443,这个下面会说到。
4 配置haproxy
1# /etc/haproxy/haproxy.cfg
2#---------------------------------------------------------------------
3# Global settings
4#---------------------------------------------------------------------
5global
6 log /dev/log local0
7 log /dev/log local1 notice
8 daemon
9
10#---------------------------------------------------------------------
11# common defaults that all the 'listen' and 'backend' sections will
12# use if not designated in their block
13#---------------------------------------------------------------------
14defaults
15 mode http
16 log global
17 option httplog
18 option dontlognull
19 option http-server-close
20 option forwardfor except 127.0.0.0/8
21 option redispatch
22 retries 1
23 timeout http-request 10s
24 timeout queue 20s
25 timeout connect 5s
26 timeout client 20s
27 timeout server 20s
28 timeout http-keep-alive 10s
29 timeout check 10s
30
31#---------------------------------------------------------------------
32# apiserver frontend which proxys to the masters
33#---------------------------------------------------------------------
34frontend apiserver
35 bind *:${APISERVER_DEST_PORT}
36 mode tcp
37 option tcplog
38 default_backend apiserver
39
40#---------------------------------------------------------------------
41# round robin balancing for apiserver
42#---------------------------------------------------------------------
43backend apiserver
44 option httpchk GET /healthz
45 http-check expect status 200
46 mode tcp
47 option ssl-hello-chk
48 balance roundrobin
49 server ${HOST1_ID} ${HOST1_ADDRESS}:${APISERVER_SRC_PORT} check
上面的配置需要修改为自己的配置:${APISERVER_DEST_PORT}
这个值同上面的健康检查脚本里面的值一样,我这里使用16443;${HOST1_ID} ${HOST1_ADDRESS}:${APISERVER_SRC_PORT}
其实就是你的k8s主节点的配置,比如我的配置是:
1 ### server ${HOST1_ID} ${HOST1_ADDRESS}:${APISERVER_SRC_PORT} check
2 server k8s-master01 172.27.0.17:6443 check
3 server k8s-master02 172.27.0.9:6443 check
4 server k8s-master03 172.27.0.8:6443 check
上面的配置完成后启动keepalived
和haproxy
,并设置为自动启动。
1systemctl enable haproxy --now
2systemctl enable keepalived --now
四、安装k8s
1 安装docker
安装所需的包
1yum install -y yum-utils device-mapper-persistent-data lvm2
添加docker
国内仓库
1yum-config-manager --add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装docker
1# 最新版版本
2yum install docker-ce docker-ce-cli containerd.io
3# 指定版本
4yum install -y containerd.io-1.2.13 docker-ce-19.03.11 docker-ce-cli-19.03.11
2 配置docker
创建docker
目录
1mkdir /etc/docker
添加配置
1cat > /etc/docker/daemon.json <<EOF
2{
3 "exec-opts": ["native.cgroupdriver=systemd"],
4 "log-driver": "json-file",
5 "log-opts": {
6 "max-size": "100m"
7 },
8 "registry-mirrors": ["https://0gbs116j.mirror.aliyuncs.com","https://registry.docker-cn.com","https://mirror.ccs.tencentyun.com","https://docker.mirrors.ustc.edu.cn"],
9 "storage-driver": "overlay2",
10 "storage-opts": [
11 "overlay2.override_kernel_check=true"
12 ]
13}
14EOF
设置docker
自启动
1mkdir -p /etc/systemd/system/docker.service.d
2
3systemctl enable docker
4systemctl daemon-reload
5systemctl restart docker
3 安装kubelet、kubeadm、kubectl
配置阿里云仓库
1cat <<EOF > /etc/yum.repos.d/kubernetes.repo
2[kubernetes]
3name=Kubernetes
4baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
5enabled=1
6gpgcheck=1
7repo_gpgcheck=1
8gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
9EOF
安装kubelet
、kubeadm
、kubectl
1## 最新版本
2yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
3## 指定版本
4yum install -y kubelet-1.18.6 kubeadm-1.18.6 kubectl-1.18.6 --disableexcludes=kubernetes
kubelet
设置自启动
1systemctl enable --now kubelet
以上内容在3台master
服务器上均需要执行。
五、master初始化
关于master
初始化我选择在k8s-master01
上执行:
1kubeadm init --control-plane-endpoint "k8s-vip:16443" \
2--image-repository registry.aliyuncs.com/google_containers \
3--service-cidr=10.1.0.0/16 --pod-network-cidr=10.244.0.0/16 \
4--upload-certs | tee kubeadm-init.log
待初始完成后有一部分日志输出,这其中有两部分内容需要我们记住:
根据日志内容我们可以看到有两个join的输出,其中最面上的是
control-plane node
,即主节点的join命令,下面的则是
worker node
的join命令,一定别弄错了。
在
k8s-master01
配置环境变量。
1mkdir -p $HOME/.kube
2sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
3sudo chown $(id -u):$(id -g) $HOME/.kube/config
在k8s-master02
和k8s-master03
执行join命令,如下:
1kubeadm join k8s-vip:16443 --token j3vjyp.9namdndnyigysdp2 \
2 --discovery-token-ca-cert-hash sha256:ad6b80c857adc41cb585f5fab771a064b13c2d069090365fa1f6d4cbefb5c257 \
3 --control-plane --certificate-key a2828d4279238f976ce580977e5e113dddacd4ae0dd00903d4ebef8627ba33d1
这时候在k8s-master01
执行:
1kubectl get node
会发现都是NotReay
,接下里就配置网络组建,我这里依然使用calico
,在k8s-master01
执行:
1kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
然后在看就发现节点全部正常了,如下图:
在看下系统的其他组件,在
k8s-master01
执行:
1kubectl get pod -n kube-system -o wide
如下图:
六、最后
接下来我们需要把k8s-master01
的/etc/kubernetes/admin.conf
配置文件拷贝的其他主节点上去,当然也可以复制到普通的worker
节点,这都没什么问题,也可以加入接普通的worker
节点,因为我没买那么多服务器就没有做这一步了,理论上应该没什么问题的。需要注意的是初始化生成的证书只有两个小时的有效时间,如果证书过期的话需要在master
重新生成证书。
其实相对来讲高可用的k8s集群和之前部署的单master
部署没有很大的区别,关键其实在于keepalived
和haproxy
的安装配置,还有就是master
节点和worker
节点加入的命令稍微有一点区别。整体来看其实不复杂,但是因为自己对keepalived、haproxy
都不熟悉,所以中间还是走了一些弯路,好在文档还是比较详细的,所以最终还是顺利完成了高可用集群部署。今天的学习就到这里,如果各位小伙伴有什么问题都可以找我交流哦,谢谢大家~~~