面對大規模 K8s 集羣,如何先於用戶發現問題?

頭圖.png

做者 | 彭南光(光南)
來源 | 阿里巴巴雲原生公衆號git

千里之堤,潰於蟻穴。web

緒論

不知道你們是否經歷過這樣的情景:忽然被用戶告知系統出現問題,而後一臉懵地惶惶然排查修復;或是等到本身發現系統出現故障時,實際已經對用戶形成了嚴重的惡劣影響。算法

所謂千里之堤,潰於蟻穴。用戶信任的創建是長期而艱難的,然而要摧毀這種信任卻很簡單。一旦出現上述問題,不只極大影響用戶使用體驗,同時會給用戶留下一個這個產品/團隊不可靠的印象,喪失用戶對產品/團隊長期好不容易積累下來的信用資本,將來再想創建這樣的信任關係就很難了。數據庫

這也是爲何咱們說快速發現問題的能力如此重要的緣由,只有先作到快速發現問題,才能談怎樣排查問題、如何解決問題。api

那麼怎樣才能在複雜的大規模場景中,作到真正先於用戶發現問題呢?下面我會帶來咱們在管理大規模 ASI 集羣過程當中對於快速發現問題的一些經驗和實踐,但願能對你們有所啓發。安全

注:ASI 是 Alibaba Serverless infrastructure 的縮寫,是阿里巴巴針對雲原生應用設計的統一基礎設施。有興趣能夠閱讀:《揭開阿里巴巴複雜任務資源混合調度技術面紗》架構

背景

1. 複雜的場景和曾面臨的困境

咱們所管理的大規模 ASI 集羣場景很是複雜,這爲咱們的工做帶來了極大挑戰,任何一個場景處理不慎就有可能致使意料以外的傷害擴大化。less

  • 從組件維度看,咱們目前有幾百個組件,每一年有幾萬次的組件變動。頻繁的組件變動如何在穩定性和效率之間取得權衡,怎樣讓變動時更穩定,怎樣讓灰度更確信,從而下降爆炸半徑?機器學習

  • 從集羣維度看,目前有上千個集羣和海量節點,碰到的集羣/節點問題較多,監控鏈路覆蓋比較繁複,怎樣讓集羣運行時更加可信?分佈式

  • 從二方用戶和業務場景看,咱們支持了大量的集團二方用戶,同時業務場景也很是複雜,怎樣保證各有特點的業務場景都能獲得一致的細心關照?

1.png

2. 問題預判和解決思路

基於長期的集羣管理經驗,咱們有以下預設:

  1. 數據監控做爲正向鏈路,沒法無死角覆蓋全部場景。即便鏈路中各個節點的監控數據正常,也不能 100% 保證鏈路可用。

    • 集羣狀態每時每刻都在變化,各個組件也在不停地更新升級,同時鏈路上的每一個系統也在不停的變動,監控數據的覆蓋永遠是正向的追趕,只能逼近 100% 全覆蓋而沒法徹底達到。
    • 即便整個集羣鏈路中全部組件/節點的監控數據都正常,也不能保證集羣鏈路 100% 可用。就如同業務系統同樣,看上去都是可用的,沒有問題暴露。但只有經過全鏈路壓測實際探測過整個鏈路後,才能獲得實際可用的結論。
    • 你要正向證實一個東西可用,須要舉證無數的例子。而若是要反向證實不可用,一個反例就夠了。數據監控鏈路只能逼近全覆蓋,而沒法保證真正全覆蓋。
  2. 大規模場景下,數據沒法達到 100% 的徹底一致性。
    • 當集羣規模足夠大時,數據的一致性問題將會越發顯現。好比全局風控組件是否全集羣鏈路覆蓋?相關流控配置是否全集羣鏈路推平?pod 主容器時區是否與上層一致?集羣客戶端節點證書是否有即將過時?等等問題,一旦疏忽,將有可能釀成嚴重的故障。

只有彌補上述兩類風險點,纔能有底氣真正作到先於用戶發現問題。咱們解決上述兩類風險的思路分別是:

  1. 黑盒探測
    • 所謂黑盒探測,既模擬廣義上的用戶行爲,探測鏈路是否正常。
  2. 定向巡檢
    • 所謂巡檢,既檢查集羣異常指標,找到已有或可能將存在的風險點。

