云原生背景下故障演练体系建设的思考与实践—云原生混沌工程系列之指南篇
?作者:?智妍(鄭妍)、?浣碧(何穎)?
什么是混沌工程,云原生大潮下的混沌工程特點
通過使用云計算廠商如阿里云、AWS 等提供的服務(wù),現(xiàn)代服務(wù)提供者得以用更低廉的成本,更穩(wěn)定地進行豐富的軟件服務(wù)提供。但是真的一切如此輕而易舉嗎?主流云計算廠商在 SLA 承諾的范圍內(nèi),都各自出現(xiàn)過一些歷史故障,可參見這份血淋淋的?github 上的報告列表 [1] 。另一方面,各個云產(chǎn)品提供給了用戶使用的一些高可用能力,經(jīng)常依然是需要用正確的姿勢來配置和使用的。
混沌工程可以幫助業(yè)務(wù)系統(tǒng)服務(wù)提供者通過創(chuàng)建破壞性事件、觀察系統(tǒng)和人員響應(yīng)方式、針對優(yōu)化改進這 3 個步驟來發(fā)現(xiàn)生產(chǎn)服務(wù)中脆弱的環(huán)節(jié),并根據(jù)預(yù)期的 SLA 目標(biāo)進行實施改進。除了指出需要改進的系統(tǒng)組件設(shè)計問題之外,混沌工程還可幫助發(fā)現(xiàn)需要監(jiān)控和告警上的盲點、發(fā)現(xiàn)人員對系統(tǒng)理解、應(yīng)急響應(yīng) SOP、排查能力上的不足,進而使得業(yè)務(wù)系統(tǒng)及其研發(fā)、運維人員整體的高可用能力水位大大上浮。因此 Netflix 提出此概念后,各大軟件廠商紛紛進行了對內(nèi)實踐和對外產(chǎn)品提供。
云原生在傳統(tǒng)云計算基礎(chǔ)上,提供了更快更低成本的彈性,更好的軟硬一體化靈活性,已經(jīng)成為云計算發(fā)展最快的技術(shù)方向。云原生幫助開發(fā)者大幅度降低資源成本和交付成本,從而更快更好地贏得市場。同時,云原生也給傳統(tǒng)運維、研發(fā)方式帶來了徹底的變革,這就使得傳統(tǒng)的混沌工程手段需要跟隨演進。
云原生背景下,其上的應(yīng)用服務(wù)的混沌工程實施和傳統(tǒng)有什么不同呢?從我們在阿里電商、中間件云原生化的大量實踐中,總結(jié)出以下主要差異:
在這樣差異的背景下,用云原生的手段,實施更加針對植根于云原生應(yīng)用的場景的混沌工程,是更加恰如其分,能夠提供更多能力提升的。
混沌工程實施模式的階段和發(fā)展
既然混沌工程能帶來如此多的好處,一個基于云原生的應(yīng)用服務(wù)或體系想要實踐,要如何落地呢?
從演練工具和落地實施來看,一個組織的故障演練經(jīng)常分為幾個發(fā)展階段:手工演練,流程工具自動化演練,常態(tài)化無人值守演練,生產(chǎn)突襲演練。
這幾個階段的實施難度是從低到高,當(dāng)然相應(yīng)的收益也是從低到高。一個組織(云用戶)可以隨著自己業(yè)務(wù)應(yīng)用服務(wù)體量的增大、復(fù)雜化和高可用能力的增高的歷程,根據(jù)實際情況需要選擇自己合適的階段,然后隨之進行升級和發(fā)展。即使從最簡便的手工演練開始做起實施,經(jīng)常也能帶來相當(dāng)明顯且長遠的高可用能力系統(tǒng)性提升。
那么每個階段分別有什么特點,又該如何選擇呢
-
手工演練: 一般在高可用能力建設(shè)初期階段,或者一次性驗收的情況下手工注入故障完成。通過人為查看告警是否生效,系統(tǒng)恢復(fù)情況來進行演練。在這個階段只需要一些故障注入的小工具或者腳本,方便后續(xù)使用即可。
-
自動化演練: 高可用能力建設(shè)到一定階段后,往往會有定期檢查高可用能力是否退化的需求,自動化演練開始排上日程。自動化演練步驟一般包括:環(huán)境準(zhǔn)備 -> 故障注入 -> 檢查 -> 環(huán)境恢復(fù)。在每個步驟中配置相應(yīng)的腳本來形成演練流程,下一次就可以一鍵點擊自動化執(zhí)行了。
-
常態(tài)化執(zhí)行: 演練進行到下一階段,我們會有更高的要求,希望演練可以自主混沌化執(zhí)行,以無人值守的方式進行,這又對系統(tǒng)的高可用能力有了新的挑戰(zhàn)。這要求系統(tǒng)有不僅有監(jiān)控告警可以發(fā)現(xiàn)故障,也有對應(yīng)的預(yù)案模塊來負(fù)責(zé)恢復(fù),而要做到無人值守,需要系統(tǒng)進行更智能精確的判斷故障情況,自動執(zhí)行相應(yīng)預(yù)案。
- 生產(chǎn)突襲: 以上演練大多在灰度環(huán)境進行,不會影響到業(yè)務(wù),生產(chǎn)突襲則要求系統(tǒng)有能力在生產(chǎn)環(huán)境控制爆炸半徑的前提下進行故障演練,以期發(fā)現(xiàn)一些業(yè)務(wù)相關(guān)、規(guī)模相關(guān)、配置相關(guān)、應(yīng)急響應(yīng)相關(guān)的,在灰度環(huán)境遺漏的部分,生產(chǎn)環(huán)境的演練對系統(tǒng)的要求較高,需要有一套執(zhí)行規(guī)范,對系統(tǒng)的隔離能力也有較高要求。大多數(shù)的工作,能力建設(shè)都在灰度環(huán)境完成驗證,但生產(chǎn)突襲仍作為一個有效且必要的演練手段,用更真實的場景給研發(fā)體感,讓其真實執(zhí)行預(yù)案,也鍛煉了應(yīng)急能力,對系統(tǒng)有更多信心和認(rèn)知。
如何進行一次完整的故障演練實施
當(dāng)應(yīng)用首次使用 Kubernetes 進行應(yīng)用部署和擴容時,最先關(guān)注的更多是功能是否可用,故障演練則是更高級別的要求,我們假設(shè)當(dāng)前的系統(tǒng)已經(jīng)初步通過了功能驗收,但對于一些故障情況下系統(tǒng)的表現(xiàn)還未知的前提下,來開始我們的故障演練之旅。故障演練本身作為一種破壞性的操作,需要循序漸進,遵循一定的規(guī)范和流程來落地。下面我們從環(huán)境建設(shè)、系統(tǒng)能力分析、高可用能力建設(shè)、演練實施建議幾個方面來介紹一下,一個首次在 Kubernetes 中部署起來的應(yīng)用應(yīng)該如何循序漸進的實施故障演練。
Step 1:隔離環(huán)境建設(shè)
故障演練,特別是首次執(zhí)行之前,我們需要明確好當(dāng)前注入故障的環(huán)境情況,是否可能影響到業(yè)務(wù)流量,是否會造成無法彌補的損失,在阿里內(nèi)部,我們有復(fù)雜的環(huán)境隔離和變更管控,以防故障注入影響到業(yè)務(wù)流量。
在環(huán)境類別上,我們會區(qū)分為以下幾類:
-
業(yè)務(wù)測試環(huán)境:用來進行 e2e 測試,全面的功能驗收,這個環(huán)境和有業(yè)務(wù)流量的生產(chǎn)網(wǎng)絡(luò)是隔離的,從網(wǎng)絡(luò)上避免了流量錯誤進入到其他環(huán)境,因此可以在這個環(huán)境上盡情的進行各種容錯性測試。
-
金絲雀環(huán)境:可以理解為是一種全面的鏈路灰度環(huán)境,這個環(huán)境有當(dāng)前系統(tǒng)的所有組件,一般用來做上下游聯(lián)調(diào),系統(tǒng)內(nèi)部的鏈路灰度使用,這個環(huán)境是沒有實際業(yè)務(wù)流量的;
-
安全生產(chǎn)灰度環(huán)境:這個環(huán)境我們會引入 1% 的生產(chǎn)流量,并提前建設(shè)了切流能力,一旦這個環(huán)境出現(xiàn)問題,可以把流量迅速切換到生產(chǎn)環(huán)境中,該環(huán)境一般用來結(jié)合用戶流量做一段時間的灰度,以免全量發(fā)布導(dǎo)致的不可控;
-
生產(chǎn)環(huán)境:真實用戶流量的環(huán)境,這個環(huán)境的任何運維動作都需要進行嚴(yán)格的變更審核和前幾個環(huán)境的灰度通過才能變更;
故障演練一般會開始在金絲雀環(huán)境引入,可以在全鏈路、無真實流量的環(huán)境中做一些高可用能力的建設(shè)和驗收,常態(tài)執(zhí)行的演練,在這個環(huán)境演練多次的場景,可定期在灰度環(huán)境和生產(chǎn)環(huán)境中、控制爆炸半徑的前提下進行真實突襲,作為能力的驗收。
一般情況下,考慮到成本投入和系統(tǒng)復(fù)雜度,業(yè)務(wù)應(yīng)用可能不會建設(shè) 4 個隔離環(huán)境來循序漸進的推進,但我們推薦應(yīng)用應(yīng)該至少有兩個環(huán)境來區(qū)分用戶流量,環(huán)境上至少有一個和生產(chǎn)隔離的灰度環(huán)境,至少初期必須如此。環(huán)境建設(shè)中需要關(guān)注的問題如下:
-
隔離性:灰度環(huán)境和生產(chǎn)環(huán)境盡量做到隔離,包括但不限于網(wǎng)絡(luò)隔離,權(quán)限隔離,數(shù)據(jù)隔離等,考慮到一些容災(zāi)的能力,還可以將兩個集群建設(shè)在不同地域的 Kubernetes 集群中。
-
真實性:灰度環(huán)境和生產(chǎn)環(huán)境盡量保持一致,比如外部依賴,組件版本。
環(huán)境建設(shè)達標(biāo)后,才具備了演練的準(zhǔn)入條件。
Step 2:故障場景分析
在分析系統(tǒng)的高可用能力時,往往沒有一個統(tǒng)一的答案,每個系統(tǒng)的薄弱點,瓶頸都不盡相同,但整理系統(tǒng)高可用能力時,我們可以提供一些通用的思路。
- 歷史故障:
歷史故障通常是快速了解一個系統(tǒng)薄弱能力的教科書,通過分析歷史故障,進行分類,可以快速得出當(dāng)前系統(tǒng)那些組件更容易出現(xiàn)問題。
比如系統(tǒng)能力需要進行快速的彈性伸縮,伸縮失敗可能影響業(yè)務(wù)流量,可以推斷出它強依賴 Kubernetes 的擴縮容能力,需要監(jiān)控關(guān)注此能力的可用性;比如系統(tǒng)數(shù)據(jù)讀寫頻繁,歷史出現(xiàn)過數(shù)據(jù)不一致問題,則可以考慮在數(shù)據(jù)層面進行穩(wěn)定性建設(shè),增加備份能力,回滾能力等。
- 架構(gòu)分析
系統(tǒng)的架構(gòu)在一定程度上決定了這個系統(tǒng)的瓶頸,通過分析系統(tǒng)的依賴也可以更了解系統(tǒng)的邊界,也更便于進行運維上的優(yōu)化。
比如一個應(yīng)用的部署方式是主備模式的,那必須要檢查的能力就是主備切換是否順暢,切換過程是否影響到業(yè)務(wù)流量;比如一個應(yīng)用強依賴底層存儲,一旦存儲掛掉,業(yè)務(wù)會大面積故障,則在整理高可用能力的時候就需要想到存儲掛掉后是否有降級方案,存儲問題是否可以提前預(yù)警。
- 社區(qū)經(jīng)驗:
很多系統(tǒng)的架構(gòu)都是大同小異的,參考社區(qū)或友商的經(jīng)驗就像提前看了模擬考題,總會有意想不到的收獲。我們總會在業(yè)界爆出一些故障時進行自我反思和重新整理,多次發(fā)現(xiàn)了自身的一些問題。網(wǎng)線被挖斷、刪庫跑路等寶貴的經(jīng)驗庫,都在我們定期演練的列表中。
在阿里云原生的架構(gòu)上,我們整理了如下所示的演練模型供參考,在這個高可用能力模型中,我們根據(jù)系統(tǒng)架構(gòu)按照管控層組件、元集群組件、擴展組件,數(shù)據(jù)存儲,節(jié)點層,整體集群進行區(qū)分,在每個模塊中有一些通用的故障可以互相借鑒。
Step 3:系統(tǒng)高可用能力建設(shè)
在實際進行故障注入前,我們還需要問自己幾個問題。根據(jù)上述已經(jīng)分析到的我們想讓系統(tǒng)擁有的高可用能力列表,系統(tǒng)是否具備當(dāng)這些故障來臨時有敏捷的發(fā)現(xiàn)能力,人員有迅速的響應(yīng)能力,系統(tǒng)本身是否具備自愈的能力或一些可用來在故障過程中使用快速恢復(fù)系統(tǒng)的工具呢?下面我們從發(fā)現(xiàn)能力和恢復(fù)能力兩個方面來給一些通用的建議。
- 發(fā)現(xiàn)能力
監(jiān)控和告警是能夠發(fā)現(xiàn)系統(tǒng)是否處于穩(wěn)態(tài)并讓應(yīng)用負(fù)責(zé)人一目了然的方式。阿里內(nèi)部團隊建設(shè)了兩種監(jiān)控告警方式,一種是白盒告警,借助系統(tǒng)內(nèi)部暴露出來的各種維度的可觀測性數(shù)據(jù)的異常波動來發(fā)現(xiàn)潛在問題;一種是黑盒告警,從客戶視角把系統(tǒng)當(dāng)做黑盒,探測正向功能。
- 恢復(fù)能力
故障來臨后,最優(yōu)的結(jié)果是系統(tǒng)穩(wěn)定絲滑,毫無影響,這對系統(tǒng)的能力建設(shè)要求極高,而實際的情況往往更為復(fù)雜。在阿里內(nèi)部的實踐中,除了對系統(tǒng)本身專門建設(shè)了基本的進程自愈、切流能力、遷移能力、限流能力等,也建設(shè)了預(yù)案中心,中心化的沉淀我們所有的止損能力到系統(tǒng)中,白屏管理,接入,運行,根據(jù)專家經(jīng)驗建立止損能力集,作為故障時的重要工具。
Step 4:演練實施
以上步驟完成之后,我們認(rèn)為系統(tǒng)已具備了初步的高可用能力,可以開始實施故障演練。
一般情況下首次演練我們會挑選一些核心場景進行,在預(yù)發(fā)或測試環(huán)境,工具上使用半自動化的腳本或僅包含故障注入模塊的流水線來觸發(fā),在研發(fā)和運維人員在場的情況下進行首次試驗。試驗前確認(rèn)場景的預(yù)期,比如故障注入后需要 1min 進行告警,10min 內(nèi)系統(tǒng)自愈恢復(fù),以便在演練過程中隨時確認(rèn)。演練執(zhí)行后需要各部分人員進行人工確認(rèn)系統(tǒng)表現(xiàn)是否符合預(yù)期,演練結(jié)束后及時恢復(fù)故障和環(huán)境。場景在演練過程中不符預(yù)期的部分,需要多次在此階段不斷驗證和演練;符合預(yù)期的場景進行標(biāo)記,可以開始進入到常態(tài)化演練階段。
常態(tài)化演練階段的關(guān)鍵詞是混沌化、無人值守,Kubernetes 集群由于架構(gòu)的優(yōu)勢,本身具備一定的自愈能力,因此更適合無人值守的演練。我們會篩選已經(jīng)通過半自動演練的場景集合,組織為一些故障演練流水線,每個流水線中一般包含故障注入、監(jiān)控檢查、恢復(fù)檢查、故障恢復(fù)等步驟,來閉環(huán)完成單個演練流程。同時阿里內(nèi)部使用云原生技術(shù)進行混沌化觸發(fā),實現(xiàn)在演練對象、環(huán)境、時間、場景上的隨機,使得這些演練場景可以混沌化、常態(tài)化、無人值守的執(zhí)行。通過常態(tài)化故障演練,助于發(fā)現(xiàn)一些偶發(fā)性系統(tǒng)問題,并可以在系統(tǒng)升級過程中協(xié)助檢查已有的高可用能力。
生產(chǎn)突襲的實施需要根據(jù)系統(tǒng)的架構(gòu)情況進行,在阿里內(nèi)部的實施中,一種控制風(fēng)險的方式是選擇流量低峰去進行,并提前預(yù)備一鍵切流預(yù)案,一旦出現(xiàn)故障無法恢復(fù)的情況,立即切流止損。其他突襲相關(guān)的風(fēng)險控制設(shè)計我們會在后續(xù)的系列文章中詳細分析。
結(jié)語
在內(nèi)部云原生領(lǐng)域?qū)嵤┕收涎菥毜倪^程中,我們分析了 200 多個演練場景,通過 1000+/月的頻次進行常態(tài)化故障演練,有效的發(fā)現(xiàn)了 90 多個問題,避免了問題半徑進一步擴大;通過演練流程的搭建、校驗和混沌化執(zhí)行,定期監(jiān)測系統(tǒng)的告警和預(yù)案恢復(fù)能力,有效的攔截 50 多個新增高可用問題上線。生產(chǎn)環(huán)境的突襲演練是我們邁出的艱難但有力的一步,鍛煉了研發(fā)運維人員的應(yīng)急響應(yīng)能力,在真實用戶場景下錘煉系統(tǒng),推進了產(chǎn)品的輪班制度,提升了云原生底座的穩(wěn)定性和競爭力。
相關(guān)鏈接
[1] github 上的報告列表:??https://github.com/danluu/post-mortems??
點擊此處,前往故障演練 Chaos 主頁查看更多詳情!
總結(jié)
以上是生活随笔為你收集整理的云原生背景下故障演练体系建设的思考与实践—云原生混沌工程系列之指南篇的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 来了,「年度最强技术答辩」看这里
- 下一篇: 2021 阿里云容器服务年度盘点:企业级