常旭征,焦文彬
1(中國科學院計算機網絡信息中心,北京 100190)
2(中國科學院大學,北京 100149)
云計算經過十幾年的發展,其底層的虛擬化技術已逐漸成熟,而Docker虛擬化技術由于啟動速度快、靈活、輕便等諸多優點逐漸成為云計算領域的熱點[1].各大云計算廠商也紛紛建立了自己的Docker技術平臺[2],與此同時以Kubernetes[3]為代表的容器編排工具逐漸成為云原生的事實標準,越來越多的微服務使用Kubernetes進行部署和管理.
Kubernetes 最早來源于Google的Borg論文,理論基礎較為完善豐富,同時擴展性強、自動化程度高,其主要設計目標是使部署和管理復雜的分布式系統變得容易[3],它為每個容器分配IP,并且可以在集群中的任意位置進行訪問,從而提供了一種分布式的環境[4].
Kubernetes 由一個master節點和若干worker節點組成,master是整個Kubernetes集群中的控制節點,包括api server、kube-scheduler、controller-manager 三個組件,其中api server負責接收客戶端請求,kubescheduler負責對Kubernetes 中的原子調度單元pod進行調度,controller-manager 對Kubernetes 中的控制器進行管理,worker節點是工作節點,用來運行具體的pod.Kubernetes負責將用戶的應用打包為的異構的分布式應用程序,從而使其在一組虛擬機上可用,因此,在這種情況下要解決的一個重要的問題就是調度或放置這些容器化應用程序到一組主機上.在提交部署應用程序時,編排系統需要考慮應用程序的特定約束,盡可能充分的利用各種計算資源,提高集群的負載均衡,從而降低企業的成本[5].
Kubernetes的資源調度算法由于擴展性較好,逐漸成為國內外學者研究的熱點.以往的資源調度算法僅僅關注優選過程,對預選過程關注較少,且優選過程未考慮網絡利用率資源指標,不能很好的提高集群的負載均衡效率,且資源利用率的計算方法也較為復雜.本文對Kubernetes資源調度算法中的預選和優選過程都進行了改進,且在優選過程中使用了新的資源利用率計算方式,并且加入了網絡利用率這一新的指標,以最大程度的提高整個集群的負載均衡效率.
Kube-scheduler是Kubernetes的集群調度器,它根據用戶創建的pod 請求為pod 找到一個合適的節點運行在其上面[7],這就是調度pod的過程.Kubernetes的調度過程分為兩部分,分別是預選和優選過程.
預選過程是根據用戶提交的yaml 文件,遍歷所有node,過濾掉不符合用戶定義要求的節點,例如用戶定義的pod標簽要求使用帶有SSD 硬盤的節點,那么顯然kube-scheduler就不會把該pod調度到非SSD節點上.通過分析Kubernetes 源碼可知,其內置的部分預選函數有:Check Node Condition,即檢查節點是否正常,NoDisk Conflict,即檢測磁盤不能沖突,Pod Tolerates Node Taints,即檢查pod是否可以容忍節點上的污點等等.
優選過程則是為預選過程選擇出的每個節點打分,本文基于Least Requested Priority和Balanced Resource Allocation 兩種原始的算法進行,這兩種算法得分為[0,10]中的整數,并且每種算法都有一個權重,默認為1[8].其中Least Requested Priority的設計思想為:node上的CPU和memory 空閑比例的和越大,則當前節點得分越高,這不難理解,因為CPU和內存空閑比例越大代表當前節點可以容納更多pod,不會擠占資源占用率高的節點,有利于提高整個集群的資源利用率和負載均衡,其計算公式為:

而Balanced Resource Allocation 設計思想為計算CPU和內存利用率之間的差值,差值越小,說明CPU和內存使用越均衡,從而得分越高,其計算公式為:

其中,Rcpu代表節點上已申請的CPU 使用量與當前pod申請的CPU容量之和,Rmem代表節點上已申請的內存使用量與當前pod申請的內存容量之和,Ccpu和Cmem分別代表節點總的CPU容量和內存容量.
從以上分析可以看出,Kubernetes 默認的算法的預選過程要遍歷所有節點,當節點過多會導致預選耗時嚴重,因此可以在預選過程中只選出滿足條件的節點個數即可,而無需輪詢所有節點,因為節點的資源利用率是隨時變化的,我們關注的是集群的最終均衡效率,而不是中間的某一個狀態,輪詢所有節點后再打分并不代表最終結果最優.同時優選過程只考慮了CPU個和內存利用率,而未關注節點本身的網絡利用率,磁盤利用率等指標,而當今的互聯網應用紛繁復雜,僅靠CPU和內存指標顯然無法反應出集群的整體情況.下文將對優選過程進行改進,對節點的CPU、內存、網絡、磁盤等指標綜合考量,以改進現有的優選過程算法模型.
針對優選過程,改進的資源調度算法整體思想是合理調度pod 以提高整個集群的負載均衡效率,而對于負載均衡效率的計算,張玉芳等學者[9]在考慮節點本身性能的前提下,提出了基于負載權值的計算方法,使用該文獻的方法進行負載的計算.同時譚莉等[8]提出的考慮節點的性能的算法雖然加上了節點性能的考慮,但對于互聯網應用來說,網絡利用率也是不可忽略的因素,因此本文在原有的負載均衡計算上加入網絡利用率指標,把CPU、內存、網絡、磁盤IO 四個維度數據綜合考量計算最終得分.計算公式為:

