天天看點

「雲原生」穩定性和可擴充性更強的k8s高可用方案講解與實戰操作

作者:大資料老司機

一、概述

在前面我的文章裡或者網上其它資料講高可用方案,基本上大多數使用Keepalived VIP的方案,但是這種方案并不是最佳的,還有更優的高可用方案,下面将詳細介紹。如果小夥伴對k8s master Keepalived VIP的方案不了解的,可以參考我這篇文章:「雲原生」Kubernetes(k8s)最完整版環境部署(V1.24.1)

二、架構

「雲原生」穩定性和可擴充性更強的k8s高可用方案講解與實戰操作
「雲原生」穩定性和可擴充性更強的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

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、配置互信

# 直接一直回車就行
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、時間同步

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 以指向高可用性方案中的負載均衡器的位址。
           
「雲原生」穩定性和可擴充性更強的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
           
「雲原生」穩定性和可擴充性更強的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
           
「雲原生」穩定性和可擴充性更強的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
           
「雲原生」穩定性和可擴充性更強的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
           
「雲原生」穩定性和可擴充性更強的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
           
「雲原生」穩定性和可擴充性更強的k8s高可用方案講解與實戰操作

4、修改kube-prxoy配置

kubectl edit cm kube-proxy -oyaml -n kube-system
           
「雲原生」穩定性和可擴充性更強的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
           
「雲原生」穩定性和可擴充性更強的k8s高可用方案講解與實戰操作

修改/etc/kubernetes/kubelet.conf配置

「雲原生」穩定性和可擴充性更強的k8s高可用方案講解與實戰操作

重新開機

systemctl restart kubelet
           

等網絡插件自動安裝完後,再檢視節點狀态

kubectl get nodes
kubectl get pods -A
           
「雲原生」穩定性和可擴充性更強的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
           
「雲原生」穩定性和可擴充性更強的k8s高可用方案講解與實戰操作
【結論】如上圖可知,挂一個master節點不影響叢集。

2)master節點故障模拟(兩個master故障)

# 關機192.168.182.113
showdown -h now
# 在其它master節點上檢視節點狀态
kubectl get nodes
           
「雲原生」穩定性和可擴充性更強的k8s高可用方案講解與實戰操作
【結論】如上圖可知,挂兩個master節點,整個叢集不可用,還是之前說的,三個master節點隻允許挂一個master節點,這裡就不細說了,可以參考我之前的文章:【雲原生】K8S master節點更換IP以及master高可用故障模拟測試

無VIP穩定性更強的k8s高可用方案講解就先到這裡了,也是我們目前生成環境中使用的方案,小夥伴有任何疑問,歡迎給我留言,後續會持續更新【雲原生+大資料】相關的文章,請小夥伴耐心等待~

繼續閱讀