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