其中,L(i)表示節點負載,S(i)表示節點性能.
L(i)的計算公式為:

其中,L(c)表示CPU 利用率,L(m)表示內存利用率,L(n)表示網絡利用率,L(d)表示磁盤利用率.
S(i)的計算公式為:

其中,n為CPU核數,S(c)表示CPU 頻率,S(m)表示內存容量,S(n)表示網絡速率,S(d)表示磁盤IO 速率.
3.2.1 獲取節點資源指標
在本實驗中,使用兩個腳本computeL.sh和computeS.sh分別統計worker節點的CPU、內存、網絡、磁盤利用率和CPU核數、內存容量、網絡速率、磁盤讀寫速率,分別表示資源利用率和節點性能.
3.2.2 實現Kubernetes自定義調度器
在Kubernetes 官方文檔中,給出了3種實現自定義調度器的方法[10]:(1)修改原有的scheduler模塊并重新編譯;(2)重新實現自己的調度器模塊;(3)實現一個稱為“scheduler extender”的調度接口,供調度器調用決策.本文使用第2種方式并根據官方例子實現一個簡易的調度器,這里假設只有兩個節點,多個節點同理,其流程如圖1所示.

圖1 自定義調度器執行流程
自定義調度器的運行邏輯為一個輪詢過程:首先獲取所有標簽為my-scheduler 并且尚未綁定節點的pod,其次在所有worker節點上分別運行computeL.sh和computeS.sh 兩個腳本獲取資源利用率和節點性能,然后計算得到每個worker節點得分,最后將當前調度的pod與得分最高的worker節點進行綁定,這個綁定過程通過向api server發送post 請求完成,從而完成最終的調度.其偽代碼如下:
Input:各個節點的CPU、內存、IO、網絡利用率及CPU核數和頻率、內存容量、網絡帶寬和磁盤容量.

其中偽代碼第4行和第5行的兩個函數computeL()和computeS()分別為根據Linux 命令獲取節點性能指標的兩個shell函數.
本實驗采用Kubernetes 1.11版本,通過虛擬機的方式部署在臺式機上,集群中共有1個master和3個worker 共4個節點,配置如表1所示.
1)用默認的調度器搭建完集群后,在集群中起35個pod,分別執行不同的任務,然后使用文獻[9]中的方法計算集群的均衡負載;2)刪除原來的pod,使用文獻[8]的資源調度算法,重新起與之前一樣的35個pod,重新計算集群的負載均衡效率;3)刪除原來的pod,使用自定義調度器,重新起與之前一樣的35個pod,重新計算集群的負載均衡效率;4)對比3次的實驗結果找出差異.其中,集群負載均衡效率計算方法為:

其中,L(avg)代表節點的平均負載,S(avg)代表節點節點平均性能,H(i)越大,說明集群負載均衡越好,從而資源調度算法也就越好.

表1 實驗環境
根據式(6)分別計算使用默認調度器、文獻[8]的調度器(記為調度器1)和本文實現的自定義調度器(記為調度器2)后集群總體的性能差異,得到對比結果如表2所示.

表2 實驗結果(單位:%)
圖2為使用默認調度器、調度器1和調度器2的情況下集群負載均衡效率柱狀圖對比,從實驗結果來看,3個worker節點的集群負載均衡效率對比默認調度器和調度器1 均有不同程度的提升,從而驗證了資源調度策略的有效性.

圖2 實驗結果
Kubernetes作為微服務架構最核心的編排工具,其默認資源調度算法的預選過程由于要遍歷所有節點,節點數量較多時比較耗時,改進的資源調度算法對預選過程做了優化,提出關注集群最終的資源利用率,而不關注中間狀態,因此無需遍歷所有節點進而提升資源調度效率.同時針對優選過程僅僅考慮了CPU和內存兩個指標,且只是pod申請的CPU和內存,并未考慮節點本身的性能指標的問題,本文在現有的資源調度算法研究基礎上,加入了除CPU、內存和磁盤外的網絡利用率和速率,并實現了自定義調度器來應用改進的資源調度算法,以期提升集群的整體負載均衡效率.最后通過實驗對比分析驗證了算法的有效性.