Kubernetes漏洞搞垮了應用程序!癱瘓 1 個小時
Monzo的技術負責人詳細描述了這次故障的具體原因。
由於四個月前就已存在的一個Kubernertes漏洞(https://github.com/kubernetes/kubernetes/issues/47131),英國網上銀行初創公司Monzo上周五的服務中斷了一個多小時。
據Monzo的工程負責人奧利弗?貝蒂(Oliver Beattie)聲稱,「由於一連串不幸的事件」,這個漏洞導致整個生產集群癱瘓,著名作家萊蒙尼?斯尼克特(Lemony Snicket)也許會將這起事件取「致命缺陷」(Fatal Flaw)這個標題。
客戶們在此期間看到收款延遲、付款失敗。 Monzo作為一家基於互聯網的銀行來運作,客戶通過其智能手機應用程序來訪問,它提供活期存款賬戶、預算編製工具和開支警告等服務。
周一,貝蒂公布了分析這起事件的結果(https://community.monzo.com/t/current-account-payments-may-fail-major-outage/26296/95),歸咎於Kubernetes及其與相關軟體不兼容。
貝蒂解釋道,Monzo的架構依賴Kubernetes用於集群編排、分散式資料庫etcd以及管理集群路由和負載均衡的軟體linkerd。
出現故障前兩周,Monzo的平台團隊剛將其etc集群升級到了新版本,並將規模從三個節點擴展到了九個節點。沒想到這麼一來,他們實際上為故障埋下了隱患。周四,一個工程團隊為賬戶持有人部署了一項新功能,但是開始看到問題隨之出現,於是相應縮減了服務,以便該服務不在任何副本上運行,但仍作為一項Kubernetes服務而運行。
周五大約14:10(英國標準時間)前後,工程團隊對用於處理付款的一項服務進行了更改。這時,客戶開始遇到付款失敗。兩分鐘後,恢復了這一更改,但問題依然存在。
到14:18,Monzo的工程師們查明了問題原來出在linkerd上。這個軟體沒有收到Kubernetes發來的關於新的pod在網路上何處運行的最新消息,因而將請求路由至不再有效的IP地址。
14:26,他們決定重新啟動在後台運行的數百個linkerd實例,覺得這麼做有望全面解決問題。但是計劃落空了,原因是運行集群節點的Kubelet(每個節點上運行的主要「節點代理」)無法從Kubernetes apiserver獲取配置數據。
工程師們懷疑另外的問題在影響Kubernetes或etcd,於是重啟了三個apiserver進程。到15:13,所有的linkerd pod已重新啟動。不過銀行應用程序的服務沒有收到任何請求。到這個時候,平台完全癱瘓了。
15:27,工程師們注意到:試圖讀取來自apiserver的服務發現響應時,linkerd將NullPointerException(空指針異常)記入日誌。他們意識到之所以無法解析空的響應,正是由於運行的Kubernetes和linkerd的版本彼此不兼容。
為了恢復服務,他們改而使用在該公司的過渡環境(又譯登台環境,staging environment)中測試的更新版linkerd。進行了必要的版本升級後,他們認識到:只要刪除沒有副本的服務,就可以避免試圖解析這類服務引起的錯誤。這讓linkerd得以恢復其服務發現,平台開始恢復如初。
貝蒂表示,他的團隊「在Kubernetes和etcd客戶端發現了一個漏洞,在重新配置集群(就像我們在上一周執行的那種操作)後,這個漏洞會導致請求超時。由於這種超時,服務部署後,linkerd無法從Kubernetes收到關於可以在網路上何處找到它的最新消息。」
他表示,重新啟動linkerd實例讓問題更複雜化,因為它揭露了特定版本的linkerd和Kubernetes之間的不兼容性。
貝蒂總結道:「我想要對每個人保證,我們非常重視這起事件;這是我們公司有史以來發生的最嚴重的技術事件之一,我們的目標是經營一家客戶可以永遠依賴的銀行。我們知道我們讓大家失望了,對此深表歉意。」
真誠的道歉似乎受到了客戶的好評,許多客戶對詳細披露和解釋原委的做法表示了讚賞。
推薦閱讀:
※容器編排Kubernetes之kube-dns源碼解讀
※Kubernetes v1.7新特性解析-Secret加密存儲
※漫畫:小黃人學 Kubernetes Service
TAG:Kubernetes | 漏洞 |