Kubernetes(簡稱“K8s”或者“Kube”)是一個開源的,用于管理云平臺中多個主機上的容器化的應用,K8s的目標是讓部署容器化的應用簡單并且高效,是理想的托管平臺。K8s于2015年發布,并迅速成為事實上的容器編排標準。
在相關項目中,采用麒麟云原生平臺,基于K8s調度相關的scheduler-plugins和node-feature-discovery項目深度定制開發了NUMA感知調度功能,以滿足特定客戶需求。在開發測試驗證環節,分別發現開源社區的scheduler-plugins和node-feature-discovery項目存在以下問題。
問題現象描述
scheduler-plugins是K8s調度SIG的擴展庫項目,用于增強K8s默認調度器的功能。其中,noderesourcetopology插件支持NUMA感知調度,但若某臺服務器的NUMA節點中存在未插入內存條的情況,可能會出現問題:分配給Pod的NUMA節點組合中可能包含這些無內存的節點,導致Pod無法正常運行。
node-feature-discovery是K8s另一個SIG的項目,用于收集節點硬件信息,包括NUMA拓撲信息。同樣,若某個節點的NUMA節點存在未插入內存條的情況,node-feature-discovery服務也可能無法啟動,從而無法獲取節點的NUMA拓撲信息。
問題定位
針對scheduler-plugins問題,經過定位發現:findSuitableCombination函數在選取NUMA node組合時未經過充分的考慮。如下圖所示,該函數主要是在循環檢查每一種NUMA node組合,針對具體一種NUMA node組合,首先計算組合內資源總和(下圖所標識的第一步),接著判斷該資源總和是否滿足pod資源請求(下圖所標識的第二步)。假設一種NUMA node組合為 "2,3,6",2和6的內存之和滿足pod內存請求,但是3沒有插入內存條,此時依然認為 "2,3,6"組合是滿足要求的。
針對node-feature-discovery問題,經過定位發現,GetNumaMemoryResources函數在計算服務器上的NUMA node的memory與hugepages信息時發生錯誤,該函數默認所有NUMA node都有內存條,導致遍歷計算某些未插入內存條的NUMA node的hugepages信息發生錯誤。如下圖所示:getHugepagesBytes函數計算某些未插入內存條的NUMA node的hugepages信息會發生錯誤,導致整個node-feature-discovery服務啟動失敗。
問題修復
基于上述分析及定位,麒麟軟件推出修復方案:
(1)針對scheduler-plugins問題,在循環檢查每一種NUMA node組合中,先對具體的NUMA node組合進行有效性校驗,對不存在某種資源的非法組合進行過濾,有效的組合才會進行接下來的計算。
(2)針對node-feature-discovery問題,GetNumaMemoryResources函數遍歷計算服務器上的NUMA node的memory與hugepages信息時,如果getHugepagesBytes函數返回的錯誤是文件或者目錄不存在則跳過該計算。
以上修復方案已第一時間反饋,并被CNCF社區接受。