在 Ali Kubernetes 系统中,我们这样实践混沌工程
在傳統(tǒng)的軟件測(cè)試中,我們通常通過(guò)一個(gè)給定的條件來(lái)判斷系統(tǒng)的反饋,通過(guò)斷言來(lái)判斷是否符合預(yù)期,測(cè)試條件和結(jié)果通常比較明確和固定。而混沌工程,是通過(guò)注入一些“不確定”因素,象放進(jìn)了一群淘氣的猴子,在系統(tǒng)資源、可用性、安全性、延遲、壓力等方面進(jìn)行搗亂,而此過(guò)程中,要求系統(tǒng)可以毫無(wú)影響的提供服務(wù),用戶無(wú)感知。
這其實(shí)對(duì)系統(tǒng)的自愈能力,健壯性都有很高的要求。故障注入一般是指比較受控的一些實(shí)驗(yàn)條件,通過(guò)注入一些相對(duì)極端的異常場(chǎng)景,為系統(tǒng)提供可靠性測(cè)試的過(guò)程。 整體來(lái)說(shuō),混沌是一種故障注入規(guī)則,強(qiáng)調(diào)了一些不確定性、隨機(jī)性,比較常見(jiàn)的"猴子"有 Netflix 的"猴子軍團(tuán)",可以用來(lái)隨機(jī)關(guān)閉系統(tǒng)實(shí)例,注入延時(shí),回收資源,檢查安全漏洞等等。
開(kāi)源工具介紹
除了一般系統(tǒng)的 monkey,基于 Kubernetes 已經(jīng)有一些"猴子"工具可以測(cè)試系統(tǒng)的健壯性。接下來(lái),介紹一下比較常見(jiàn)的三種 Kubernetes monkey:
kube-monkey
https://github.com/asobti/kube-monkey
- 運(yùn)行方式:kube-monkey 通過(guò) label 設(shè)置受害者 pod,創(chuàng)建了一個(gè)單獨(dú)的 kube-monkey pod 對(duì)受害者 pod 施加影響;
- 注入類型:目前支持的故障注入類型僅有殺容器;
- 配置項(xiàng):可以通過(guò)配置文件設(shè)置運(yùn)行周期和頻率,在一定時(shí)間內(nèi)隨機(jī)的殺死打標(biāo)范圍內(nèi)的 pod。
powerfulseal
https://github.com/bloomberg/powerfulseal
- 注入類型:powerfulseal 的故障注入類型包括殺 pod 和啟停 node。
- 運(yùn)行方式:包括交互模式,自動(dòng)模式、打標(biāo)模式和示例模式。交互模式通過(guò)界面交互查詢node/namespace/pod,啟停 node 或殺死 pod 操作;自動(dòng)模式通過(guò)讀取配置文件確定注入范圍,注入頻率;打標(biāo)模式通過(guò)給 pod 打標(biāo)確定注入的靶向 pod 及注入頻率;示例模式可以反映根據(jù)使用資源情況進(jìn)行故障注入的過(guò)程。
Chaos Toolkit-kubernetes
https://github.com/chaostoolkit/chaostoolkit-kubernetes
是 chaos 工具包中的一個(gè),通過(guò) chaos run experiment.json 設(shè)置 json 文件來(lái)指定 namespace,正則匹配名字等等來(lái)隨機(jī)殺一個(gè) pod。
以上三種"猴子",主要是基于殺 pod 場(chǎng)景來(lái)注入故障,雖然是最有力的場(chǎng)面但是比較有局限性,對(duì)于商業(yè)化系統(tǒng)面臨的復(fù)雜場(chǎng)景,是值得參考但是不夠的。
結(jié)合 Ali Kubernetes 故障場(chǎng)景分析
Ali Kubernetes 作為一個(gè)管理大規(guī)模集群的商業(yè)調(diào)度系統(tǒng),需要應(yīng)對(duì)的不僅包括一些基本的 Kubernetes 中 pod 誤刪誤停的故障現(xiàn)象,也包含一些底層 OS、內(nèi)核、網(wǎng)絡(luò)、誤配置等災(zāi)難場(chǎng)景。同時(shí)由于其支撐業(yè)務(wù)生態(tài)的復(fù)雜性,全鏈路綜合異常流也需要特殊的驗(yàn)證。
為更系統(tǒng)的進(jìn)行演練,在過(guò)程中主要進(jìn)行了以下幾部分工作:
FMEA 分析就是失效模式和效果分析,旨在對(duì)系統(tǒng)范圍內(nèi)潛在的失效模式加以分析,以便按照嚴(yán)重程度加以分類,或者確定失效對(duì)于該系統(tǒng)的影響。
從故障場(chǎng)景上,分析得出較為符合 Ali Kubernetes 的三大類場(chǎng)景:
- 通用故障場(chǎng)景:包括網(wǎng)絡(luò)相關(guān)故障(網(wǎng)絡(luò) iohang ,斷網(wǎng),網(wǎng)絡(luò)延遲等),宿主機(jī)相關(guān)故障(機(jī)器重啟,機(jī)器 load 高等)
- Ali Kubernetes 業(yè)務(wù)場(chǎng)景故障:包括 Kubernetes 相關(guān)的故障(pod 刪除,pod patch等),pod 遷移,混部、etcd 等業(yè)務(wù)相關(guān)場(chǎng)景;
- chaos 故障:較為隨機(jī)的故障注入,可以為以上任何故障的組合
?
從影響面上,需要 case by case 確定影響范圍為無(wú)任何影響,僅影響部分功能,影響核心功能等等;從驗(yàn)證恢復(fù)手段上,也可以分為自動(dòng)恢復(fù)、手動(dòng)恢復(fù),同時(shí)需要關(guān)注監(jiān)控情況及恢復(fù)時(shí)間。
在分析過(guò)程中,我們發(fā)現(xiàn),已有的開(kāi)源工具無(wú)法完全滿足 Ali Kubernetes 的故障場(chǎng)景。下面舉 2 個(gè)典型故障場(chǎng)景:
pod 被誤刪
這個(gè)場(chǎng)景并不是簡(jiǎn)單的 pod 隨機(jī)刪除,而是在 kubelet 連錯(cuò) apiserver 配置等異常情況下,重啟 ali-kubelet 后,al 自行判斷了容器在當(dāng)前集群內(nèi)不存在,自己做了刪除操作。
要引入這個(gè)故障需要修改 kubelet 組件的配置,重啟 kubelet,才算是真正引入了故障,而當(dāng)前的無(wú)論是 kube-monkey 還是 powerfulseal 場(chǎng)景都無(wú)法滿足。
master 組件斷網(wǎng)
有的人可能會(huì)說(shuō),直接指定 master 組件的機(jī)器引入斷網(wǎng)操作,是不是就可以了呢?然鵝現(xiàn)實(shí)是比較骨感的,我們也許只知道這個(gè) master 所在集群的 kubeconfig,組件的機(jī)器其實(shí)也可以隨著每次升級(jí)變動(dòng)的。在僅僅已知 kubeconfig 的情況下我們只能先查一下 master 組件的機(jī)器信息,再在機(jī)器上引入斷網(wǎng)的操作,才算是一個(gè)整體的故障引入。而目前所有的開(kāi)源工具也沒(méi)有此類稍微復(fù)雜一些的場(chǎng)景,只是通過(guò)指定 pod namespace 來(lái)隨機(jī)的刪除一些 pod。
所以綜上所述,其實(shí)我們需要對(duì)此進(jìn)行擴(kuò)展開(kāi)發(fā),除了簡(jiǎn)單的殺 pod,我們亟需一套可以自由開(kāi)發(fā)的小程序,把這個(gè)步驟拼接起來(lái),進(jìn)行更為復(fù)雜的故障注入。
套件實(shí)現(xiàn)
為了滿足此類復(fù)雜的故障注入,我們使用了目前集團(tuán)內(nèi)正在開(kāi)發(fā)的一套故障注入系統(tǒng) monkeyking,并在它的基礎(chǔ)上擴(kuò)展了一些 kubernetes 相關(guān)的套件,來(lái)達(dá)到既可以注入 kubernetes 相關(guān)的故障,又可以注入一些通用故障,同時(shí)又可以相對(duì)自由的擴(kuò)展故障集合的目的。
這個(gè)故障注入的演練流程如下圖所示:
它的每一個(gè)步驟都可以是我們自由擴(kuò)展的一個(gè)或者多個(gè)小程序,各個(gè)小程序之間的執(zhí)行順序也可以自由的定義。考慮到 Ali Kubernetes 的場(chǎng)景,我們?cè)谄渲袛U(kuò)展了四大類小程序套件。
通用故障小程序
在這一部分主要實(shí)現(xiàn)了一些比較通用的 os 故障,網(wǎng)絡(luò)故障,比如最基本的指定一個(gè)宿主機(jī)斷網(wǎng),指定宿主機(jī)重啟這類。
Kubernetes 套件小程序
這一部分主要實(shí)現(xiàn)了一些通用的 Kubernetes 命令,通過(guò)指定這些命令和入?yún)?#xff0c;我們可以執(zhí)行比如 create delete apply patch 這些操作,來(lái)間接的達(dá)到注入一些 Kubernetes 相關(guān)故障的目的。
實(shí)現(xiàn)原理如下:
要點(diǎn)說(shuō)明:
- 下載集群證書(shū)的地址及證書(shū)的 md5 碼都作為小程序的輸入,在執(zhí)行實(shí)際的 kubectl 生效命令前進(jìn)行下載校驗(yàn);
- 底層 toolkit 中已經(jīng)加入了 kubectl 命令行工具,無(wú)需自己找環(huán)境進(jìn)行配置和下載;
- 目前已經(jīng)支持了 apply,create,delete,patch,get 操作,支持指定 label,namespace,-o json 的操作
舉個(gè)例子,上文中 master 組件故障的場(chǎng)景中,我們就可以利用以上的兩類小程序來(lái)完成故障注入的操作:
開(kāi)源工具小程序
目前我們和集團(tuán)安全生產(chǎn)的 MonkeyKing 團(tuán)隊(duì)合作,聯(lián)合在故障注入平臺(tái) monkeyking 中集成了開(kāi)源工具 kube-monkey,實(shí)現(xiàn)過(guò)程借助了上文的 kubernetes 套件執(zhí)行,可以通過(guò)打標(biāo)的方式標(biāo)記受害者,讓 kube-monkey 隨機(jī)的殺受害者 pod。步驟如下:
環(huán)境準(zhǔn)備
- 鎖演練環(huán)境
- 在當(dāng)前集群中初始化kube-monkey: 使用kubernetes套件的apply功能提交km-config.yaml文件,部署 kube-monkey deployment
**
給應(yīng)用標(biāo)記受害者 label
- 使用 Kubernetes 套件的 patch 功能,標(biāo)記受害者
**
驗(yàn)證步驟
- 自定義組件校驗(yàn)應(yīng)用服務(wù)是否可用
**
故障恢復(fù)
- 使用 Kubernetes 套件的 patch 功能,給受害者去標(biāo)
- 使用 Kubernetes 套件的 delete 功能,刪除 kube-monkey deployment
- 解鎖演練環(huán)境
其他業(yè)務(wù)相關(guān)小程序
這一部分比較自由,主要根據(jù) Ali Kubernetes 的業(yè)務(wù)需求,接入了一些常用的小程序。
比如故障演練過(guò)程中,環(huán)境需要獨(dú)占,不允許其他測(cè)試執(zhí)行,在這里實(shí)現(xiàn)了一個(gè)小程序用來(lái)對(duì)環(huán)境進(jìn)行加解鎖操作;比如校驗(yàn)階段需要驗(yàn)證服務(wù)是否可用,這里實(shí)現(xiàn)了一個(gè)通過(guò) curl 命令校驗(yàn)返回值的方式驗(yàn)證服務(wù)是否可用的小程序;比如故障注入過(guò)程可能影響vip掛載,這里也實(shí)現(xiàn)了一個(gè)調(diào)用 vip 服務(wù)校驗(yàn) vip 下 ip 數(shù)量及是否可用的小程序。
總結(jié)
在 Ali Kubernetes 中,我們將故障以場(chǎng)景化的方式進(jìn)行沉淀,將底層 os,內(nèi)核、網(wǎng)絡(luò)、誤配置等故障聯(lián)合 Kubernetes 相關(guān)故障,引入混沌工程的理念進(jìn)行注入,有效的發(fā)現(xiàn)了很多系統(tǒng)穩(wěn)定性問(wèn)題,驅(qū)動(dòng)開(kāi)發(fā)人員更多關(guān)注系統(tǒng)健壯性。
后續(xù)我們會(huì)在 Ali Kubernetes? 演進(jìn)過(guò)程中持續(xù)發(fā)力,基于架構(gòu)和業(yè)務(wù)場(chǎng)景輸入更多 Kubernetes 相關(guān)的故障場(chǎng)景,為系統(tǒng)的高可用保駕護(hù)航。
原文鏈接
本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。
總結(jié)
以上是生活随笔為你收集整理的在 Ali Kubernetes 系统中,我们这样实践混沌工程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 阿里云发布时间序列数据库TSDB,关于时
- 下一篇: 构建可靠系统的原则与实践