一、概述

在前面我的文章里或许网上其它材料讲高可用计划,基本上大多数运用Keepalived VIP的计划,可是这种计划并不是最佳的,还有更优的高可用计划,下面将详细介绍。假如小伙伴对k8s master Keepalived VIP的计划不了解的,能够参阅我这篇文章:Kubernetes(k8s)最新版最完整版环境布置+master高可用完成(k8sV1.24.1+dashboard+harbor)

二、架构

【云原生】无VIP稳定性和可扩展性更强的k8s高可用方案讲解与实战操作

【云原生】无VIP稳定性和可扩展性更强的k8s高可用方案讲解与实战操作

三、开端布置

1)节点信息

hostname IP 人物
local-168-182-110 192.168.182.110 master
local-168-182-111 192.168.182.110 node
local-168-182-112 192.168.182.110 node
local-168-182-113 192.168.182.113 master
local-168-182-130 192.168.182.130 master
### 2)前期预备(一切节点)
#### 1、装备hosts
“`bash
192.168.182.110 local-168-182-110
192.168.182.111 local-168-182-111
192.168.182.112 local-168-182-112
192.168.182.113 local-168-182-113
192.168.182.130 local-168-182-130
“`
#### 2、装备互信
“`bash
# 直接一向回车就行
ssh-keygen

ssh-copy-id -i ~/.ssh/id_rsa.pub root@local-168-182-110 ssh-copy-id -i ~/.ssh/id_rsa.pub root@local-168-182-111 ssh-copy-id -i ~/.ssh/id_rsa.pub root@local-168-182-112 ssh-copy-id -i ~/.ssh/id_rsa.pub root@local-168-182-113 ssh-copy-id -i ~/.ssh/id_rsa.pub root@local-168-182-130

#### 3、时刻同步
```bash
yum install chrony -y
systemctl start chronyd
systemctl enable chronyd
systemctl status chronyd
chronyc sources

4、封闭防火墙

systemctl stop firewalld
systemctl disable firewalld

5、禁用SELinux

# 暂时封闭
setenforce 0
# 永久禁用
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config

6、封闭swap

# 暂时封闭;封闭swap主要是为了功用考虑
swapoff -a
# 能够通过这个指令检查swap是否封闭了
free
# 永久封闭        
sed -ri 's/.*swap.*/#&/' /etc/fstab

7、设置bridge-nf-call-iptables

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
# 设置所需的 sysctl 参数,参数在重新发动后坚持不变
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF
# 运用 sysctl 参数而不重新发动
sudo sysctl --system

3)装置容器docker(一切节点)

# 装备yum源
cd /etc/yum.repos.d ; mkdir bak; mv CentOS-Linux-* bak/
# centos7
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
# 装置yum-config-manager装备东西
yum -y install yum-utils
# 设置yum源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 装置docker-ce版别
yum install -y docker-ce
# 发动并设置开机自启
# 设置为开机自启并现在马上发动服务 --now:马上发动服务
systemctl enable --now docker
# 检查版别号
docker --version
# 检查版别详细信息
docker version
# Docker镜像源设置
# 修正文件 /etc/docker/daemon.json,没有这个文件就创建
# 装备docker cgroup 驱动程序systemd
# 增加以下内容后,重启docker服务:
cat >/etc/docker/daemon.json<<EOF
{
   "registry-mirrors": ["http://hub-mirror.c.163.com"],
    "exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
# 加载
systemctl restart docker
# 检查
systemctl status docker

4)装备k8s yum源(一切节点)

cat > /etc/yum.repos.d/kubernetes.repo << EOF
[k8s]
name=k8s
enabled=1
gpgcheck=0
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
EOF

5)开端装置kubeadm,kubelet和kubectl(一切节点)

