k8s高可用部署后續:SLB


前一段時間寫了使用keepalived+haproxy部署k8s高可用集群,核心思想是利用keepalived生成vip實現主備容災,以及haproxy負載k8s-apiserver流量。k8s高可用部署:keepalived + haproxy

這種方式是自己實現了負載均衡。本文將探討在用戶已有SLB的場景下如何實現k8s高可用

SLB概念

阿里雲文檔中SLB(Server Load Balancer)介紹如下:

負載均衡基礎架構是采用集群部署,提供四層(TCP協議和UDP協議)和七層(HTTP和HTTPS協議)的負載均衡,可實現會話同步,以消除服務器單點故障,提升冗余,保證服務的穩定性。

負載均衡作為流量轉發服務,將來自客戶端的請求通過負載均衡集群轉發至后端服務器,后端服務器再將響應通過內網返回給負載均衡。

本文還涉及到SLB的一個關鍵技術限制:

在 4 層(TCP 協議)服務中,不支持添加進后端的服務器既作為 Real Server,又作為客戶端向所在的 SLB 實例發送請求。因為,返回的數據包只在服務器內部轉發,不經過負載均衡,所以通過配置在 SLB 后端的 服務器去訪問其 VIP 是不通的。

另外對於SLB的健康檢查、調度算法等最佳實踐不做探討,請查閱相關文檔。文本探討的范圍僅限於架構可行性驗證。

架構

1 keepalived+haproxy

 

由於4層SLB不支持后端服務訪問其VIP,根據kubeadm官方安裝文檔:

 

 

 

 

 

 

指定vip會發生如下超時錯誤:

[etcd] Creating static Pod manifest for local etcd in “/etc/kubernetes/manifests”

[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory “/etc/kubernetes/manifests”. This can take up to 4m0s

[kubelet-check] Initial timeout of 40s passed.

查看kubele日志:

# sudo journalctl -u kubelet.service

k8s.io/kubernetes/pkg/kubelet/kubelet.go:442: Failed to list *v1.Service: Get https://172.16.105.26:9443/api/v1/services?limit=500&resourceVersion=0: dial tcp 172.16.105.26:9443: connect: connection refused

還記得之前說的4層負載的技術限制嗎?

基於此我們出了一個比較”臟”的方案:keepalived+haproxy。安裝步驟與上一篇文章一樣,只是結果不同:

  •  這種方式還是先啟用keepalived綁定vip,此時對vip的請求屬於本地訪問,不會轉發出去,因此不會出現訪問不通的情況。
  • 三台keepalived都必須是leader, 否則只有一台能綁定vip,其他兩台還是加入不了
  • 如何使三台都是keepalived leader? 兩種方式: 1)關閉vrrp協議(阿里雲默認關閉),此時keepalived backup收不到其他節點的廣播信息,將自己設為leader; 2)用單播方式啟動keepalived

問題:

1.  這種實現方式相當於在LB的后端又實現一次LB,但是用戶請求多了一次轉發, 顯然不是一個令人滿意的方案。

2. 這種keepalived全主模式不能應用在純vip場景下(如openstack)。這種情況安裝是沒問題的,master1先綁定vip,master2,3通過vip訪問apiserver時走本地流量,由於本地apiserver:6443還未啟動,被haproxy負載到健康節點。這么做安裝是沒問題的。但是不能保證高可用。當master1 done時,子網內部訪問vip還是能找到另外兩台健康節點,但是子網外部訪問時,路由器還是會路由到master1。

2 綁定vip方式

keepalived的解決方式其實是將vip綁定三台k8s-master,使得三台主機初始化時走本地網絡,解決后端訪問不了slb的問題。那么其實我們不需要在keepalived后面再加一層haproxy,使得請求多一次轉發,更進一步,我們不需要keepalived來綁定vip,手動綁定就好了。

安裝步驟:

2.1 init k8s-master-leader

綁定vip:

# ip addr add 172.16.105.26/32 dev eth0

查詢綁定結果:

#ip a| grep eth0

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000

    inet 172.16.104.54/24 brd 172.16.104.255 scope global eth0

    inet 172.16.105.26/32 scope global eth0

kubeadm-config.yaml

apiVersion: kubeadm.k8s.io/v1beta1

kind: ClusterConfiguration

kubernetesVersion: v1.14.1

imageRepository: registry.aliyuncs.com/google_containers

networking:

  podSubnet: 10.244.0.0/16

controlPlaneEndpoint: 172.16.105.26:6443

join

sudo kubeadm init –config=kubeadm-config.yaml –experimental-upload-certs

記錄下日志中的join命令

2.2 join k8s-master-follower

分別將k8s-master-follower加入k8s-master-leader

 sudo kubeadm join 172.16.105.26:6443 –token c1d2cb.vx086ez76bpggqj5 \

    –discovery-token-ca-cert-hash sha256:bc749b4e7e75f93ea9c0055d1c6e36c814b04247ca9e5bb6168ec3a27e5693bd \

    –experimental-control-plane –certificate-key cdb31f173bf87a573217a4cd1d6e22dc1d396a4da5050e36bdec407bd2aab29d

2.3 為k8s-master-follower綁定vip

您可能注意到follower join時沒有先綁定vip。原因是follower join時需要訪問k8s-apiserver獲取證書等信息,綁定vip直接走本地,獲取失敗。而此時slb健康檢查認為k8s-master-leader是可以負載的,所以直接訪問前端slb會負載到k8s-master-leader,可以訪問k8s-apiserver。

那為什么還要為k8s-master-follower綁定vip呢?在每個k8s-master-follower請求slb時有1/3的幾率負載到自身,此時訪問不通。綁定vip后,每個k8s-master-follower訪問slb都是訪問的本機。

總結

第一篇文章講述了只有vip,沒有實際slb設備的模式下,采用keepalived+haproxy實現高可用的方式。本篇講述了依賴雲廠商SLB高可用和負載均衡時安裝k8s。方案一並不完美,通過改良后形成了方案二。當然業內肯定還有很多其他的解決方案,作者才疏學淺,還沒來得及一一拜讀。

完成本篇的同時又接到了一個新的需要:SLB不是以vip形式提供,而是域名。域名SLB當然比IP要強,大部分雲廠商負載均衡肯定不是一台設備,背后都是大規模的集群,會保證SLB服務本身的高可用。這種場景下已經不能通過綁定vip來實現,如何解決呢?敬請期待第三篇。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM