kubernetes叢集內排程與負載均衡

zxhyxwwu 發表於 2020-11-21

kubernetes負載均衡包括叢集外負載均衡和叢集內負載均衡,專業術語叫南北流量和東西流量,本文主要講述叢集內負載均衡(東西流量)。本文第一部分會講述kubernetes元件總覽,第二部分會講述kuber-scheduler是什麼,第三部分會講述kuber-scheduler核心概念,第四部分會講述kuber-scheduler是如何實現負載均衡排程的,最後一部分會講述kuber-scheduler的高可用選舉機制,在講到高可用和分部署叢集leader選舉時,會對知識點做適當遷移應用,引申一下。

一、Kubernetes元件總覽

1、kubectl:命令列方式操作Kubernetes API Server

2、client-go:程式設計式客戶端

3、kube-apiserver:暴露資源組/資源版本/資源

4、kube-controller-manager(高可用):管理節點(Node)、Pod副本、服務、端點(Endpoint)、名稱空間(Namespace)、服務賬戶(ServiceAccount)、資源定額(ResourceQuota)等

5、kube-scheduler(高可用):監控Pod資源物件和Node資源物件,為一個Pod資源物件找到合適的節點並在該節點上執行。

6、kubelet:接收、處理、上報kube-apiserver元件下發的任務

7、kube-proxy:監控kube-apiserver的服務和端點資源變化,並通過iptables/ipvs等配置負載均衡器,為一組Pod提供統一的TCP/UDP流量轉發和負載均衡功能。

二、什麼是kube-scheduler

kube-scheduler用來監控Pod資源物件和Node資源物件,為一個Pod資源物件找到合適的節點並在該節點上執行。在整個系統中承擔了“承上啟下”的重要功能,“承上”是指它負責接收Controller Manager建立的新Pod,為其安排一個落腳的“家”——目標Node;“啟下”是指安置工作完成後,目標Node上的kubelet服務程式接管後繼工作,負責Pod生命週期中的“下半生”。

三、kube-scheduler核心概念

1、優先順序與搶佔機制

Pod資源物件實現了兩種機制,包括優先順序(Priority)與搶佔(Preempt)機制。通過Pod資源物件的優先順序可控制kube-scheduler的排程決策,被驅逐走的低優先順序的Pod資源物件會重新進入排程佇列並等待再次選擇合適的節點Node。在生產環境中,可以對不同業務進行分級,重要業務可擁有高優先順序策略,以提升重要業務的可用性。

搶佔機制的搶佔演算法函式的執行流程如下:

(1)、判斷當前Pod資源物件是否有資格搶佔其他Pod資源物件所在的節點。

(2)、從預選排程失敗的節點中嘗試找到能夠排程成功的節點列表(潛在的節點列表)。

(3)、從潛在的節點列表中嘗試找到能夠搶佔成功的節點列表(驅逐的節點列表)。

(4)、從驅逐的節點列表中選擇一個節點用於最終被搶佔的節點(被搶佔節點)。

(5)、獲取被搶佔節點上的所有NominatedPods列表。

需要注意的是,當叢集面對資源短缺的壓力時,高優先順序的Pod將依賴於排程程式搶佔低優先順序的Pod的方式進行排程,這樣可以優先保證高優先順序的業務執行,因此建議不要禁用搶佔機制。

kube-scheduler優先順序與搶佔機制的場景示例如下圖所示,在SchedulingQueue排程佇列中擁有高優先順序(HighPriority)、中優先順序(MidPriority)、低優先順序(LowPriority)3個Pod資源物件。

kubernetes叢集內排程與負載均衡

場景1:kube-scheduler排程器將待排程Pod資源物件按照優先順序順序排程到可用節點上。

場景2:當排程Pod 3資源物件時,可用節點沒有可用資源執行Pod 3。此時,Pod 3在排程佇列中處於待排程狀態。

場景3:可用節點上已經排程了Pod 2與Pod 3資源物件,當排程Pod 1時,可用節點上已經沒有資源執行Pod 1了,此時高優先順序的Pod 1將搶佔低優先順序的Pod 3,而被搶佔後的Pod 3重新進入排程佇列等待再次選擇合適的節點。

2、親和性與反親和性

(1)、NodeAffinity節點親和性支援兩種排程策略:

(a)沒有滿足條件的節點時,資源物件建立失敗並不斷重試。該策略也被稱為硬(Hard)策略。

(b)沒有滿足條件的節點時,從其他節點中選擇較優的節點。該策略也被稱為軟(Soft)模式。

(2)、PodAffinity資源物件親和性支援兩種排程策略:

(a)沒有滿足條件的節點時,資源物件建立失敗並不斷重試。該策略也被稱為硬(Hard)策略。

(b)沒有滿足條件的節點時,從其他節點中選擇較優的節點。該策略也被稱為軟(Soft)模式。

(3)、PodAntiAffinity(Pod資源物件反親和性)支援兩種排程策略:

(a)沒有滿足條件的節點時,資源物件建立失敗並不斷重試。該策略也被稱為硬(Hard)策略。

(b)沒有滿足條件的節點時,從其他節點中選擇較優的節點。該策略也被稱為軟(Soft)模式。

下面講述親和性和反親和性的使用場景。

1、節點親和性適用場景:

(1)排程到指定機房。

(2)排程到具有GPU硬體資源的節點上。

(3)排程到I/O密集型的節點上。

2、Pod物件資源親和性適用場景:

(1)排程到同一主機。

(2)排程到同一硬體叢集。

(3)排程到同一機房。

其目的就是縮短網路傳輸延時,增加效能。

3、Pod資源物件反親和性適用場景:

避免有同一標籤的Pod資源排程到同一個節點。一般用於容災,實現高可用。

這種負載均衡方式本質是7層負載均衡。

需要注意的是,因為親和性和反親和性需要大量邏輯處理,在超過百個節點的叢集,不要使用親和性和反親和性排程。

3、bind繫結機制

bind(繫結)操作是將通過排程演算法計算出來的最佳節點與Pod資源物件進行繫結,該過程是非同步操作,無須等待bind操作完成即可進入下一輪的排程週期。

此操作之後,執行Pod資源物件的工作交給繫結節點上的kubelet元件,實現啟下的承接。

四、kube-scheduler是怎樣實現搶佔式排程的

1、預設所有Pod的優先順序都為0,設定優先順序的方式是在yaml檔案裡,kind設定為  PriorityClass,value的值越高,優先順序越高。

yaml示例如下:

apiVersion: scheduling.k8s.io/v1

kind: PriorityClass

metadata:

    name: high-priority

value: 100000

globalDefault: false

description: "This priority class should be used for hello service pods only."

2、元件架構設計

kubernetes叢集內排程與負載均衡

3、元件啟動流程

kubernetes叢集內排程與負載均衡

4、元件排程流程

kubernetes叢集內排程與負載均衡

五、kuber-scheduler的高可用選舉機制

分散式叢集的高可用,都離不開選舉。

常見分散式選舉場景包括:

(1)主從,如MySQL,Redis,kafka,Zookeeper。

(2)對等,如Eureka。

常見選舉演算法原理包括:

(1)欺負演算法(最大的程式id演算法總是獲勝)。

(2)環演算法。

常見的選舉演算法包括:

(1)最簡單的選舉演算法:選舉因子包括IP地址、CPU核數、記憶體大小、自定義序列號等等。不考慮選舉過程中的異常。

(2)拜占庭將軍問題:實則是一個協議問題。

(3)Paxos演算法.

(4)Raft分散式選舉演算法。

(5)Zookeeper,ZooKeeper Atomic Broadcast(ZAB,ZooKeeper原子訊息廣播協議)。

在Kubernetes叢集中,允許同時執行多個kube-scheduler節點,其中正常工作的只有一個kube-scheduler節點(即領導者節點),其他kube-scheduler節點為候選(Candidate)節點並處於阻塞狀態。使用的選舉演算法為:建立鎖標識-簡單選舉演算法。

kube-scheduler元件在Etcd上實現分散式鎖的原理如下。

(1)分散式鎖依賴於Etcd上的一個key,key的操作都是原子操作。將key作為分散式鎖,它有兩種狀態——存在和不存在。

(2)key(分散式鎖)不存在時:多節點中的一個節點成功建立該key(獲得鎖)並寫入自身節點的資訊,獲得鎖的節點被稱為領導者節點。領導者節點會定時更新(續約)該key的資訊。

(3)key(分散式鎖)存在時:其他節點處於阻塞狀態並定時獲取鎖,這些節點被稱為候選節點。候選節點定時獲取鎖的過程如下:定時獲取key的資料,驗證資料中領導者租約是否到期,如果未到期則不能搶佔它,如果已到期則更新key並寫入自身節點的資訊,更新成功則成為領導者節點。

 

附錄參考:

1、《Kubernetes原始碼剖析》,鄭東旭

2、《Kubernetes進階實戰》,馬永亮

3、《Kubernetes權威指南:從Docker到Kubernetes實踐全接觸(第4版)》,龔正等

4、分散式選舉演算法