# 查找一切的版别,这儿挑选1.23.x版别
yum --showduplicates list kubelet
# disableexcludes=kubernetes:禁掉除了这个kubernetes之外的别的仓库
yum install -y kubelet-1.23.6 kubeadm-1.23.6 kubectl-1.23.6 --disableexcludes=kubernetes
# 设置为开机自启并现在马上发动服务 --now:马上发动服务
systemctl enable --now kubelet
# 检查状况,这儿需求等候一段时刻再检查服务状况,发动会有点慢
systemctl status kubelet
# 检查版别
kubectl version
yum info kubeadm

6)运用 kubeadm 初始化集群(第一个master节点)

最好提前把镜像下载好,这样装置快

docker pull registry.aliyuncs.com/google_containers/kube-apiserver:v1.23.6
docker pull registry.aliyuncs.com/google_containers/kube-controller-manager:v1.23.6
docker pull registry.aliyuncs.com/google_containers/kube-scheduler:v1.23.6
docker pull registry.aliyuncs.com/google_containers/kube-proxy:v1.23.6
docker pull registry.aliyuncs.com/google_containers/pause:3.6
docker pull registry.aliyuncs.com/google_containers/etcd:3.5.1-0
docker pull registry.aliyuncs.com/google_containers/coredns:v1.8.6

集群初始化

kubeadm init \
  --apiserver-advertise-address=192.168.182.110 \
  --image-repository registry.aliyuncs.com/google_containers \
  --kubernetes-version v1.23.6 \
  --control-plane-endpoint=192.168.182.110 \
  --service-cidr=10.1.0.0/16 \
  --pod-network-cidr=10.244.0.0/16 \
  --v=5
# –image-repository string:    这个用于指定从什么位置来拉取镜像(1.13版别才有的),默许值是k8s.gcr.io,咱们将其指定为国内镜像地址:registry.aliyuncs.com/google_containers
# –kubernetes-version string:  指定kubenets版别号,默许值是stable-1,会导致从https://dl.k8s.io/release/stable-1.txt下载最新的版别号,咱们能够将其指定为固定版别(v1.22.1)来跳过网络请求。
# –apiserver-advertise-address  指明用 Master 的哪个 interface 与 Cluster 的其他节点通讯。假如 Master 有多个 interface,主张清晰指定,假如不指定,kubeadm 会主动挑选有默许网关的 interface。这儿的ip为master节点ip,记得替换。
# –pod-network-cidr             指定 Pod 网络的范围。Kubernetes 支撑多种网络计划,并且不同网络计划对  –pod-network-cidr有自己的要求,这儿设置为10.244.0.0/16 是因为咱们将运用 flannel 网络计划,有必要设置成这个 CIDR。
# --control-plane-endpoint     cluster-endpoint 是映射到该 IP 的自定义 DNS 称号,这儿装备hosts映射:127.0.0.1   cluster-endpoint。 这将答应你将 --control-plane-endpoint=cluster-endpoint 传递给 kubeadm init,并将相同的 DNS 称号传递给 kubeadm join。 稍后你能够修正 cluster-endpoint 以指向高可用性计划中的负载均衡器的地址。

【云原生】无VIP稳定性和可扩展性更强的k8s高可用方案讲解与实战操作

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

检查节点信息

kubectl get nodes

【云原生】无VIP稳定性和可扩展性更强的k8s高可用方案讲解与实战操作
发现节点是NotReady状况,检查日志是因为没有装CNI网络插件,接下来就开端装置Calico 网络插件,当然也能够挑选其它网络插件。

7)装置Calico网络插件

wget https://docs.projectcalico.org/manifests/calico.yaml
kubectl apply -f calico.yaml
# 检查
kubectl get all -n kube-system|grep calico
# 等calico pod都正常了,再检查节点状况
kubectl get pods -A
kubectl get nodes

【云原生】无VIP稳定性和可扩展性更强的k8s高可用方案讲解与实战操作

8)装备IPVS(一切节点)

1、加载ip_vs相关内核模块

modprobe -- ip_vs
modprobe -- ip_vs_sh
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr

一切节点验证敞开了ipvs:

lsmod |grep ip_vs

2、装置ipvsadm东西

yum install ipset ipvsadm -y

3、编辑kube-proxy装备文件,mode修正成ipvs

kubectl edit  configmap -n kube-system  kube-proxy

4、重启kube-proxy

# 先检查
kubectl get pod -n kube-system | grep kube-proxy
# 再delete让它自拉起
kubectl get pod -n kube-system | grep kube-proxy |awk '{system("kubectl delete pod "$1" -n kube-system")}'
# 再检查
kubectl get pod -n kube-system | grep kube-proxy

9)master节点参加集群

【问题】

One or more conditions for hosting a new control plane instance is not satisfied. unable to add a new control plane instance to a cluster that doesn't have a stable controlPlaneEndpoint address

【解决】增加如下装备:

# controlPlaneEndpoint: 192.192.168.110
kubectl edit cm kubeadm-config -n kube-system

【云原生】无VIP稳定性和可扩展性更强的k8s高可用方案讲解与实战操作
开端执行下面的指令将master节点参加集群

# 在第一个master节点上执行以下获取执行指令
# 证假如过期了,能够运用下面指令生成新证书上传,这儿会打印出certificate key,后边会用到
CERT_KEY=`kubeadm init phase upload-certs --upload-certs|tail -1`
# 其中 --ttl=0 表示生成的 token 永不失效. 假如不带 --ttl 参数, 那么默许有用时刻为24小时. 在24小时内, 能够很多量约束增加 worker.
echo `kubeadm token create --print-join-command --ttl=0` " --control-plane --certificate-key $CERT_KEY --v=5"
# 拿到上面打印的指令在需求增加的节点上执行
# --control-plane 标志告诉 kubeadm join 创建一个新的操控平面。参加master有必要加这个标记
# --certificate-key ... 将导致从集群中的 kubeadm-certs Secret 下载操控平面证书并运用给定的密钥进行解密。这儿的值便是上面这个指令(kubeadm init phase upload-certs --upload-certs)打印出的key。
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

等网络插件主动装置完后,再检查节点状况

kubectl get nodes

【云原生】无VIP稳定性和可扩展性更强的k8s高可用方案讲解与实战操作

10)修正master节点指向自己apiserver

1、修正装备

cd /etc/kubernetes
# 修正/etc/kubernetes/admin.conf,/etc/kubernetes/kubelet.conf文件中的server ip改成127.0.0.1
vi /etc/kubernetes/admin.conf
vi /etc/kubernetes/kubelet.conf
# 覆盖装备
cp /etc/kubernetes/admin.conf ~/.kube/config

2、删去旧的证书,生成新证书

cd /etc/kubernetes/pki
# 先备份
mv apiserver.key apiserver.key.bak
mv apiserver.crt apiserver.crt.bak
# 运用如下指令生成,别离在三个master节点上执行
kubeadm init phase certs apiserver --apiserver-advertise-address 192.168.182.110 --apiserver-cert-extra-sans "127.0.0.1,10.1.0.1"
kubeadm init phase certs apiserver --apiserver-advertise-address 192.168.182.113 --apiserver-cert-extra-sans "127.0.0.1,10.1.0.1"
kubeadm init phase certs apiserver --apiserver-advertise-address 192.168.182.130 --apiserver-cert-extra-sans "127.0.0.1,10.1.0.1"
#  --apiserver-cert-extra-sans "127.0.0.1":设置了这个,之后参加节点验证证书阶段就不会报错了。

3、修正apiserver

kubectl -n kube-system edit cm kubeadm-config -o yaml

【云原生】无VIP稳定性和可扩展性更强的k8s高可用方案讲解与实战操作

4、修正kube-prxoy装备

kubectl edit cm kube-proxy -oyaml -n kube-system

【云原生】无VIP稳定性和可扩展性更强的k8s高可用方案讲解与实战操作
重启

