k8s-單節點升級為叢集(高可用)
單master節點升級為高可用叢集
對於生產環境來說,單節點master風險太大了。 非常有必要做一個高可用的叢集,這裡的高可用主要是針對控制面板來說的,比如 kube-apiserver、etcd、kube-comtroller-manager、kube-scheduler 這幾個元件,其中 kube-controller-manager 與 kube-scheduler 元件是 kubernetes 叢集自己去實現的高可用,apiserver 和 etcd 就需要手動去搭建高可叢集了。 高可用的架構有很多,比如典型的 haproxy+keepalived架構,或者使用 nginx來做代理實現。我們這裡為了宣告如何將單 master 升級為高可用的叢集,採用相對就更簡單的 nginx 模式,當然這種模式也有一些缺點,但是足以說明高可用的實現方式了。
從上圖可以看出,我們需要在所有控制節點上安裝 nginx、keepalived服務。 來代理 apiserver,這裡我準備了2個節點作為控制平面節點: k8s-master1、k8s-master2, 這裡我預設所有節點都已經正常安裝配置好了docker, 以及節點初始化操作。
在所有節點 hosts配置檔案中新增如下內容:
$ cat /etc/hosts 127.0.0.1 api.k8s.local 192.168.166.128 k8s-master1 192.168.166.129 k8s-master2 192.168.166.130 k8s-node1 192.168.166.131 k8s-node2
1、更新證書
由於我們需要將叢集替換成高可用的叢集,那麼勢必會想到我們會用一個負載均衡器來代理 APIServer, 也就是這個負載均衡器訪問 APIServer 的時候需要能正常訪問,所以預設安裝的 APIServer 證書就需要更新,因為裡面沒有包含我們需要的地址,需要保證在 SAN 列表中包含一些額外的名稱。
首先我們一個 kubeadn 的配置檔案,如果一開始安裝叢集的時候你就是使用的配置檔案,那麼我們可以直接更新這個配置檔案,但是我們你沒有使用這個配置檔案,直接使用 kubeadm init 來安裝的叢集,那麼我們可以從叢集中獲取 kubeadm 的配置資訊來外掛一個配置檔案,因為 kubeadm 會將其配置寫入到 kube-system 名稱空間下面的名為 kubeadm-config 的 ConfigMap 中。可以直接執行如下所示的命令將該配置匯出:會生成一個 kubeadm.yam的配置檔案
$ kubectl -n kube-system get configmap kubeadm-config -o jsonpath='{.data.ClusterConfiguration}' > kubeadm.yaml
生成的kubeadm.yaml 檔案中並沒有列出額外的 SAN 資訊,我們需要新增一個新的資料,需要在 apiserver 屬性下面新增一個 certsSANs 的列表。如果你在啟動叢集的時候就使用的 kubeadm 的配置檔案,可能就已經包含 certsSANs 列表了,如果沒有我們就需要新增它,比如我們這裡要新增一個新的域名 api.k8s,local 以及 k8s-master 和 k8s-master2 這兩個主機名和IP地址 192.168,.166.128、192.168.166.129、192.168.168.100。可以新增多個IP,192.168.166.100為虛擬VIP,那麼我們需要在 apiServer 下面新增如下的所示的資料:
apiServer: certSANs: - api.k8s.local - k8s-master1 - k8s-master2 - 192.168.166.128 - 192.168.166.129 - 192.168.166.100 extraArgs: authorization-mode: Node,RBAC timeoutForControlPlane: 4m0s apiVersion: kubeadm.k8s.io/v1beta2 certificatesDir: /etc/kubernetes/pki clusterName: kubernetes controllerManager: {} dns: type: CoreDNS etcd: local: dataDir: /var/lib/etcd imageRepository: registry.aliyuncs.com/k8sxio kind: ClusterConfiguration kubernetesVersion: v1.17.11 networking: dnsDomain: cluster.local podSubnet: 10.244.0.0/16 serviceSubnet: 10.96.0.0/12 scheduler: {}
上面我只列出了 apiServer 下面新增的 certSANs 資訊,這些資訊是包括在標準的 SAN 列表之外的,所以不用擔心這裡沒有新增 kubernetes、kubernetes.default 等等這些資訊,因為這些都是標準的 SAN 列表中的。
更新完 kubeadm 配置檔案後我們就可以更新證書了,首先我們移動現有的 APIServer 的證書和金鑰,因為 kubeadm 檢測到他們已經存在於指定的位置,它就不會建立新的了。
$ mv /etc/kubernetes/pki/apiserver.{crt,key} ~
然後直接使用 kubeadm 命令生成一個新的證書:
$ kubeadm init phase certs apiserver --config kubeadm.yaml W0902 10:05:28.006627 832 validation.go:28] Cannot validate kubelet config - no validator is available W0902 10:05:28.006754 832 validation.go:28] Cannot validate kube-proxy config - no validator is available [certs] Generating "apiserver" certificate and key [certs] apiserver serving cert is signed for DNS names [ydzs-master kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local api.k8s.local k8s-master1 k8s-master2] and IPs [10.96.0.1 192.168.166.128 192.168.166.129 192.168.166.100]
通過上面的命令可以檢視到 APIServer 簽名的 DNS 和 IP 地址資訊,一定要和自己的目標籤名資訊進行對比,如果缺失了資料就需要在上面的 certSANs 中補齊,重新生成證書。
該命令會使用上面指定的 kubeadm 配置檔案為 APIServer 生成一個新的證書和金鑰,由於指定的配置檔案中包含了 certSANs 列表,那麼 kubeadm 會在建立新證書的時候自動新增這些 SANs。
最後一步是重啟 APIServer 來接收新的證書,最簡單的方法是直接殺死 APIServer 的容器:
$ docker ps | grep kube-apiserver | grep -v pause 7fe227a5dd3c aa63290ccd50 "kube-apiserver --ad…" 14 hours ago Up 14 hours k8s_kube-apiserver_kube-apiserver-ydzs-master_kube-system_6aa38ee2d66b7d9b6660a88700d00581_0 $ docker kill 7fe227a5dd3c 7fe227a5dd3c
容器被殺掉後,kubelet 會自動重啟容器,然後容器將接收新的證書,一旦 APIServer 重啟後,我們就可以使用新新增的 IP 地址或者主機名來連線它了,比如我們新新增的api.k8s.local
。
驗證證書
要驗證證書是否更新我們可以直接去編輯 kubeconfig 檔案中的 APIServer 地址,將其更換為新新增的 IP 地址或者主機名,然後去使用 kubectl 操作叢集,檢視是否可以正常工作。
當然我們可以使用openssl命令去檢視生成的證書資訊是否包含我們新新增的 SAN 列表資料:
$ openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text Certificate: ...... Subject: CN=kube-apiserver ...... X509v3 Subject Alternative Name: DNS:ydzs-master, DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster.local, DNS:api.k8s.local, DNS:k8s-master1, DNS:k8s-master2, IP Address:10.96.0.1, IP Address:192.168.166.128 IP Address:192.168.166.129, IP Address:192.168.166.100 ......
如果上面的操作都一切順利,最後一步是將上面的叢集配置資訊儲存到叢集的 kubeadm-config 這個 ConfigMap 中去,這一點非常重要,這樣以後當我們使用 kubeadm 來操作叢集的時候,相關的資料不會丟失,比如升級的時候還是會帶上 certSANs 中的資料進行簽名的。
$ kubeadm config upload from-file --config kubeadm.yaml
# 如果上面命令報錯,可以直接編輯修改 新增需要的內容即可
$ kubectl -n kube-system edit configmap kubeadm-config
使用上面的命令儲存配置後,我們同樣可以用下面的命令來驗證是否儲存成功了:
$ kubectl -n kube-system get configmap kubeadm-config -o yaml
更新 APIServer 證書的名稱在很多場景下都會使用到,比如在控制平面前面新增一個負載均衡器,或者新增新的 DNS 名稱或 IP 地址來使用控制平面的端點,所以掌握更新叢集證書的方法也是非常有必要的。
2、部署 nginx + keepalived 高可用負載均衡器
Kubernetes作為容器集群系統,通過健康檢查+重啟策略實現了Pod故障自我修復能力,通過排程演算法實現將Pod分散式部署,並保持預期副本數,根據Node失效狀態自動在其他Node拉起Pod,實現了應用層的高可用性。
針對Kubernetes叢集,高可用性還應包含以下兩個層面的考慮:Etcd資料庫的高可用性和Kubernetes Master元件的高可用性。 而kubeadm搭建的K8s叢集,Etcd只起了一個,存在單點,所以我們這裡會獨立搭建一個Etcd叢集。
Master節點扮演著總控中心的角色,通過不斷與工作節點上的Kubelet和kube-proxy進行通訊來維護整個叢集的健康工作狀態。如果Master節點故障,將無法使用kubectl工具或者API做任何叢集管理。
Master節點主要有三個服務kube-apiserver、kube-controller-manager和kube-scheduler,其中kube-controller-manager和kube-scheduler元件自身通過選擇機制已經實現了高可用,所以Master高可用主要針對kube-apiserver元件,而該元件是以HTTP API提供服務,因此對他高可用與Web伺服器類似,增加負載均衡器對其負載均衡即可,並且可水平擴容。
kube-apiserver高可用架構圖:
- Nginx是一個主流Web服務和反向代理伺服器,這裡用四層實現對apiserver實現負載均衡。
- Keepalived是一個主流高可用軟體,基於VIP繫結實現伺服器雙機熱備,在上述拓撲中,Keepalived主要根據Nginx執行狀態判斷是否需要故障轉移(偏移VIP),例如當Nginx主節點掛掉,VIP會自動繫結在Nginx備節點,從而保證VIP一直可用,實現Nginx高可用。
注:為了節省機器,這裡與K8s master節點機器複用。也可以獨立於k8s叢集之外部署,只要nginx與apiserver能通訊就行。
2.1 安裝軟體包(主/備)
yum install epel-release -y
yum install nginx keepalived -y
2.2 Nginx配置檔案(主/備一樣)
cat > /etc/nginx/nginx.conf << "EOF" user nginx; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; include /usr/share/nginx/modules/*.conf; events { worker_connections 1024; } # 四層負載均衡,為兩臺Master apiserver元件提供負載均衡 stream { log_format main '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent'; access_log /var/log/nginx/k8s-access.log main; upstream k8s-apiserver { server 192.168.166.128:6443; # Master1 APISERVER IP:PORT server 192.168.166.129:6443; # Master2 APISERVER IP:PORT } server { listen 16443; # 由於nginx與master節點複用,這個監聽埠不能是6443,否則會衝突 proxy_pass k8s-apiserver; } } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; server { listen 80 default_server; server_name _; location / { } } } EOF
2.3 keepalived配置檔案(Nginx Master)
cat > /etc/keepalived/keepalived.conf << EOF global_defs { notification_email { [email protected] [email protected] [email protected] } notification_email_from [email protected] smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id NGINX_MASTER } vrrp_script check_nginx { script "/etc/keepalived/check_nginx.sh" } vrrp_instance VI_1 { state MASTER interface ens33 # 修改為實際網絡卡名 virtual_router_id 51 # VRRP 路由 ID例項,每個例項是唯一的 priority 100 # 優先順序,備伺服器設定 90 advert_int 1 # 指定VRRP 心跳包通告間隔時間,預設1秒 authentication { auth_type PASS auth_pass 1111 } # 虛擬IP virtual_ipaddress { 192.168.166.100/24 } track_script { check_nginx } } EOF
- vrrp_script:指定檢查nginx工作狀態指令碼(根據nginx狀態判斷是否故障轉移)
- virtual_ipaddress:虛擬IP(VIP)
準備上述配置檔案中檢查nginx執行狀態的指令碼:
cat > /etc/keepalived/check_nginx.sh << "EOF" #!/bin/bash count=$(ss -antp |grep 16443 |egrep -cv "grep|$$") if [ "$count" -eq 0 ];then exit 1 else exit 0 fi EOF chmod +x /etc/keepalived/check_nginx.sh
2.4 keepalived配置檔案(Nginx Backup)
cat > /etc/keepalived/keepalived.conf << EOF global_defs { notification_email { [email protected] [email protected] [email protected] } notification_email_from [email protected] smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id NGINX_BACKUP } vrrp_script check_nginx { script "/etc/keepalived/check_nginx.sh" } vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 51 # VRRP 路由 ID例項,每個例項是唯一的 priority 90 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.166.100/24 } track_script { check_nginx } } EOF
準備上述配置檔案中檢查nginx執行狀態的指令碼:
cat > /etc/keepalived/check_nginx.sh << "EOF" #!/bin/bash count=$(ss -antp |grep 16443 |egrep -cv "grep|$$") if [ "$count" -eq 0 ];then exit 1 else exit 0 fi EOF chmod +x /etc/keepalived/check_nginx.sh
注:keepalived根據指令碼返回狀態碼(0為工作正常,非0不正常)判斷是否故障轉移。
2.5 啟動並設定開機啟動
systemctl daemon-reload
systemctl start nginx
systemctl start keepalived
systemctl enable nginx
systemctl enable keepalived
2.6 檢視keepalived工作狀態
[root@k8s-master1 install]# ip add |grep ens33 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 inet 192.168.166.128/24 brd 192.168.166.255 scope global noprefixroute ens33 inet 192.168.166.100/24 scope global secondary ens33
可以看到,在ens33網絡卡綁定了192.168.31.88 虛擬IP,說明工作正常。
2.7 Nginx+Keepalived高可用測試
關閉主節點Nginx,測試VIP是否漂移到備節點伺服器。
在Nginx Master執行 pkill nginx
在Nginx Backup,ip addr命令檢視已成功繫結VIP。
啟動成功後 apiserver 的負載均衡地址就成了https://192.168.166.100:16443
。然後我們將 kubeconfig 檔案中的 apiserver 地址替換成負載均衡器的地址。
# 修改 kubelet 配置 $ vi /etc/kubernetes/kubelet.conf ...... server: https://192.168.166.100:16443 name: kubernetes ...... $ systemctl restart kubelet # 修改 controller-manager $ vi /etc/kubernetes/controller-manager.conf ...... server: https://192.168.166.100:16443 name: kubernetes ...... # 重啟 $ docker kill $(docker ps | grep kube-controller-manager | \ grep -v pause | cut -d' ' -f1) # 修改 scheduler $ vi /etc/kubernetes/scheduler.conf ...... server: https://192.168.166.100:16443 name: kubernetes ...... # 重啟 $ docker kill $(docker ps | grep kube-scheduler | grep -v pause | \ cut -d' ' -f1)
然後更新 kube-proxy
$ kubectl -n kube-system edit cm kube-proxy ...... kubeconfig.conf: |- apiVersion: v1 kind: Config clusters: - cluster: certificate-authority: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt server: https://api.k8s.local:8443 name: default ......
當然還有 kubectl 訪問叢集的~/.kube/config
檔案也需要修改。
3、更新控制面板
由於我們現在已經在控制平面的前面添加了一個負載平衡器,因此我們需要使用正確的資訊更新此 ConfigMap。(您很快就會將控制平面節點新增到叢集中,因此在此ConfigMap中擁有正確的資訊很重要。)
首先,使用以下命令從 ConfigMap 中獲取當前配置:
$ kubectl -n kube-system get configmap kubeadm-config -o jsonpath='{.data.ClusterConfiguration}' > kubeadm.yaml
# 或者直接編輯新增
$ kubectl -n kube-system edit configmap kubeadm-config
然後在當前配置檔案裡面裡面新增controlPlaneEndpoint
屬性,用於指定控制面板的負載均衡器的地址。
$ vi kubeadm.yaml
apiVersion: v1
data:
ClusterConfiguration: |
apiServer:
certSANs:
- api.k8s.local
- k8s-master1
- k8s-master2
- 192.168.166.128
- 192.168.166.129
- 192.168.166.100
extraArgs:
authorization-mode: Node,RBAC
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controlPlaneEndpoint: 192.168.166.100:16443 # 新增改配置
controllerManager: {}
......
然後需要在kube-public
名稱空間中更新cluster-info
這個 ConfigMap,該名稱空間包含一個Kubeconfig 檔案,該檔案的server:
一行指向單個控制平面節點。只需使用kubectl -n kube-public edit cm cluster-info
更新該server:
行以指向控制平面的負載均衡器即可。
$ kubectl -n kube-public edit cm cluster-info ...... server: https://192.168.166.100:16443 name: "" ...... $ kubectl cluster-info Kubernetes master is running at https://192.168.166.100:16443 KubeDNS is running at https://api.k8s.local:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy KubeDNSUpstream is running at https://api.k8s.local:8443/api/v1/namespaces/kube-system/services/kube-dns-upstream:dns/proxy Metrics-server is running at https://api.k8s.local:8443/api/v1/namespaces/kube-system/services/https:metrics-server:/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
更新完成就可以看到 cluster-info 的資訊變成了負載均衡器的地址了。
新增控制平面
接下來我們來新增額外的控制平面節點,首先使用如下命令來將叢集的證書上傳到叢集中,供其他控制節點使用:
$ kubeadm init phase upload-certs --upload-certs I0903 15:13:24.192467 20533 version.go:251] remote version is much newer: v1.19.0; falling back to: stable-1.17 W0903 15:13:25.739892 20533 validation.go:28] Cannot validate kube-proxy config - no validator is available W0903 15:13:25.739966 20533 validation.go:28] Cannot validate kubelet config - no validator is available [upload-certs] Storing the certificates in Secret "kubeadm-certs" in the "kube-system" Namespace [upload-certs] Using certificate key: e71ef7ede98e49f5f094b150d604c7ad50f125279180a7320b1b14ef3ccc3a34
上面的命令會生成一個新的證書金鑰,但是隻有2小時有效期。由於我們現有的叢集已經執行一段時間了,所以之前的啟動 Token 也已經失效了(Token 的預設生存期為24小時),所以我們也需要建立一個新的 Token 來新增新的控制平面節點:
$ kubeadm token create --print-join-command --config kubeadm.yaml W0903 15:29:10.958329 25049 validation.go:28] Cannot validate kube-proxy config - no validator is available W0903 15:29:10.958457 25049 validation.go:28] Cannot validate kubelet config - no validator is available kubeadm join 192.168.166.100:16443 --token f27w7m.adelvl3waw9kqdhp --discovery-token-ca-cert-hash sha256:6917cbf7b0e73ecfef77217e9a27e76ef9270aa379c34af30201abd0f1088c34
上面的命令最後給出的提示是新增 node 節點的命令,我們這裡要新增控制平面節點就要使用如下所示的命令:
$ kubeadm join <DNS CNAME of load balancer>:<lb port> \ --token <bootstrap-token> \ --discovery-token-ca-cert-hash sha256:<CA certificate hash> \ --control-plane --certificate-key <certificate-key>
獲得了上面的新增命令過後,登入到 ydzs-master2 節點進行相關的操作,在 ydzs-master2 節點上安裝軟體:
$ yum install -y kubeadm-1.19.0 kubelet-1.19.0 kubectl-1.19.0
要加入控制平面,我們可以先拉取相關映象:
$ kubeadm config images pull --image-repository registry.aliyuncs.com/k8sxio
然後執行上面生成的 join 命令,將引數替換後如下所示:
$ kubeadm join 192.168.166.100:16443 \ --token f27w7m.adelvl3waw9kqdhp \ --discovery-token-ca-cert-hash sha256:6917cbf7b0e73ecfef77217e9a27e76ef9270aa379c34af30201abd0f1088c34 \ --control-plane --certificate-key e71ef7ede98e49f5f094b150d604c7ad50f125279180a7320b1b14ef3ccc3a34 [preflight] Running pre-flight checks [preflight] Reading configuration from the cluster... [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml' [preflight] Running pre-flight checks before initializing the new control plane instance [preflight] Pulling images required for setting up a Kubernetes cluster [preflight] This might take a minute or two, depending on the speed of your internet connection [preflight] You can also perform this action in beforehand using 'kubeadm config images pull' [download-certs] Downloading the certificates in Secret "kubeadm-certs" in the "kube-system" Namespace [certs] Using certificateDir folder "/etc/kubernetes/pki" [certs] Generating "apiserver-kubelet-client" certificate and key [certs] Generating "apiserver" certificate and key [certs] apiserver serving cert is signed for DNS names [ydzs-master2 kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local api.k8s.local api.k8s.local ydzs-master2 ydzs-master3] and IPs [10.96.0.1 10.151.30.70 10.151.30.11 10.151.30.70 10.151.30.71] [certs] Generating "front-proxy-client" certificate and key [certs] Generating "etcd/healthcheck-client" certificate and key [certs] Generating "etcd/server" certificate and key [certs] etcd/server serving cert is signed for DNS names [ydzs-master2 localhost] and IPs [10.151.30.70 127.0.0.1 ::1] [certs] Generating "etcd/peer" certificate and key [certs] etcd/peer serving cert is signed for DNS names [ydzs-master2 localhost] and IPs [10.151.30.70 127.0.0.1 ::1] [certs] Generating "apiserver-etcd-client" certificate and key [certs] Valid certificates and keys now exist in "/etc/kubernetes/pki" [certs] Using the existing "sa" key [kubeconfig] Generating kubeconfig files [kubeconfig] Using kubeconfig folder "/etc/kubernetes" [endpoint] WARNING: port specified in controlPlaneEndpoint overrides bindPort in the controlplane address [kubeconfig] Writing "admin.conf" kubeconfig file [kubeconfig] Writing "controller-manager.conf" kubeconfig file [kubeconfig] Writing "scheduler.conf" kubeconfig file [control-plane] Using manifest folder "/etc/kubernetes/manifests" [control-plane] Creating static Pod manifest for "kube-apiserver" W0903 15:55:08.444989 4353 manifests.go:214] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC" [control-plane] Creating static Pod manifest for "kube-controller-manager" W0903 15:55:08.457787 4353 manifests.go:214] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC" [control-plane] Creating static Pod manifest for "kube-scheduler" W0903 15:55:08.459829 4353 manifests.go:214] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC" [check-etcd] Checking that the etcd cluster is healthy ...... This node has joined the cluster and a new control plane instance was created: * Certificate signing request was sent to apiserver and approval was received. * The Kubelet was informed of the new secure connection details. * Control plane (master) label and taint were applied to the new node. * The Kubernetes control plane instances scaled up. * A new etcd member was added to the local/stacked etcd cluster. To start administering your cluster from this node, you need to run the following as a regular user: mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config Run 'kubectl get nodes' to see this node join the cluster.
檢視etcd
$ cat /etc/kubernetes/manifests/etcd.yaml ...... - --initial-cluster=k8s-master2=https://192.168.166.129:2380,k8s-master1=https://192.168.166.128:2380 - --initial-cluster-state=existing ......
檢視叢集是否正常:
[root@k8s-master2 ~]# kubectl get node NAME STATUS ROLES AGE VERSION k8s-master1 Ready master 4h29m v1.19.0 k8s-master2 Ready master 3h47m v1.19.0 k8s-node1 Ready <none> 4h15m v1.19.0 k8s-node2 Ready <none> 4h14m v1.19.0
這裡我們就可以看到 k8s-master1、k8s-master2 2個節點變成了 master 節點,我們也就完成了將單 master 升級為多 master 的高可用叢集了。
最後負載均衡訪問測試:
找K8s叢集中任意一個節點,使用curl檢視K8s版本測試,使用VIP訪問:
$ curl -k https://192.168.166.100:16443/version { "major": "1", "minor": "20", "gitVersion": "v1.20.0", "gitCommit": "e87da0bd6e03ec3fea7933c4b5263d151aafd07c", "gitTreeState": "clean", "buildDate": "2021-02-18T16:03:00Z", "goVersion": "go1.15.8", "compiler": "gc", "platform": "linux/amd64" }
可以正確獲取到K8s版本資訊,說明負載均衡器搭建正常。該請求資料流程:curl -> vip(nginx) -> apiserver
通過檢視Nginx日誌也可以看到轉發apiserver IP:
$ tail /var/log/nginx/k8s-access.log -f 192.168.166.130 192.168.166.129:6443 - [13/Jun/2021:15:06:15 +0800] 200 423 192.168.166.130 192.168.166.128:6443 - [13/Jun/2021:15:06:15 +0800] 200 423 192.168.166.130 192.168.166.128:6443 - [13/Jun/2021:15:06:15 +0800] 200 423 192.168.166.130 192.168.166.129:6443 - [13/Jun/2021:15:06:15 +0800] 200 423 192.168.166.130 192.168.166.129:6443 - [13/Jun/2021:15:06:15 +0800] 200 423