2022 AWS Summit — 您的 Amazon EKS 經歷過混沌工程嗎?了解如何在 Kubernetes 測試破壞性事件以防患未然

身為DevOps工程師
9 min readAug 13, 2022

--

這次很榮幸能去參加AWS Summit擔任Speaker,負責一個議程。台下的觀眾數量也比我預期來得多,至少三、四百個。其實已經打破我目前上台演講的觀眾紀錄了。

以下針對這次演講的主題,做一個文章的分享。也順便讓自己可以整理一下這段時間的內容以及更新一下停置多時的部落格 QQ。

什麼是混沌工程?

簡單地用一句話來形容的話,就是對服務進行一些破壞性相關的測試。

e.g. cpu, memory沒辦法正常使用, 硬碟壞軌, 機器突然重開機

與一般的軟體測試不同。在軟體測試中,我們會對開發好的application,進行一連串的input。然後預期它會給出什麼樣的output。但對於混沌工程來說,就不是這麼一回事了。

我們其實除了需要擔心application有沒有bug外,有一種情況是發生了非bug的事件,而造成了application沒辦法正常運作。

在混沌工程中,就是要去模擬,如果發生這種破壞性事件,會有什麼樣的影響。這樣才可以去讓我們可以知道,如果這種情況發生,系統還能不能一切正常的服務。

混沌工程建議注意事項

在我們進行混沌工程的時候,有幾點是我們需要特別去注意的

盡可能小的範圍

今天,我們的混沌工程,可能是在Production的環境上執行。大家都知道Production環境如果被我們混沌工程跑到掛掉了,那我們大概離回家吃自己不遠了。為了不要讓這樣的事情發生,請記得一開始的範圍,盡可能不要做得太大,就算只是一點點的不穩定,只要對使用者的體驗造成了不好的影響,其實都不是個好事。

定義判斷穩定的條件

另外,記得要先設定好,什麼樣的條件下,才可以算是通過了這次混沌工程的測試。不然執行下去後,沒有任何的判斷條件,感覺好像是跑來自嗨的。

最後記得,請模擬現實生活中,有可能會發生的。有一些太浮誇 不太可能的情境,請直接把它忽略。

有什麼好處?

混沌工程有什麼好處呢?會想套用混沌工程的企業他們圖的是什麼?

關於這個問題,最直接的答案就是

提升系統的容錯性

想要去提升系統的容錯性,畢竟有一個測試,它會來幫我測說,如果今天隨機的少了幾個節點,系統是不是仍然可以正常的服務

再來就是當發生這些破壞性的事情時,我們的monitor機制設計的夠不夠好,能不能夠讓我們可以迅速地找出發生了什麼問題。

最後這點,也是最重要的一點了吧

如果整體都做得非常完美了。

大家對自己的系統也會更有自信,假日跟晚上才有好日子可以過啊

什麼樣的地方適合 ?

高度重視 SLA 的企業,例如:

  • 電商
  • 金融
  • 遊戲
  • 串流影音

其實什麼地方都可以導入,但這邊如果照優先度來排的話。越高度重視服務SLA的企業,越會推薦他們可以花一些時間,來做這樣的測試。

像是電商,假如今天電商機房發生了破壞性事件。服務停止了一個小時,整整一個小時沒有辦法讓消費者到上面購物,甚至沒辦法讓廠商讀取到出貨相關的資訊。這個損失是相當龐大的。

為了預防這樣的情況發生,就很適合藉由混沌工程的方式,盡可能讓系統處於一個擁有很高容錯的環境之下。

工具介紹

  1. AWS FIS(Fault Injection Simulator)
  2. kube-monkey
  3. kubedoom

AWS FIS(Fault Injection Simulator)

在最一開始,我們要先去建立一個Template出來,藉由這個Template,我們可以去啟動各種實驗。在Template中,我們可以去設定Action, Target與要停止的條件是什麼,如果條件達成了,就會自動停止。

如果條件一直沒有達成,那它就會一直執行到完成為止。完成之後我們就可以去判斷結果是不是有符合預期了。像是Alarm有沒有如預期的觸發, 服務有沒有正常的運作。

這邊列出幾個FIS的ActionType

  • ec2: reboot-instances
  • ec2: stop-instances
  • eks: terminate-nodegroup-instances
  • ssm: send-command

除了直接對ec2做開關機外及eks的teminate nodegroup外,還可以搭配System Manager SSM。搭配SSM後,就可以去執行我們自己定義script,把script送到instance去執行。因為有可以自行定義script的彈性,所以我們可以針對不同的情境做不同的測試。像是模擬CPU 有高度壓力以至於Application無法正常使用的情況下,會做出什麼樣的反應。