基於以上思路,咱們設計並實現了 KubeProbe 探測/巡檢中心,用於彌補複雜系統的正向監控的不足,幫助咱們更好、更快地發現系統風險和線上問題。

設計

黑盒探測和定向巡檢

1)黑盒探測

不知道你是否也經歷過一條鏈路上各個系統監控數據都正常,可是實際鏈路流程就是跑不通。或者由於系統變化快,監控覆蓋不到 100% 的場景老是會有遺漏,致使影響到了用戶卻沒有報警,對用戶沒有實質影響卻報警頻發從而疲於奔命。

若是一個系統開發者本身都不使用本身的系統,那麼怎麼可能先於用戶發現系統問題呢?因此要先於用戶發現系統問題,首先咱們本身就得先成爲用戶,並且必定是使用最多,瞭解最深,無時無刻不在使用和感知系統情況的用戶。

所謂黑盒探測,就是讓本身成爲本身的用戶,模擬廣義"用戶"的行爲去對集羣/組件/鏈路等待待測對象作探測。注意,這裏的"用戶"並不只僅是狹義上使用系統的同窗,而是廣義用戶。好比,etcd 的"用戶"是 APIServer,而 ASI 的"用戶"多是某個經過 APIServer 操做集羣的同窗,也多是 Normandy 發起的發佈/擴容/縮容操做。

2.png

咱們但願 KubeProbe 能在 變動時(監聽到集羣狀態發生變化/組件變動/組件發佈/系統升級等等事件)/運行時(週期,高頻)/故障恢復時(手動),經過週期/事件觸發/手動觸發,執行各類不一樣類型的黑盒探測,第一時間感知組件/集羣/鏈路的可用性。

以 etcd 集羣的可用性來舉例,咱們能夠實現一個探測用例,邏輯是對 etcd 作 create/get/delete/txn 等等操做,並記錄每一個操做的成功率/消耗時間,當成功率低於 100% 或消耗時間超過容忍閾值後,觸發報警。咱們將週期高頻運行這個 etcd 的探測用例,同時對於 etcd 集羣的任何變動都會發出一個事件 event 觸發這個 etcd 探測當即運行,這樣就能儘可能確保第一時間發現 etcd 可用性故障了。同時,當 etcd 集羣由於某些緣由不可用了,咱們也能夠經過手動觸發等其餘方式作探活,也能第一時間獲得是否恢復的信息。

2)定向巡檢

在大規模集集羣/系統場景下,數據一致性是必定會面臨的難題。數據不一致,將致使一些隱患,可能會在將來引起某些肯定性的故障。

相比於黑盒探測面對的未知故障場景,定向巡檢的目標是對集羣的已知風險點作掃描。

3.png

咱們但願 KubeProbe 可以按期對整個集羣/鏈路作定向的巡檢,找出這些數據不一致的點,判斷數據不一致是否可能引起風險,從而可以防患於未然,治未病。

好比 etcd 冷熱備多集羣覆蓋不全,可能致使集羣遇到故障沒法快速恢復。那麼咱們就按期對 etcd 的冷熱備覆蓋狀況作定向巡檢,找出沒有覆蓋推平的集羣,並告警。好比 集羣風控系統沒有全集羣鏈路覆蓋,限流配置沒有全集羣鏈路推平,可能致使某些故障場景引起集羣全面崩潰,咱們按期對風控配置全網掃描,判斷是否可能致使故障,找出這些隱藏的已知風險點並告警。

實現

1. 架構

1)基本架構

KubeProbe 的基本實現架構大體以下圖,KubeProbe 中心端配置集羣/集羣組與巡檢/探測用例/用例集之間的關聯關係,負責對集羣作具體某次探測實例下發。某個具體的巡檢/探測用例下發到具體某個集羣將使用用例的鏡像建立一個 pod,這個 pod 裏會執行若干巡檢/探測邏輯,當執行完成後會回調中心端回寫本次巡檢/探測結果。其具體結果在中心端統一展現/告警,並提供給其餘消費者消費(如支持 ASIOps 平臺的發佈阻斷)。

