歡迎光臨
每天分享高質量文章

雖然驚天地,但不是人人都會哭泣 ——再論Kubernetes驚天地泣鬼神之大Bug

前幾天,朋友圈裡瘋轉了一篇知乎上的帖子,《Kubernetes 驚天地泣鬼神之大Bug》。很多朋友看到了帖子,紛紛轉發給我以表慰問。看到該bug會影響到所有的Kubernetes叢集,嚇得我趕緊吃根辣條冷靜一下。
線上上的巡檢郵件梳理了一遍,貌似沒發現異常。冷靜下來再想想,以我們的叢集規模,如果真有這個bug,那麼早就該發現了,為何到現在沒有爆出來。按照作者的觸發方式,我進行了反覆的實驗,怎麼也觸發不了。我感覺又不淡定了,啥情況,不是說所有的都會影響麼?為啥觸發不了?我決定追根溯源,來找找到底為啥會出現這樣的問題。
此bug,按照作者的描述,基本上是這樣的,對於Kubernetes的某一種資源(不僅是service,其他的資源一樣應該也是如此),如果先建立一個最早的物件a,然後再執行一些建立物件的操作,最後再刪除那個最早的物件a,此時watch到的刪除event中的物件a的resourceVersion不是期待的一個最新最大的resourceVersion,而是最早建立這個物件a時的建立event中的那個老的resourceVersion,從而導致controller-manager的一些回放event的行為。對應到資源service上就是作者描述的service的刪除建立被回放,導致其所屬的endpoint的消失和重建,從而造成服務的不穩定性。
看完我們立刻在自己的環境上驗證,看是否可以重現,結果是未能重現,實驗結果如下,所有event的object的resourceVersion都是遞增的。
這與作者描述的完全不符合啊。算了,我們還是去原始碼裡找答案吧。
delete時間的resourceVersion是在這裡,在我們的主力版本(1.6)上,該程式碼是這樣的。

這裡的入參 watchCacheEvent的event是從etcd中獲取的。我們使用命令列從etcd中把這些事件抓取出來。
其中kv對應的是event中的Object,prev_kv對應的是event中的PrevObject。紅線圈出的Delete情況的event.preObject的resourceVersion是此物件上一次event的mod_revision,因此會小於Object的resourceVersion。這樣我們就可以理解了,在1.6版本中,始終是以當前的Object的resourceVersion作為watch event的resourceVersion,這樣所有的event中的resourceVersion都是遞增的。這個是沒有問題的。
而在1.7+的版本中,該程式碼是這樣的。

這個時候,watch event的resourceVersion變為了PreObject的,這樣就必然存在在watch的event的resourceVersion不是嚴格遞增的,當遇到delete事件時,會傳回到前面某個event的resourceVersion上去的問題。
之後社群的修複#58547後的程式碼是這樣的。

這裡可以看到,watch event的resourceVersion被更新為了event的ResouceVersion,重新保證了event的resourceVersion始終是遞增的。
在對比了GitHub上的commit記錄,可以看到,此bug是在#46223這個pr中引入的。該pr被合入到1.7.0之後的版本,可以參見https://github.com/kubernetes/kubernetes/commit/e9e69356e4907fa4d0f45ea7e7768357ba71aba9#diff-dc17590f6b960d2fea2b44de5c0fbc10
而社群在#58547這個pr中修複此問題,也就是說可以對比https://github.com/kubernetes/kubernetes/commit/57998d247df74cc96547158a0b39e5d7bffa271b#diff-dc17590f6b960d2fea2b44de5c0fbc10中之後的版本得以修複。因此受影響的版本主要是介於兩個pr之間的版本。
這裡我們介紹一下復現的方法,大家可以參照來自檢下自己的叢集是否需要修複。
Kubernetes版本不斷向前發展,這其中會有老的bug被修複,也可能會有新的bug被引入。這些對於社群都是很正常的。但是對於生產環境來說,又是存在著較大的風險的。在實際生產過程中,我們開發了一系列的周邊工具和運營監控系統,用以保證叢集的穩定。畢竟穩定可靠對於生產環境來說,才是最基本的原則。
本文轉載自公眾號:TIGCHAT,點選檢視原文

Kubernetes入門與進階實戰培訓

本次培訓內容包括:Docker基礎、容器技術、Docker映象、資料共享與持久化、Docker三駕馬車、Docker實踐、Kubernetes基礎、Pod基礎與進階、常用物件操作、服務發現、Helm、Kubernetes核心元件原理分析、Kubernetes服務質量保證、排程詳解與應用場景、網路、基於Kubernetes的CI/CD、基於Kubernetes的配置管理等,點選瞭解具體培訓內容
6月22日正式上課,點選閱讀原文連結即可報名。
贊(0)

分享創造快樂