螞蟻金服 Service Mesh 大規模落地系列 - 運維篇

支付寶技術團隊發表於2020-01-02

螞蟻金服 Service Mesh 大規模落地系列 - 運維篇

本文為《螞蟻金服 Service Mesh 大規模落地系列》第三篇 - 運維篇,該系列將會從核心、RPC、訊息、無線閘道器、控制面、安全、運維、測試等模組對 Service Mesh 雙十一大規模落地實踐進行詳細解析。文末包含往期系列文章。

引言

Service Mesh 是螞蟻金服下一代架構的核心,也是螞蟻金服內部向雲原生演進的重要一環。本文為 Service Mesh 系列文章的運維篇,作者:黃家琦 (花名:嘉祁),螞蟻金服運維專家,Service Mesh SRE,主要關注雲原生基礎設施、中介軟體及 Service Mesh 的穩定性,同時也是 Pythoner, sofa-bolt-python 作者。

本文將主要分享大規模服務網格在螞蟻金服當前體量下落地到支撐螞蟻金服雙十一大促過程中,運維角度所面臨的挑戰與演進。內容包括雲原生化的選擇與問題,對資源模型的挑戰,大規模下運維設施的演進,以及周邊技術風險能力的建設。

Service Mesh 在2019年得到了大規模的應用與落地,截止目前,螞蟻金服的 Service Mesh 資料平面 MOSN 已接入應用數百個 ,接入容器數量達數十萬,是目前已知的 全世界最大的 Service Mesh 叢集 。同時,在剛剛結束的雙十一大促中,Service Mesh 的表現也十分亮眼, RPC 峰值 QPS 達到了幾千萬,訊息峰值 TPS 達到了幾百萬,且引入 Service Mesh 後的平均 RT 增長幅度控制在 0.2 ms 以內。

擁抱雲原生

Service Mesh 在軟體形態上,是將中介軟體的能力從框架中剝離成獨立軟體。而在具體部署上,保守的做法是以獨立程式的方式與業務程式共同存在於業務容器內。我們在螞蟻金服內部的做法,則從開始,就選擇了擁抱雲原生。

Sidecar 模式


業務容器內獨立程式的好處在於與傳統的部署模式相容,易於快速上線;但獨立程式強侵入業務容器,對於映象化的容器更難於管理。而云原生化,則可以將 Service Mesh 本身的運維與業務容器解耦開來,實現中介軟體運維能力的下沉。在業務映象內,僅僅保留長期穩定的 Service Mesh 相關 JVM 引數,從而僅通過少量環境變數完成與 Service Mesh 的聯結。同時考慮到面向容器的運維模式的演進,接入 Service Mesh 還同時要求業務完成映象化,為進一步的雲原生演進打下基礎。

           優                     劣

獨立程式

  • 相容傳統的部署模式                    侵入業務容器
  • 改造成本低                   映象化難於運維
  • 快速上線

Sidecar

  • 面向終態                  依賴 K8s 基礎設施
  • 運維解耦                  運維環境改造成本高

                             應用需要映象化改造

在接入 Service Mesh 之後,一個典型的 POD 結構可能包含多個 Sidecar:

  • MOSN:RPC Mesh, MSG Mesh, ...(擴充套件中);
  • 其它 Sidecar;

MOSN: https://github.com/sofastack/sofa-mosn

螞蟻金服 Service Mesh 大規模落地系列 - 運維篇

這些 Sidecar 容器,與業務容器共享相同的網路 Namespace,使得業務程式可以以本地埠訪問 Service Mesh 提供的服務,保證了與保守做法一致的體驗。

基礎設施雲原生支撐


我們也在基礎設施層面同步推進了面向雲原生的改造,以支撐 Service Mesh 的落地。

業務全面映象化

首先是在螞蟻金服內部推進了全面的映象化,我們完成了內部核心應用的全量容器的映象化改造。改造點包括:

  • 基礎映象層面增加對於 Service Mesh 的環境變數支撐;
  • 應用 Dockerfile 對於 Service Mesh 的適配;
  • 推進解決了存量前後端分離管理的靜態檔案的映象化改造;
  • 推進了大量使用前端區塊分發的應用進行了推改拉的改造;
  • 大批量的 VM 模式的容器升級與替換;

容器 POD 化

除了業務映象層面的改造,Sidecar 模式還需要業務容器全部跑在 POD 上,來適應多容器共享網路。由於直接升級的開發和試錯成本很高,我們最終選擇將接入 Service Mesh 的 數百個應用的數萬個非 K8s 容器,通過大規模擴縮容的方式,全部更換成了 K8s PODs。

經過這兩輪改造,我們在基礎設施層面同步完成了面向雲原生的改造。

資源的演進

Sidecar 模式的帶來一個重要的問題,如何分配資源。

理想比例的假設


最初的資源設計基於記憶體無法超賣的現實。我們做了一個假設:

  • MOSN 的基本資源佔用與業務選擇的規格同比例這一假設。


CPU 和 Memory 申請與業務容器相應比例的額外資源。這一比例最後設定在了 CPU 1/4,Memory 1/16。

此時一個典型 Pod 的資源分配如下圖示:

螞蟻金服 Service Mesh 大規模落地系列 - 運維篇

這一方式帶來了兩個問題:

  1. 螞蟻金服已經實現了業務資源的 Quota 管控,但 Sidecar 並不在業務容器內,Service Mesh 容器成為了一個資源洩漏點;
  2. 業務很多樣,部分高流量應用的 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 中超賣出來,業務容器內仍然可以看到全部的資源。

螞蟻金服 Service Mesh 大規模落地系列 - 運維篇

考慮到記憶體超賣也引入了 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 的未來。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69904796/viewspace-2671559/,如需轉載,請註明出處,否則將追究法律責任。

相關文章