4.png

2)高頻架構

除了上述的基本架構以外,咱們對於高頻探測用例(既探測週期短,觸發頻率須要很是頻繁,甚至保持無縫探測的場景)設計了一套集羣內的分佈式常駐探測架構,該架構經過集羣內的 ProbeOperator 組件 watch 自定義對象 probeConfig 的變化,在集羣內建立一個常駐的探測 pod,將持續無間斷的運行探測邏輯,實現接近無縫的持續探測,並將結果經過去噪/令牌桶限流等處理後,上報中心端,共給其餘消費者消費。

5.png

2. KubeProbe 探測/巡檢用例管理

全部的探測/巡檢用例都使用統一的 git 倉庫管理,由咱們提供一個統一的 client 庫,client 庫最核心提供的方法主要有兩個。

KPclient "gitlab.alibaba-inc.com/{sigma-inf}/{kubeProbe}/client"

// 報告成功
// 此方法會向KubeProbe報告本次巡檢結果爲成功
KPclient.ReportSuccess()
os.Exit(0)

// 報告失敗
// 報告方法會向KubeProbe報告本次巡檢結果爲失敗,而且失敗信息爲 `我失敗啦`
KPclient.ReportFailure([]string{"我失敗啦!"})
os.Exit(1)

咱們能夠經過提供好的 Makefile 將這個用例打包成鏡像,錄入 KubeProbe 中心端就能夠對集羣作配置和下發了。將具體巡檢/探測邏輯和 KubeProbe 中心管控端解耦,能夠靈活而又簡便的讓更多的二方用戶接入本身的特殊巡檢/探測邏輯。

目前已經使用的探測/巡檢用例包括:

  • 通用探測:模擬 pod / deployment / statefulset 生命週期探測集羣整條管控鏈路。
  • etcd 黑盒探測:模擬 etcd 的基本操做,探測元集羣中各 etcd 狀態。
  • 金絲雀探測(感謝質量技術同窗的大力支持):模擬用戶使用 ASI 的部署場景,實現金絲雀應用的全鏈路模擬發佈/擴容/縮容。
  • Virtual cluster 探測:探測 vc 虛擬集羣的管控鏈路狀態。
  • 聯邦鏈路探測:探測聯邦控制器相關鏈路的狀態。
  • 節點通用探測:在集羣每一個節點上模擬調度一個探測 pod,探測節點側鏈路狀態。
  • ASI 客戶端/服務端證書巡檢:檢查客戶端/服務端證書有效性以及到期時間是否已超過告警閾值。
  • 全局風控限流巡檢:檢查各 ASI 集羣是否已經推平並開啓 KubeDefender 全侷限流風控配置。
  • ······

3. KubeProbe 中心端管控

編寫完成探測/巡檢用例,並打包上傳好鏡像後,就須要在 KubeProbe 中心端註冊這個用例模版,即將鏡像註冊進 KubeProbe 中心端的數據庫中。

咱們能夠經過"渲染配置"參數傳入一些指定的 env 環境變量到巡檢/探測 pod 中,用於執行不一樣的業務邏輯,實現同一個用例模版生成多個用例。

最後經過統一的配置管控將用例和集羣作綁定,配置對應的參數,執行各類下發邏輯。

6.png

同時,咱們還在 KubeProbe 中心端作了大量權限安全管控,髒數據資源清理以及提效增速的工做(好比採用徹底以 ownerreferences 的巡檢/探測用例資源自動清理能力等等),這裏再也不贅述。

4. 打通發佈 / 變動阻斷

咱們打通了 KubeProbe 探測與發佈變動的關聯,當對應集羣中有任何變動發生時(如某組件在作發佈),咱們會自動經過相應的事件觸發此集羣綁定的全部巡檢/探測用例,檢查集羣狀態是否正常。若是探測失敗,則會將變動阻斷,下降爆炸半徑,提高集羣變動時穩定性。

5. 爲何不使用 Kuberhealthy

