本文爲《螞蟻金服 Service Mesh 大規模落地系列》 運維篇,該系列將會從核心、RPC、消息、無線網關、控制面、安全、運維、測試等模塊對 Service Mesh 雙十一大規模落地實踐進行詳細解析。前端
Service Mesh 是螞蟻金服下一代架構的核心,也是螞蟻金服內部向雲原生演進的重要一環。本文爲 Service Mesh 系列文章的運維篇,做者:黃家琦 (花名:嘉祁),螞蟻金服運維專家,Service Mesh SRE,主要關注雲原生基礎設施、中間件及 Service Mesh 的穩定性,同時也是 Pythoner,sofa-bolt-python 做者。python
本文將主要分享大規模服務網格在螞蟻金服當前體量下落地到支撐螞蟻金服雙十一大促過程當中,運維角度所面臨的挑戰與演進。內容包括雲原生化的選擇與問題,對資源模型的挑戰,大規模下運維設施的演進,以及周邊技術風險能力的建設。git
Service Mesh 在2019年獲得了大規模的應用與落地,截止目前,螞蟻金服的 Service Mesh 數據平面 MOSN 已接入應用數百個,接入容器數量達數十萬,是目前已知的全世界最大的 Service Mesh 集羣。同時,在剛剛結束的雙十一大促中,Service Mesh 的表現也十分亮眼,RPC 峯值 QPS 達到了幾千萬,消息峯值 TPS 達到了幾百萬,且引入 Service Mesh 後的平均 RT 增加幅度控制在 0.2 ms 之內。github
Service Mesh 在軟件形態上,是將中間件的能力從框架中剝離成獨立軟件。而在具體部署上,保守的作法是以獨立進程的方式與業務進程共同存在於業務容器內。咱們在螞蟻金服內部的作法,則從開始,就選擇了擁抱雲原生。後端
業務容器內獨立進程的好處在於與傳統的部署模式兼容,易於快速上線;但獨立進程強侵入業務容器,對於鏡像化的容器更難於管理。而云原生化,則能夠將 Service Mesh 自己的運維與業務容器解耦開來,實現中間件運維能力的下沉。在業務鏡像內,僅僅保留長期穩定的 Service Mesh 相關 JVM 參數,從而僅經過少許環境變量完成與 Service Mesh 的聯結。同時考慮到面向容器的運維模式的演進,接入 Service Mesh 還同時要求業務完成鏡像化,爲進一步的雲原生演進打下基礎。安全
優 劣網絡
獨立進程架構
兼容傳統的部署模式 侵入業務容器app
改形成本低 鏡像化難於運維負載均衡
快速上線
Sidecar
面向終態 依賴 K8s 基礎設施
運維解耦 運維環境改形成本高
應用須要鏡像化改造
在接入 Service Mesh 以後,一個典型的 POD 結構可能包含多個 Sidecar:
MOSN:RPC Mesh, MSG Mesh, ...(擴展中);
其它 Sidecar;
MOSN:https://github.com/sofastack/sofa-mosn
這些 Sidecar 容器,與業務容器共享相同的網絡 Namespace,使得業務進程能夠以本地端口訪問 Service Mesh 提供的服務,保證了與保守作法一致的體驗。
咱們也在基礎設施層面同步推動了面向雲原生的改造,以支撐 Service Mesh 的落地。
首先是在螞蟻金服內部推動了全面的鏡像化,咱們完成了內部核心應用的全量容器的鏡像化改造。改造點包括:
基礎鏡像層面增長對於 Service Mesh 的環境變量支撐;
應用 Dockerfile 對於 Service Mesh 的適配;
推動解決了存量先後端分離管理的靜態文件的鏡像化改造;
推動了大量使用前端區塊分發的應用進行了推改拉的改造;
大批量的 VM 模式的容器升級與替換;
除了業務鏡像層面的改造,Sidecar 模式還須要業務容器所有跑在 POD 上,來適應多容器共享網絡。因爲直接升級的開發和試錯成本很高,咱們最終選擇將接入 Service Mesh 的 數百個應用的數萬個非 K8s 容器,經過大規模擴縮容的方式,所有更換成了 K8s PODs。
通過這兩輪改造,咱們在基礎設施層面同步完成了面向雲原生的改造。
Sidecar 模式的帶來一個重要的問題,如何分配資源。
最初的資源設計基於內存沒法超賣的現實。咱們作了一個假設:
MOSN 的基本資源佔用與業務選擇的規格同比例這一假設。
CPU 和 Memory 申請與業務容器相應比例的額外資源。這一比例最後設定在了 CPU 1/4,Memory 1/16。
此時一個典型 Pod 的資源分配以下圖示:
這一方式帶來了兩個問題:
螞蟻金服已經實現了業務資源的 Quota 管控,但 Sidecar 並不在業務容器內,Service Mesh 容器成爲了一個資源泄漏點;
業務不少樣,部分高流量應用的 Service Mesh 容器出現了嚴重的內存不足和 OOM 狀況;
不止於此,爲了快速支撐 Service Mesh 在非雲環境的鋪開,上線了原地接入 Service Mesh。而原地接入 Service Mesh 的資源沒法額外分配,在內存不能超賣的狀況下,採起了二次分割的分配方式。此時的 POD 內存資源被切分爲1/16內存給 Sidecar,與15/16給業務容器。除了以上兩個問題,還帶來一些新的問題:
業務可見內存不一致,業務監控誤差,業務進程 OOM 風險。
討論以後,咱們追加了一個假設:
Service Mesh 容器佔用的資源實質是在接入 Service Mesh 以前業務已使用的資源。接入 Service Mesh 的過程,同時也是一次資源置換。
基於這個假設,推動了調度層面支持 POD 內的資源超賣,新的資源分配方案以下圖,Service Mesh 容器的 CPU、MEM 都從 POD 中超賣出來,業務容器內仍然能夠看到所有的資源。
考慮到內存超賣也引入了 POD OOM 的風險,所以對於 Sidecar 容器還調整了 OOM Score,保證在內存不足時,Service Mesh 進程可以發揮啓動比 Java 業務進程更快的優點,下降影響。
新的分配方案解決了同時解決了以上兩個問題,而且平穩支持了大促前的多輪壓測。
但新的分配方案上線時,Service Mesh 已經在彈性建站時同步上線。同時咱們還發如今一些場景下,Service Mesh 容器沒法搶佔到 CPU 資源,致使業務 RT 出現了大幅抖動,緣由是在 CPU Share 模式下,POD 內默認並無等額的分配 CPU Quota 給 Sidecar。
因而還有兩個問題待解決:
存量的已分配 Sidecar 仍有 OOM 風險;
Sidecar 沒法搶佔到 CPU;
咱們已經沒法承受更換所有 POD 的代價。最終在調度的支持下,經過對 Pod Annotation 的手動從新計算+修改,在 POD 內進行了所有資源的重分配,來修復這兩個風險。最終的修復容器總數約 25w 個。
Service Mesh 的變動包括了接入與升級,全部變動底層都是由 Operator 組件來接受上層寫入到 POD annotation 上的標識,對相應 POD Spec 進行修改來完成,這是典型的雲原生的方式。因爲螞蟻金服的資源現狀與運維須要,又發展出了原地接入與平滑升級。與 Operator 有關的具體細節在 Operator 篇中會詳細介紹,請持續關注本公衆號。
最初的 Service Mesh 接入只提供了建立時注入 Sidecar。以後引入原地接入的緣由,是爲了支撐大規模的快速接入與回滾。
建立接入:
資源替換過程須要大量 Buffer;
回滾困難;
原地接入:
不須要從新分配資源;
可原地回滾;
原地接入/回滾須要對 POD Spec 進行精細化的修改,實踐中發現了不少問題,當前能力只作了小範圍的測試。
Service Mesh 是深度參與業務流量的,所以最初的 Sidecar 的升級方式也須要業務伴隨重啓。看似簡單的這個過程當中,咱們也遇到了一個嚴重問題:
Pod 內的容器啓動順序隨機致使業務沒法啓動。
這個問題最終依賴於調度層修改了啓動邏輯,POD 內須要優先等待全部 Sidecar 啓動完成,因而帶來第二個問題:
Sidecar 啓動慢了,上層超時。
此問題仍在解決中。
Sidecar 中,MOSN 提供了更爲靈活的平滑升級機制:由 Operator 控制啓動第二個 MOSN Sidecar,完成鏈接遷移,再退出舊的 Sidecar。小規模測試顯示,整個過程業務能夠作到流量不中斷,幾近無感。目前平滑升級一樣涉及到 POD Spec 的大量操做,考慮到大促前的穩定性,目前此方式未作大規模使用。
在逐漸達到大促狀態的過程當中,接入 Service Mesh 的容器數量開始大爆炸式增長。容器數量從千級別迅速膨脹到10w+,最終達到全站數十萬容器規模,並在膨脹後還經歷了數次版本變動。
快速奔跑的同時,缺乏相應的平臺能力也給大規模的 Sidecar 運維帶來了極大挑戰:
版本管理混亂:
Sidecar 的版本與應用/ Zone 的映射關係維護在內部元數據平臺的配置中。大量應用接入後,全局版本,實驗版本,特殊 Bugfix 版本等混雜在多個配置項中,統一基線被打破,難於維護。
元數據不一致:
元數據平臺維護了 POD 粒度的 Sidecar 版本信息,可是因爲 Operator 是面向終態的,會出現元數據與底層實際不一致的狀況,當前仍依賴巡檢發現。
缺乏完善的 Sidecar ops 支撐平臺:
缺乏多維度的全局視圖;
缺乏固化的灰度發佈流程;
依賴於人工經驗配置管理變動;
監控噪聲巨大;
固然,Service Mesh 與 PaaS 的開發團隊都已經在建設相應的一些能力,這些問題正獲得逐步的緩解。
咱們的監控平臺爲 Service Mesh 提供了基礎的監控能力和大盤,以及應用維度的 Sidecar 的監控狀況。包括:
系統監控:
CPU;
MEM;
LOAD;
業務監控:
RT;
RPC 流量;
MSG 流量;
Error 日誌監控;
Service Mesh 進程還提供了相應的 Metrics 接口,提供服務粒度的數據採集與計算。
在 Service Mesh 上線後,巡檢也陸續被加入:
日誌 Volume 檢查;
版本一致性;
分時調度狀態一致;
Service Mesh 自身具有按需關閉部分功能的能力,當前經過配置中心實現:
日誌分級降級;
Tracelog 日誌分級降級;
控制面(Pilot)依賴降級;
軟負載均衡長輪詢降級;
對於 Service Mesh 依賴的服務,爲了防止潛在的抖動風險,也增長了相應的預案:
軟負載均衡列表中止變動;
服務註冊中心高峯期關閉推送;
Service Mesh 是很是基礎的組件,目前的應急手段主要是重啓:
Sidecar 單獨重啓;
POD 重啓;
除了傳統的變動三板斧以外,咱們還引入了無人值守變動,對 Service Mesh 變動作了自動檢測,自動分析與變動熔斷。
無人值守變動防控主要關注變動後對系統和業務和影響,串聯了多層檢測,主要包括:
系統指標:包括機器內存、磁盤、CPU;
業務指標:業務和 Service Mesh 的 RT、QPS 等;
業務關聯鏈路:業務上下游的的異常狀況;
全局的業務指標;
通過這一系列防控設施,能夠將全站性的 Service Mesh 變動風險在單一批次變動內發現和阻斷,避免了風險放大。
Service Mesh 在快速落地的過程當中,遇到並解決了一系列的問題,但同時也要看到還有更多的問題還亟待解決。作爲下一代雲原生化中間件的核心組件之一,Service Mesh 的技術風險能力還須要持續的建議與完善。
將來須要在下面這些方面持續建設:
大規模高效接入與回滾能力支撐;
更靈活的變動能力,包括業務無感的平滑/非平滑變動能力;
更精準的變動防控能力;
更高效,低噪聲的監控;
更完善的控制面支持;
應用維度的參數定製能力;
歡迎有志於中間件 Service Mesh 化與雲原生穩定性的同窗加入咱們,共同建設 Service Mesh 的將來。