做者 | 彭南光(光南)
來源 | 阿里巴巴雲原生公衆號git
千里之堤,潰於蟻穴。web
不知道你們是否經歷過這樣的情景:忽然被用戶告知系統出現問題,而後一臉懵地惶惶然排查修復;或是等到本身發現系統出現故障時,實際已經對用戶形成了嚴重的惡劣影響。算法
所謂千里之堤,潰於蟻穴。用戶信任的創建是長期而艱難的,然而要摧毀這種信任卻很簡單。一旦出現上述問題,不只極大影響用戶使用體驗,同時會給用戶留下一個這個產品/團隊不可靠的印象,喪失用戶對產品/團隊長期好不容易積累下來的信用資本,將來再想創建這樣的信任關係就很難了。數據庫
這也是爲何咱們說快速發現問題的能力如此重要的緣由,只有先作到快速發現問題,才能談怎樣排查問題、如何解決問題。api
那麼怎樣才能在複雜的大規模場景中,作到真正先於用戶發現問題呢?下面我會帶來咱們在管理大規模 ASI 集羣過程當中對於快速發現問題的一些經驗和實踐,但願能對你們有所啓發。安全
注:ASI 是 Alibaba Serverless infrastructure 的縮寫,是阿里巴巴針對雲原生應用設計的統一基礎設施。有興趣能夠閱讀:《揭開阿里巴巴複雜任務資源混合調度技術面紗》。架構
咱們所管理的大規模 ASI 集羣場景很是複雜,這爲咱們的工做帶來了極大挑戰,任何一個場景處理不慎就有可能致使意料以外的傷害擴大化。less
從組件維度看,咱們目前有幾百個組件,每一年有幾萬次的組件變動。頻繁的組件變動如何在穩定性和效率之間取得權衡,怎樣讓變動時更穩定,怎樣讓灰度更確信,從而下降爆炸半徑?機器學習
從集羣維度看,目前有上千個集羣和海量節點,碰到的集羣/節點問題較多,監控鏈路覆蓋比較繁複,怎樣讓集羣運行時更加可信?分佈式
基於長期的集羣管理經驗,咱們有以下預設:
數據監控做爲正向鏈路,沒法無死角覆蓋全部場景。即便鏈路中各個節點的監控數據正常,也不能 100% 保證鏈路可用。
只有彌補上述兩類風險點,纔能有底氣真正作到先於用戶發現問題。咱們解決上述兩類風險的思路分別是:
基於以上思路,咱們設計並實現了 KubeProbe 探測/巡檢中心,用於彌補複雜系統的正向監控的不足,幫助咱們更好、更快地發現系統風險和線上問題。
不知道你是否也經歷過一條鏈路上各個系統監控數據都正常,可是實際鏈路流程就是跑不通。或者由於系統變化快,監控覆蓋不到 100% 的場景老是會有遺漏,致使影響到了用戶卻沒有報警,對用戶沒有實質影響卻報警頻發從而疲於奔命。
若是一個系統開發者本身都不使用本身的系統,那麼怎麼可能先於用戶發現系統問題呢?因此要先於用戶發現系統問題,首先咱們本身就得先成爲用戶,並且必定是使用最多,瞭解最深,無時無刻不在使用和感知系統情況的用戶。
所謂黑盒探測,就是讓本身成爲本身的用戶,模擬廣義"用戶"的行爲去對集羣/組件/鏈路等待待測對象作探測。注意,這裏的"用戶"並不只僅是狹義上使用系統的同窗,而是廣義用戶。好比,etcd 的"用戶"是 APIServer,而 ASI 的"用戶"多是某個經過 APIServer 操做集羣的同窗,也多是 Normandy 發起的發佈/擴容/縮容操做。
咱們但願 KubeProbe 能在 變動時(監聽到集羣狀態發生變化/組件變動/組件發佈/系統升級等等事件)/運行時(週期,高頻)/故障恢復時(手動),經過週期/事件觸發/手動觸發,執行各類不一樣類型的黑盒探測,第一時間感知組件/集羣/鏈路的可用性。
以 etcd 集羣的可用性來舉例,咱們能夠實現一個探測用例,邏輯是對 etcd 作 create/get/delete/txn 等等操做,並記錄每一個操做的成功率/消耗時間,當成功率低於 100% 或消耗時間超過容忍閾值後,觸發報警。咱們將週期高頻運行這個 etcd 的探測用例,同時對於 etcd 集羣的任何變動都會發出一個事件 event 觸發這個 etcd 探測當即運行,這樣就能儘可能確保第一時間發現 etcd 可用性故障了。同時,當 etcd 集羣由於某些緣由不可用了,咱們也能夠經過手動觸發等其餘方式作探活,也能第一時間獲得是否恢復的信息。
在大規模集集羣/系統場景下,數據一致性是必定會面臨的難題。數據不一致,將致使一些隱患,可能會在將來引起某些肯定性的故障。
相比於黑盒探測面對的未知故障場景,定向巡檢的目標是對集羣的已知風險點作掃描。
咱們但願 KubeProbe 可以按期對整個集羣/鏈路作定向的巡檢,找出這些數據不一致的點,判斷數據不一致是否可能引起風險,從而可以防患於未然,治未病。
好比 etcd 冷熱備多集羣覆蓋不全,可能致使集羣遇到故障沒法快速恢復。那麼咱們就按期對 etcd 的冷熱備覆蓋狀況作定向巡檢,找出沒有覆蓋推平的集羣,並告警。好比 集羣風控系統沒有全集羣鏈路覆蓋,限流配置沒有全集羣鏈路推平,可能致使某些故障場景引起集羣全面崩潰,咱們按期對風控配置全網掃描,判斷是否可能致使故障,找出這些隱藏的已知風險點並告警。
KubeProbe 的基本實現架構大體以下圖,KubeProbe 中心端配置集羣/集羣組與巡檢/探測用例/用例集之間的關聯關係,負責對集羣作具體某次探測實例下發。某個具體的巡檢/探測用例下發到具體某個集羣將使用用例的鏡像建立一個 pod,這個 pod 裏會執行若干巡檢/探測邏輯,當執行完成後會回調中心端回寫本次巡檢/探測結果。其具體結果在中心端統一展現/告警,並提供給其餘消費者消費(如支持 ASIOps 平臺的發佈阻斷)。
除了上述的基本架構以外,咱們對於高頻探測用例(既探測週期短,觸發頻率須要很是頻繁,甚至保持無縫探測的場景)設計了一套集羣內的分佈式常駐探測架構,該架構經過集羣內的 ProbeOperator 組件 watch 自定義對象 probeConfig 的變化,在集羣內建立一個常駐的探測 pod,將持續無間斷的運行探測邏輯,實現接近無縫的持續探測,並將結果經過去噪/令牌桶限流等處理後,上報中心端,共給其餘消費者消費。
全部的探測/巡檢用例都使用統一的 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 中心管控端解耦,能夠靈活而又簡便的讓更多的二方用戶接入本身的特殊巡檢/探測邏輯。
目前已經使用的探測/巡檢用例包括:
編寫完成探測/巡檢用例,並打包上傳好鏡像後,就須要在 KubeProbe 中心端註冊這個用例模版,即將鏡像註冊進 KubeProbe 中心端的數據庫中。
咱們能夠經過"渲染配置"參數傳入一些指定的 env 環境變量到巡檢/探測 pod 中,用於執行不一樣的業務邏輯,實現同一個用例模版生成多個用例。
最後經過統一的配置管控將用例和集羣作綁定,配置對應的參數,執行各類下發邏輯。
同時,咱們還在 KubeProbe 中心端作了大量權限安全管控,髒數據資源清理以及提效增速的工做(好比採用徹底以 ownerreferences 的巡檢/探測用例資源自動清理能力等等),這裏再也不贅述。
咱們打通了 KubeProbe 探測與發佈變動的關聯,當對應集羣中有任何變動發生時(如某組件在作發佈),咱們會自動經過相應的事件觸發此集羣綁定的全部巡檢/探測用例,檢查集羣狀態是否正常。若是探測失敗,則會將變動阻斷,下降爆炸半徑,提高集羣變動時穩定性。
社區有一個 Operator 叫 Kuberhealthy 也能夠作相似的事情,咱們曾經也考慮採用,而且深度使用過 Kuberhealthy 和參與 kuberhealthy 的社區貢獻,最終得出不適合的結論,主要緣由是對大規模集羣的支持較弱,同時高頻調用時主流程卡死問題比較嚴重,不支持事件/手動單次觸發特性,不支持統一上報數據中心等等,最終選擇了自研自建的方式,目前來看是一個比較正確的選擇。
KubeProbe 上線以來,實現探測/巡檢用例幾十個,在集團數百個 ASI 集羣中運行千萬餘次,主動發現集羣故障和問題百餘次,其中某些小故障一旦沒有發覺頗有可能升級成爲大故障,有效下降了系統風險。同時打通了變動/發佈系統,提高了變動穩定性。而且在特殊故障時,屢次先於業務方提早發現問題,更早地推進解決問題,客觀下降了故障損失。
下面是一個具體例子:
KubeProbe 所面對的場景和數據監控不一樣,更多偏向於鏈路探測。
好比,監控告警通常的告警可能以下:
這些告警,每每內容中就包含了具體的故障點,而 KubeProbe 的鏈路探測告警就有不少不同,好比:
這些 KubeProbe 的告警每每比較難從字面看出到底此次巡檢/探測是爲何失敗了,咱們每每須要根據相關的用例返回日誌,巡檢/探測 pod 日誌,KubeProbe 相關集羣事件綜合排查,定位失敗緣由。
咱們以比較混沌的 KubeProbe 探測失敗告警做爲線索,構建了一套 KubeProbe 自閉環的根因定位系統,將問題排查的專家經驗下沉進系統中,實現了快速和自動的問題定位功能,一個簡單的定位規則以下:
咱們會經過普通的根因分析樹以及對失敗巡檢探測事件/日誌的機器學習分類算法(持續開發投入中),爲每個 KubeProbe 的探測失敗 Case 作根因定位,並經過 KubeProbe 內統一實現的問題嚴重性評估系統(目前這裏的規則仍比較簡單),爲告警的嚴重性作評估,從而判斷應該如何作後續的處理適宜,好比是否自愈,是否電話告警等等。
有了上面提到的根因定位以及告警嚴重性評估系統,咱們使用了 nlp 告警機器人,實現了一套自動化的 Oncall 系統以及 ChatOps,展現一些使用的 case 以下,經過 ChatOps 和 Oncall 機器人,極大的下降了問題處理的複雜度,儘可能用技術的手段解決重複的問題。
以上是咱們在管理大規模 Kubernetes 集羣中的一點經驗,也解決了一些常見的問題,但願能對你們有所幫助。同時,這些工做在阿里雲海量規模的場景下還須要持續打磨,咱們仍在路上,而且將持續在路上。