美團集群調度系統HULK技術演進
- 2019 年 10 月 3 日
- 筆記
本文根據美團基礎架構部/彈性策略團隊負責人塗揚在2019 QCon(全球軟體開發大會)上的演講內容整理而成。本文涉及Kubernetes集群管理技術,美團相關的技術實踐可參考此前發布的《美團點評Kubernetes集群管理實踐》。
一、背景
HULK是美團的容器集群管理平台。在HULK之前,美團的在線服務大部分部署都是在VM上,在此期間,我們遇到了很大的挑戰,主要包括以下兩點:
- 環境配置資訊不一致:部分業務線下驗證正常,但線上驗證卻不正常。
- 業務擴容流程長:從申請機器、資源審核到服務部署,需要5分鐘才能完成。
因為美團很多業務都具有明顯的高低峰特性,大家一般會根據最高峰的流量情況來部署機器資源,然而在業務低峰期的時候,往往用不了那麼多的資源。在這種背景下,我們希望打造一個容器集群管理平台來解決上述的痛點問題,於是HULK項目就應運而生了。
HULK平台包含容器以及彈性調度系統,容器可以統一運行環境、提升交付效率,而彈性調度可以提升業務的資源利用率。在漫威里有個叫HULK的英雄,在情緒激動的時候會變成“綠巨人”,情緒平穩後則恢復人身,這一點跟我們容器的”彈性伸縮“特性比較相像,所以我們的系統就取名為”HULK“。
總的來講,美團HULK的演進可以分為1.0和2.0兩個階段,如下圖所示:
在早期,HULK 1.0是基於OpenStack演進的一個集群調度系統版本。這個階段工作的重點是將容器和美團的基礎設施進行融合,比如打通CMDB系統、公司內部的服務治理平台、發布平台以及監控平台等等,並驗證容器在生產環境的可行性。2018年,基礎架構部將底層的OpenStack升級為容器編排標準Kubernetes,然後我們把這個版本稱之為HULK 2.0,新版本還針對在1.0運營過程中遇到的一些問題,對系統專門進行了優化和打磨,主要包括以下幾個方面:
- 進一步打磨了彈性策略和調度系統。
- 構建了一站式容器運營平台。
- 對基礎系統軟體進行加強,自研內核,提升安全隔離能力。
截止發稿時,美團生產環境超過1萬個應用在使用容器,容器數過10萬。
二、HULK2.0集群調度系統總體架構圖
上圖中,最上層是集群調度系統對接的各個平台,包括服務治理、發布平台、測試部署平台、CMDB系統、監控平台等,我們將這些系統打通,業務就可以無感知地從VM遷移到容器中。其中:
- 容器彈性:可以讓接入的業務按需使用容器實例。
- 服務畫像:負責應用運行情況的搜集和統計,如CPU/IO使用、服務高峰期、上下游等資訊,為彈性伸縮、調度系統提供支援。
- 容器編排和鏡像管理:負責對實例進行調度與應用實例構建。
最底層的HULK Agent是我們在每個Node上的代理程式。此前,在美團技術團隊官方部落格上,我們也分享過底層的鏡像管理和容器運行時相關內容,參見《美團容器技術研發實踐》一文。而本文將重點闡述容器編排(調度系統)和容器彈性(彈性伸縮平台),以及團隊遇到的一些問題以及對應的解決方案,希望對大家能有所啟發。
三、調度系統痛點、解法
3.1 業務擴縮容異常
痛點:集群運維人員排查成本較高。
為了解決這個問題,我們可以先看一下調度系統的簡化版架構,如下圖所示:
可以看到,一次擴縮容請求基本上會經歷以下這些流程:
a. 用戶或者上層系統發起擴縮容請求。 b. 擴縮容組件從策略配置中心獲取對應服務的配置資訊。 c. 將對應的配置資訊提交到美團自研的一個API服務(擴展的K8s組件),然後K8s各Master組件就按照原生的工作流程開始Work。 d. 當某個實例調度到具體的Node上的時候,開始通過IP分配服務獲取對應的Hostname和IP。 e. Container-init是一號進程,在容器內部拉起各個Agent,然後啟動應用程式。針對已經標準化接入的應用,會自動進行服務註冊,從而承載流量。
而這些模組是由美團內部的不同同學分別進行維護,每次遇到問題時,就需要多個同學分別核對日誌資訊。可想而知,這種排查問題的方式的成本會有多高。
解法:類似於分散式調用鏈中的traceId,每次擴縮容會生成一個TaskId,我們在關鍵鏈路上進行打點的同時帶上TaskId,並按照約定的格式統一接入到美團點評日誌中心,然後在可視化平台HULK Portal進行展示。
落地效果:
- 問題排查提效:之前排查類似問題,多人累計耗時平均需要半個小時。目前,1個管理員通過可視化的介面即可達到分鐘級定位到問題。
- 系統瓶頸可視化:全鏈路上每個時段的平均耗時資訊一覽無遺。
3.2 業務訂製化需求
痛點:每次業務的特殊配置都可能變更核心鏈路程式碼,導致整體系統的靈活性不夠。
具體業務場景如下:
- 業務希望能夠去設置一些系統參數,比如開啟swap,設置memlock、ulimit等。
- 環境變數配置,比如應用名、ZooKeeper地址等。
解法:建設一體化的調度策略配置中心,通過調度策略配置中心,可訂製化調度規則。
- 實例基本配置,比如業務想給機器加Set化、泳道標識。
- 實例的擴展配置:如部分業務,比如某些服務想將實例部署在包含特定硬體的宿主機,會對核心業務有N+1的容災需求,並且還需要將實例部署在不同的IDC上。
- 相同配置的應用可以創建一個組,將應用和組進行關聯。
在策略配置中心,我們會將這些策略進行Manifest組裝,然後轉換成Kubernetes可識別的YAML文件。
落地效果:實現了平台自動化配置,運維人員得到解放。
3.3 調度策略優化
接下來,介紹一下Kubernetes調度器Scheduler的默認行為:它啟動之後,會一直監聽ApiServer,通過ApiServer去查看未Bind的Pod列表,然後根據特定的演算法和策略選出一個合適的Node,並進行Bind操作。具體的調度策略分為兩個階段:Predicates預選階段和Priorities打分階段。
Predicates 預選階段(一堆的預選條件):PodFitsResources檢查是否有足夠的資源(比如CPU、記憶體)來滿足一個Pod的運行需求,如果不滿足,就直接過濾掉這個Node。
Priorities 打分階段(一堆的優先順序函數):
- LeastRequested:CPU和記憶體具有相同的權重,資源空閑比越高的節點得分越高。
- BalancedResourcesAllocation:CPU和記憶體使用率越接近的節點得分越高。
將以上優先順序函數算出來的值加權平均算出來一個得分(0-10),分數越高,節點越優。
痛點一:當集群達到3000台規模的時候,一次Pod調度耗時5s左右(K8s 1.6版本)。如果在預選階段,當前Node不符合過濾條件,依然會判斷後續的過濾條件是否符合。假設有上萬台Node節點,這種判斷邏輯便會浪費較多時間,造成調度器的性能下降。
解法:當前Node中,如果遇到一個預選條件不滿足(比較像是短路徑原則),就將這個Node過濾掉,大大減少了計算量,調度性能也得到大幅提升。
成效:生產環境驗證,提升了40%的性能。這個方案目前已經成為社區1.10版本默認的調度策略,技術細節可以參考GitHub上的PR。
痛點二:資源利用率最大化和服務SLA保障之間的權衡。
解法:我們基於服務的行為數據構建了服務畫像系統,下圖是我們針對某個應用進行服務畫像後的樹圖展現。
調度前:可以將有調用關係的Pod設置親和性,競爭相同資源的Pod設置反親和性,相同宿主機上最多包含N個核心應用。 調度後:經過上述規則調度後,在宿主機上如果依然出現了資源競爭,優先保障高優先順序應用的SLA。
3.4 重編排問題
痛點:
(1)容器重啟/遷移場景:
- 容器和系統盤的資訊丟失。
- 容器的IP變更。
(2)驅逐場景:Kubelet會自動殺死一些違例容器,但有可能是非常核心的業務。
解法:
(1)容器重啟/遷移場景:
- 新增Reuse策略,保留原生重啟策略(Rebuild)。
- 訂製化CNI插件,基於Pod標識申請和復用IP。
(2)關閉原生的驅逐策略,通過外部組件來做決策。
四、彈性伸縮平台痛點、解法
彈性伸縮平台整體架構圖如下:
註:Raptor是美團點評內部的大監控平台,整合了CAT、Falcon等監控產品。
在彈性伸縮平台演進的過程中,我們主要遇到了以下5個問題。
4.1 多策略決策不一致
如上圖所示,一個業務配置了2條監控策略和1條周期策略:
- 監控策略:當某個指標(比如QPS、CPU)超過閾值上限後開始擴容,低於閾值下限後開始縮容。
- 周期策略:在某個固定的時間開始擴容,另外一個固定的時間開始縮容。
早期的設計是各條策略獨自決策,擴容順序有可能是:縮5台、縮2台、擴10台,也有可能是:擴10台、縮5台、縮2台,就可能造成一些無效的擴縮行為。
解法:增加了一個聚合層(或者把它稱之為策略協商層),提供一些聚合策略:默認策略(多擴少縮)和權重策略(權重高的來決策擴縮行為),減少了大量的無效擴縮現象。
4.2 擴縮不冪等
如上圖所示,聚合層發起具體擴縮容的時候,因之前採用的是增量擴容方式,在一些場景下會出現頻繁擴縮現象。比如,原先12台,這個時候彈性伸縮平台告訴調度系統要擴容8台,在返回TaskId的過程中超時或保存TaskId失敗了,這個時候彈性伸縮平台會繼續發起擴容8台的操作,最後導致服務下有28台實例(不冪等)。
解法:採用按目標擴容方式,直接告訴對端,希望能擴容到20台,避免了短時間內的頻繁擴縮容現象。
4.3 線上程式碼多版本
如上圖所示,一個業務線上有30台機器,存在3個版本(A、B、C)。之前我們彈性擴容的做法是採用業務構建的最新鏡像進行擴容,但在實際生產環境運行過程中卻遇到問題。比如一些業務構建的最新鏡像是用來做小流量測試的,本身的穩定性沒有保障,高峰期擴容的時候會提升這個版本在線上機器中的比例,低峰期的時候又把之前穩定版本給縮容了,經過一段時間的頻繁擴縮之後,最後線上遺留的實例可能都存在問題。
解法:基於約定優於配置原則,我們採用業務的穩定鏡像(採用灰度發布流程將線上所有實例均覆蓋過一遍的鏡像,會自動標記為穩定鏡像)進行擴容,這樣就比較好地解決了這個問題。
4.4 資源保障問題
如上圖所示,存量中有2個服務,一個需要擴容20台,一個需要擴容15台,這個時候如果新接入一個服務,同一時間需要擴容30台,但是資源池只剩餘50台實例了。這個時候就意味著,誰先擴容誰就可以獲得資源保障,後發起的請求就無法獲得資源保障。
解法:
(1)存量資源水位檢測:當存量資源的使用水位超過閾值的時候,比如達到80%的時候會有報警,告訴我們需要做資源補充操作。 (2)增量服務彈性資源預估:如果這個服務通過預判演算法評估,接入之後可能會導致存量服務的擴容得不到保障,則拒絕或者補充資源後,再讓這個業務接入。
4.5 端到端時效問題
如圖所示,我們的分鐘級監控時延(比如1:00:00~1:01:00的監控數據,大概需要到1:01:10後可將採集到的所有數據聚合完成)是70s+,調度鏈路時延是30s+,整體需要上100s+,在生產環境的業務往往會比較關注擴容時延。
解法:監控系統這塊已經建設秒級監控功能。基於這些做法都屬於後驗性擴容,存在一定的延遲性,目前我們也在探索基於歷史行為數據進行服務預測,在監控指標達到擴容閾值前的1~2分鐘進行提前擴容。
五、經驗總結
技術側:
- 開源產品“本土化”: 原生的Kubernetes需要和內部已有的基礎設施,如服務樹、發布系統、服務治理平台、監控系統等做融合,才能更容易在公司內進行落地。
- 調度決策:增量的調度均使用新策略來進行規範化,存量的可採用重調度器進行治理。
- 彈性伸縮:公有雲在彈性伸縮這塊是沒有SLA保障的,但是做內部私有雲,就需要做好擴容成功率、端到端時延這兩塊的SLA保障。
業務側:
- 業務遷移:建設了全自動化遷移平台,幫助業務從VM自動遷移到容器,極大地降低了因遷移而帶來的人力投入。
- 業務成本:使用HULK可較好地提升業務運維效率(HULK具備資源利用率更高、彈性擴容、一鍵擴容等特點),降低了業務成本。
作者簡介
塗揚,美團點評技術專家,現任基礎架構部彈性策略團隊負責人。
招聘資訊
美團點評基礎架構團隊誠招高級、資深技術專家,Base北京、上海。我們致力於建設美團點評全公司統一的高並發高性能分散式基礎架構平台,涵蓋資料庫、分散式監控、服務治理、高性能通訊、消息中間件、基礎存儲、容器化、集群調度等基礎架構主要的技術領域。歡迎有興趣的同學投送簡歷到 [email protected](郵件標題註明:基礎架構部彈性策略團隊)