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