既然可以自行定義Script,就也可以在Script中把Memory 以及IO的效能用盡來達到不同類型的混沌工程測試

kube-monkey

附上kube-monkey的GitHub
https://github.com/asobti/kube-monkey

講到kube-monkey就要先提一下Netflix 開源出來的混沌工程工具Chaos Monkey。Netflix可以算是數一數二有在使用混沌工程的大企業了,他們開源出來的工具,也是有很高的知名度。

Chaos Monkey提供了用TOML的格式來編寫confing,在config中我們可以進行各種的客製化設定。像是我可以去設定 start_hour、end_hour。讓每一次的混沌工程可能在早上七點的時候開始,十二點的時候停止。

那開啟之後可以幹嘛呢?這個Chaos Monkey會用隨機的方式,去把instance關閉。

而kube-monkey是在k8s上的Chaos Monkey,也支援著排程的機制。我可以去設定每週甚至是每天都會進行一次的混沌工程。

kube-monkey將隨機關閉的目標從instance修改為Pod。kube-monkey在開始執行之後,會去隨機的殺掉Pod。藉由這樣子的方式,我們可以知道在Pod會被屠殺的情況下,是不是還能夠讓整體維持著正常的模式。

如果想安裝看看,可以直接用helm進行安裝。為了可以直接體會到它的效果,可以照下面修改values.yaml。

# 預設為開啟,讓kube-monkey會真的去動作
dryRun: false
# kube-monkey只會去殺掉whitelistedNamespaces的Pod
whitelistedNamespaces: ["default"]
# 開啟debug模式,讓kube-monkey可以馬上執行動作
debug:
enabled: true
schedule_immediate_kill: true

執行安裝

helm install my-monkey . -f values.yaml

安裝完成後,不會有任何的Pod被殺掉。必須要設定好對應的lebel才會是獻祭給kube-monkey的Pod。

YAML範例
https://github.com/asobti/kube-monkey#example-of-opted-in-deployment-killing-one-pod-per-purge

# 開啟kube-monkey刪除Pod
kube-monkey/enabled: enabled
# 這個application的識別名稱,建議可以直接跟name一樣就好
kube-monkey/identifier: monkey-victim
# 幾個工作日 kube-monkey 會停止一次Pod
kube-monkey/mtbf: '2'
# kube-monkey停止Pod的模式。預設只會停止一個Pod
# fixed代表會停止固定個數的Pod
kube-monkey/kill-mode: "fixed"
# 被停止的Pod個數
kube-monkey/kill-value: '1'

kubedoom

附上kubedoom的GitHub
https://github.com/storax/kubedoom

最後這個小遊戲,是希望可以用一個比較有趣的方式,來呈現混沌工程的含義。如果要進行比較正規的混沌工程,還是比較建議使用前面兩個工具。

不知道在座的各位在小時候有沒有玩過一個叫毀滅戰士DOOM的遊戲?為什麼要提到這個遊戲呢?

大家都知道在網路上高手雲集,有些人也會特別的熱心。其中就有人把doom跟k8s做了結合,叫做kubedoom。這個kubedoom的Project會在k8s上起一個Pod,這個Pod起來之後,我們就可以用VNC 的方式,連線到kubedoom中。在kubedoom這個遊戲裡面,我們可以用各種不同的武器。去攻擊裡面的怪獸。

但那些怪獸,其實不是一般的怪獸。

那些怪獸,是我們開啟的Pod。

如果想安裝kubedoom也很簡單。直接clone下來,執行kubectl apply就可以了。

git clone https://github.com/storax/kubedoom.git
kubectl apply -k manifest/

如果是架設在EKS上,可以多加一步 port-forward來讓自己筆電的VNC Viewer可以連線過去。如果連線成功,就會看到類似上面圖片的畫面囉!

kubectl port-forward deployment/kubedoom 8585:5900 -n kubedoom

Summary

混沌工程這個名詞,其實目前還沒有這麼普遍的被大家所認識。但這項技術其實對整個系統朝向更好的系統是很重要的。畢竟,大家看到的是服務能不能正常的使用,而不是服務是不是都沒有Bug。最重要的還是讓服務可以持續地被使用。

希望藉由以上的介紹,可以讓大家對混沌工程有更清楚的認識。

--

--

身為DevOps工程師

目前在蓋亞資訊擔任DevOps Consultant。最近才從後端的世界轉成投向DevOps的懷抱,目前專注在Kubernetes, GitLab, DevSecOps的學習中。