社區有一個 Operator 叫 Kuberhealthy 也能夠作相似的事情,咱們曾經也考慮採用,而且深度使用過 Kuberhealthy 和參與 kuberhealthy 的社區貢獻,最終得出不適合的結論,主要緣由是對大規模集羣的支持較弱,同時高頻調用時主流程卡死問題比較嚴重,不支持事件/手動單次觸發特性,不支持統一上報數據中心等等,最終選擇了自研自建的方式,目前來看是一個比較正確的選擇。

一點小結果

KubeProbe 上線以來,實現探測/巡檢用例幾十個,在集團數百個 ASI 集羣中運行千萬餘次,主動發現集羣故障和問題百餘次,其中某些小故障一旦沒有發覺頗有可能升級成爲大故障,有效下降了系統風險。同時打通了變動/發佈系統,提高了變動穩定性。而且在特殊故障時,屢次先於業務方提早發現問題,更早地推進解決問題,客觀下降了故障損失。

下面是一個具體例子:

  • 咱們會接收到每一個集羣中各個組件的發佈事件,由發佈事件觸發咱們會在對應集羣中運行相關的巡檢/探測,好比調度一個定向的 pod 到某個節點組件發佈的節點上去。咱們發現 kube-proxy 的發佈會致使節點的短暫不可用,調度上去的 pod 沒法建立成功,從簡單的返回/日誌/集羣事件上看不出具體的問題,而且持續復現。通過深刻排查,得知是 kube-proxy 的問題,存在 netns 泄露。運行久了會泄露,當 kube-proxy 重啓的時候,內核要清理 netns,會卡一段時間來清理,致使節點一段時間鏈路不通,pod 能夠調度上去可是運行不起來,從然後續推動了 kube-proxy 的問題修復。

7.png

8.png

發現問題以後

1. KubeProbe 和數據監控的告警區別

KubeProbe 所面對的場景和數據監控不一樣,更多偏向於鏈路探測。

好比,監控告警通常的告警可能以下:

  • xx容器內存使用率 99%
  • webhook 雙副本所有掛掉了
  • apiserver 三副本所有宕機了

這些告警,每每內容中就包含了具體的故障點,而 KubeProbe 的鏈路探測告警就有不少不同,好比:

  • Statefulset 鏈路探測失敗,Failed to create pod sandbox: rpc error: code = Unknown
  • etcd 全流程黑盒探測失敗,context deadline exceeded
  • CloneSet 擴容失敗,connect: connection refused

這些 KubeProbe 的告警每每比較難從字面看出到底此次巡檢/探測是爲何失敗了,咱們每每須要根據相關的用例返回日誌,巡檢/探測 pod 日誌,KubeProbe 相關集羣事件綜合排查,定位失敗緣由。

2. 根因定位

咱們以比較混沌的 KubeProbe 探測失敗告警做爲線索,構建了一套 KubeProbe 自閉環的根因定位系統,將問題排查的專家經驗下沉進系統中,實現了快速和自動的問題定位功能,一個簡單的定位規則以下:

9.png

咱們會經過普通的根因分析樹以及對失敗巡檢探測事件/日誌的機器學習分類算法(持續開發投入中),爲每個 KubeProbe 的探測失敗 Case 作根因定位,並經過 KubeProbe 內統一實現的問題嚴重性評估系統(目前這裏的規則仍比較簡單),爲告警的嚴重性作評估,從而判斷應該如何作後續的處理適宜,好比是否自愈,是否電話告警等等。

3. Oncall 和 ChatOps

有了上面提到的根因定位以及告警嚴重性評估系統,咱們使用了 nlp 告警機器人,實現了一套自動化的 Oncall 系統以及 ChatOps,展現一些使用的 case 以下,經過 ChatOps 和 Oncall 機器人,極大的下降了問題處理的複雜度,儘可能用技術的手段解決重複的問題。

10.png

11.png

12.png

咱們仍在路上

以上是咱們在管理大規模 Kubernetes 集羣中的一點經驗,也解決了一些常見的問題,但願能對你們有所幫助。同時,這些工做在阿里雲海量規模的場景下還須要持續打磨,咱們仍在路上,而且將持續在路上。

相關文章
相關標籤/搜索