1. 程式人生 > >k8s 開船記-故障公告:自建 k8s 叢集在阿里雲上大翻船

k8s 開船記-故障公告:自建 k8s 叢集在阿里雲上大翻船

非常非常抱歉,新年上班第一天, 在今天阿里雲上氣候突變情況下,由於我們開船技術差,在今天 10:15~12:00 左右的訪問高峰,我們竟然把船給開翻了,造成近2個小時整個部落格站點無法訪問,由此給您帶來很大很大的麻煩,懇請您的諒解。

翻船經過如下。

FQ前的船隻情況

部落格站點正在使用的 k8s 叢集一共用了 9 臺 worker 節點伺服器,在訪問低峰時用 5 臺,另外 4 臺處於關機狀態,在進入訪問高峰前啟動。所以我們用 cron 定時任務在工作日每天早上啟動 4 臺伺服器,每天晚上關閉 4 臺伺服器。為了節約成本,這 4 臺伺服器用的是阿里雲搶佔式例項,由此帶來的風險是如果啟動時當前可用區對應的例項庫存不足,就會啟動失敗。

還有一個正在搭建中的高可用 k8s 叢集,執行著 1 臺 master 與 1 臺 worker 節點,另外 2 臺 master 與 1 臺 worker 處於關機狀態。

在 k8s 叢集之前使用的 docker swarm 叢集處於待棄用狀態,執行著 1 臺 manager 與  1 臺 worker 節點,其他節點都處於關機狀態,用的也是阿里雲搶佔式例項。

風雲突變,船隻顛簸

今天新年上班第一天,阿里雲上生意非常火爆,我們的伺服器所在可用區的所有4核8G的搶佔式例項全部售罄,造成定時啟動 k8s 叢集節點伺服器的任務全部失敗,僅有的 5 臺伺服器在訪問高峰不堪重負,開始出現 502 ,當我們發現後,嘗試通過阿里雲 ecs 控制檯啟動這些伺服器,但依然因庫存不足而無法啟動。

操作有錯誤發生:
i-bp10c3nww9y26s9yppcq : 庫存不足,請您嘗試其它型別的例項規格 或者 其它可用區/地域的例項。您可以選擇變配到其他規格,然後啟動。更改例項規格
RequestId: 86752D85-39F0-4FEC-875B-80A3269D0B23

緊急自救,卻遭意外雷擊而翻船

手動啟動伺服器失敗後,我們趕緊新購伺服器新增到叢集,本以為等伺服器加好就能恢復,哪知卻遭遇新的意外情況,新加伺服器上所有部落格站點的 pod 都啟動失敗。

NAME             READY   STATUS              RESTARTS   AGE 
blog-web-bw87z   0/1     CrashLoopBackOff    4          4m36s

Pod 啟動失敗是因為其中的部落格站點容器 dns 解析失敗,無法解析所依賴的服務的地址。

接著情況變得越來越嚴重,不僅新加伺服器因 dns 解析問題無法啟動 pod ,而且叢集中已有伺服器也因為這個問題無法啟動 pod 。本來已有 5 臺還能支撐部分請求,但由於這個意外的 dns 解析問題,叢集中除了1-2臺部落格應用的 pod 還在執行,其他全掛了,這時整個部落格站點全是 502 錯誤,k8s 巨輪就這麼翻了。

救援行動,舊漁船挺身而出

巨輪翻了後,我們開始救援行動,首當其衝就是另外一艘建造中的更高階的巨輪 —— k8s 高可用叢集,新購伺服器加到這個叢集,準備用這個叢集處理負載,哪知這個叢集也出現了異常情況,pod 也是無法啟動,一直處於 ContainerCreating 狀態。

NAME                            READY   STATUS              RESTARTS   AGE
blog-web-b2ggt                  0/1     ContainerCreating   0          4m48s

Error from server: Get https://10.0.2.82:10250/containerLogs/production/blog-web-b2ggt/blog-web: dial tcp 10.0.2.82:10250: connect: connection refused

這時唯一的救命稻草就是那艘準備棄用的舊漁船 —— docker swarm 叢集,這個叢集中處於關機狀態的節點伺服器也因為庫存不足而無法啟動,只能新加伺服器,趕緊把 k8s 叢集中的那些伺服器拿過來用映象更換系統後加入 docker swarm 叢集。

sudo rm -rf /var/lib/docker/swarm && \
service docker restart && \
docker swarm join --token xxx 10.0.151.251:2377

當 docker swarm 叢集投入使用並加到一定量的伺服器後,部落格站點才恢復正常。

開船的迷茫

恢復正常後,我們立即去排查出現 dns 解析問題的 k8s 叢集,發現所有 worker 節點都出現了 dns 解析問題, 上次我們也被 dns 解析問題坑過(詳見 k8s 開船記:升級為豪華郵輪(高可用叢集)與遇到奇怪故障(dns解析異常)),只是上次只有部分節點出現這個問題,這次是所有 worker 節點,上次是通過重啟伺服器解決的,難道這次也要重啟才能解決?

於是將 worker 節點全部重啟,重啟後所有 pod 都正常運行了,這時我們恍然大悟,後悔莫及,當時營救翻船最簡單快速的方法就是重啟所有 worker 節點伺服器。

開著舊漁船,回想著靠岸待修理的巨輪,望著茫茫大“雲”,我們更加迷茫了。使用 docker swarm 時多次遭遇奇怪的網路問題,通過重啟節點伺服器解決,開始我們懷疑水(雲),後來我們懷疑船(docker swarm),於是下定決心換掉漁船,換上巨輪(k8s),結果又遇到到了奇怪的網路問題(dns 解析問題是網路問題引起的),現在我們該懷疑誰呢?.

對於這次大翻船,最重要的原因是我們過多地使用了搶佔式例項,是我們的過錯,我們會吸取教訓,調整伺服器的部署。

這次大故障給您帶來麻煩了,再次懇請您的諒解。