kubectl delete pod -n kube-system `kubectl get pods  -n kube-system|grep kube-proxy|awk '{print $1}'`

5、重启docker和kubelet

systemctl restart docker kubelet

11)node节点上装置nginx

这儿运用nginx四层代理

mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
yum makecache
yum install epel-release
yum -y install nginx
yum -y install nginx-all-modules.noarch

装备nginx,在nginx.conf增加如下装备:

stream {                          #完成四层代理功用
    upstream kube_apiserver {            #定义集群,kube_apiserver是集群称号,可自行定义
        least_conn;# 默许调度策略是轮询,在轮询中,假如服务器down掉了,会主动剔除该服务器。
        server local-168-182-110:6443 max_fails=3 fail_timeout=30s;   #集群组是三台服务器k8s apiserver组成
        server local-168-182-113:6443 max_fails=3 fail_timeout=30s;
        server local-168-182-130:6443 max_fails=3 fail_timeout=30s;
    }
    server {                            #定义一个服务
        listen 127.0.0.1:6443;             #需求监听的端口
        proxy_pass kube_apiserver;       #调用集群
        proxy_connect_timeout 10s;					# 连接超时时刻
        proxy_timeout 300s;							# 端口坚持时刻
    }
}

12)node节点参加集群


# 在第一个master节点上执行以下获取执行指令
# 证假如过期了,能够运用下面指令生成新证书上传,这儿会打印出certificate key,后边会用到
CERT_KEY=`kubeadm init phase upload-certs --upload-certs|tail -1`
# 其中 --ttl=0 表示生成的 token 永不失效. 假如不带 --ttl 参数, 那么默许有用时刻为24小时. 在24小时内, 能够很多量约束增加 worker.
echo `kubeadm token create --print-join-command --ttl=0` " --certificate-key $CERT_KEY --v=5"
# 示例如下:
kubeadm join 127.0.0.1:6443 --token esczfh.6ckynzi6wfj8jhnk --discovery-token-ca-cert-hash sha256:bc8fb85184ed235b88afdba38f0a17976d353abb10d0739d25df452745d1eed8  --certificate-key a126867ad4d91721f157660df77cdea7862ebda8371280c3025c4cc45c23b85f --v=5

【云原生】无VIP稳定性和可扩展性更强的k8s高可用方案讲解与实战操作
修正/etc/kubernetes/kubelet.conf装备

【云原生】无VIP稳定性和可扩展性更强的k8s高可用方案讲解与实战操作
重启

systemctl restart kubelet

等网络插件主动装置完后,再检查节点状况

kubectl get nodes
kubectl get pods -A

【云原生】无VIP稳定性和可扩展性更强的k8s高可用方案讲解与实战操作

13)卸载

kubeadm reset
rm -rf /etc/kubernetes/*
rm -fr ~/.kube
rm -fr /var/lib/etcd

四、高可用毛病形式测验

1)master节点毛病模拟(一个master毛病)

# 关机192.168.182.110
showdown -h now
# 在其它master节点上检查节点状况
kubectl get nodes

【云原生】无VIP稳定性和可扩展性更强的k8s高可用方案讲解与实战操作

【定论】如上图可知,挂一个master节点不影响集群。

2)master节点毛病模拟(两个master毛病)

# 关机192.168.182.113
showdown -h now
# 在其它master节点上检查节点状况
kubectl get nodes

【云原生】无VIP稳定性和可扩展性更强的k8s高可用方案讲解与实战操作

【定论】如上图可知,挂两个master节点,整个集群不可用,还是之前说的,三个master节点只答应挂一个master节点,这儿就不细说了,能够参阅我之前的文章:【云原生】K8S master节点替换IP以及master高可用毛病模拟测验

无VIP稳定性更强的k8s高可用计划解说就先到这儿了,也是咱们现在生成环境中运用的计划,小伙伴有任何疑问,欢迎给我留言,后续会持续更新【云原生+大数据】相关的文章,请小伙伴耐心等候~