深度分析:Kubernetes調度策略
Docker是一個開源的應用容器引擎,讓開發者可以打包應用以及依賴包到一個可移植的容器中,然后發布到Linux機器上。容器使用沙箱機制,相互之間不會有任何接口,幾乎沒有性能開銷,可以很容易地在主機和數據中心中運行。
Kubernetes容器集群管理系統的主要功能包括:使用Docker對應用程序進行打包、實例化及運行;以集群的方式運行及管理跨主機的容器;解決位于不同主機之間所運行的容器之間的通信問題等等。其中,Scheduler(調度器)是Kubernetes容器集群管理系統中加載并運行的調度程序,其負責收集、統計分析容器集群管理系統中所有Node的資源使用情況,然后以此為依據將新建的Pod發送到優先級***的可用Node上去建立。
在新增Pod的過程中,調度器的調度策略被分成兩個階段:Predicates階段和Priorities階段。其中,Predicates階段回答“能不能”的問題,即能否將Pod調度到特定的Node上運行,這一階段輸出的所有滿足要求的Node將被記錄并作為第二階段的輸入。Priorities階段是回答“哪個更適合的問題”,即再次對節點進行篩選,篩選出最適合運行Pod的節點。
Predicates階段包括五個調度策略:PodFitsPorts、PodFitsResources、NoDiskConflict、 MatchNodeSelector和HostName,即需要經過上述5個Predicates的檢驗,才能確定為“能被調度到的Node”。如其中的 PodFitsPorts規則,它所評估的依據就是端口是否沖突,即檢測待調度的Pod中所有容器要用到的端口集對應的HostPort集與Node上已使用的端口是否沖突。而Priorities則是在Predicates的基礎上回答“哪個可用Node***先”的問題。
Priorities階段包括三個調度策略:LeastRequestedPriority(最少請求資源優先調度策略)、 ServiceSpreadingPriority(最小相同服務優先調度策略)和EqualPriority(平等優先調度策略)。即按照 LeastRequestedPriority、ServiceSpreadingPriority和EqualPriority三個調度策略,給 Predicates階段篩選出來的所有Node打分,并評出優先級,優先級***的Node作為Pod被調度的目的節點。
具體如下: LeastRequestedPriority的計算原則是盡量將需要新創建的Pod調度到計算資源占用比較小的Node上,這里的“計算資源”指 CPU 資源和Memory資源;ServiceSpreadingPriority的計算原則是使同一個Node上屬于相同服務的Pod數量盡量少,這樣調度的 Pod能夠盡可能地實現服務的高可用性和流量負載均衡;EqualPriority的計算原則是平等對待Predicates階段篩選出來的每一個可用 Node。目前,LeastRequestedPriority是最主要的評分依據。其計算過程如下:
遍歷所有可用Node,對每個可用Node上已經調度運行的所有Pod請求所需的Memory資源和CPU資源進行求和;
對待創建的Pod請求所需的Memory資源和CPU資源進行求和,加上S11中得出的對應的Memory和CPU的值,并以int64型的整數 totalMemory和int64型的整數totalMilliCPU進行返回;
再次遍歷所有可用Node,并計算每個可用Node的Memory資源和CPU資源的總量,并以int64型的整數capacityMemory和 int64型的整數capacityMilliCPU進行返回;
分別計算每個可用Node 的CPU得分和Memory得分;其中,CPU得分=int(((capacityMilliCPU - totalMilliCPU) * 10) / capacityMilliCPU);Memory得分= int(((capacityMemory - totalMemory) * 10) / capacityMemory);如果totalMilliCPU的值大于capacityMilliCPU或者totalMemory的值大于 capacityMemory的值,則直接返回CPU得分為0或者Memory得分為0。將得分和***的節點做為Pod的啟動節點。
Kubernetes的調度器實現了插件化,用戶可以開發自己的調度策略并以插件的形式集成到Kubernetes中,以便調度不同類型的任務。然而隨著時間的推移,由于種種因素的影響,如工作節點上資源變化、其他Pod的創建與刪除,原有已經被調度的Pod可能已經不適合調度策略了。在這種情況下,社區提出了“重調度”的概念,即控制器將某個處于運行中的Pod終止,并在不中斷服務的情況下,將此Pod重新調度到適合的節點上。