暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

k8s高可用集群搭建

超超学堂 2021-01-10
1421

在之前的文章使用kubeadm搭建k8s集群介绍了如何搭建一个简单的单master
的k8s集群,但是在实际应用中很少使用单个master
的集群。毕竟单一master
节点挂掉整个集群也就挂掉了,因此今天就来尝试一下搭建一个高可用的k8s集群。
官方提供了2种高可用的部署方式,一种是外部
ETCD
的方式,即部署一个单独的ETCD
集群,另一种就是混合部署,ETCD
apiserver
一起部署。我们采用第二种方式部署,一是部署简单,不需要在单独部署ETCD
,另一个因素就是节约服务器。

方式1.png

方式2.png
高可用的可参考官方文档:https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/high-availability/#
另外在LB的选择上可以看文档High Availability Considerations:
https://github.com/kubernetes/kubeadm/blob/master/docs/ha-considerations.md#options-for-software-load-balancing
我选择的是keepalived和haproxy,下面正式开始。

一、 服务器规划

首先准备几台服务器,计划部署3台master
,3台keepalived
haproxy
,为了节约服务器,我将keepalived
haproxy
master
一起部署,另外准备一台服务器作为VIP
。服务器规划如下:

角色ip地址
k8s-vip172.27.0.15
k8s-master01172.27.0.17
k8s-master02172.27.0.9
k8s-master03172.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

待初始完成后有一部分日志输出,这其中有两部分内容需要我们记住:

初始化日志.png

根据日志内容我们可以看到有两个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

然后在看就发现节点全部正常了,如下图:

节点图.png

在看下系统的其他组件,在k8s-master01
执行:
1kubectl 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
都不熟悉,所以中间还是走了一些弯路,好在文档还是比较详细的,所以最终还是顺利完成了高可用集群部署。今天的学习就到这里,如果各位小伙伴有什么问题都可以找我交流哦,谢谢大家~~~


文章转载自超超学堂,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论