image

上篇文章《Kubernetes 集羣 Node 間歇性 NotReady,查到最後竟然是這個原因》裏提到的問題遇到了新情況。之前用 iostat -x 觀察到磁盤的 %util 一直穩定在 100,磁盤讀寫延遲有時候高達 20 秒,在有狀況的機器上能夠找到正在大量刷日誌的進程。

最近發現一個新情況,有的 node 節點偶爾出現 %util 達到 100 的情況,持續時間不長,登錄查看的時候偶爾能看到,同時磁盤的讀寫極少,讓人有些困惑。

這個新情況出現頻率不高,暫時沒有調查思路,先強化這方面的監控,看後續能不能找到蛛絲馬跡。另外上週得到一個意外信息,node 節點是 IaaS 上的虛擬機,如果虛擬機所在的物理機的 IO 過高,虛擬機的 IO 操作會被限制,和新情況可能有關係。

言歸正傳,這裏記錄一下 Ingress 使用過程中遇到的奇葩問題和調查結果。這裏記錄的問題現象和調查過程,有可能是我在不同的公司遇到的,可能是正式生產環境中的集羣上發生的,也可能是隨便搗鼓的小集羣上發生的,這裏的重點不是如何實踐,而是問題現象和排查思路。

基於 haproxy 時遇到 503

很早之前使用基於 haproxy 的 ingress,比較頻繁地遇到 503 響應碼,業務方不停地喊,哎,503 啊,這種狀態持續了比較長的時間,那種綿延不絕被刺激而又束手無策的狀態,簡直酸爽......

硬着頭皮啃完全不熟悉的 haproxy 文檔,一天天從早到晚地試驗琢磨,好在終於有所發現。返回 503,表示 haproxy 沒有找到當前請求的 Host 對應的配置規則,但是查看配置文件,配置文件中是有的,問題有些詭異。

不停地嘗試復現,同時觀察 haproxy 進程的狀態,終於發現了端倪:因為端口複用,同時有多個 haproxy 進程在監聽 80 端口,這些 haproxy 進程中,有一部分進程的內存中加載的是舊的配置,沒有加載最新的配置文件。

當請求被分給那些內存中依然是舊配置的 haproxy 進程時,haproxy 會因為找不到對應的轉發規則而返回 503。

這個問題很隱蔽,磁盤上的配置文件是全新的,內存是舊的,且只有部分 haproxy 進程的內存是舊的,檢查配置文件不能發現問題。這些進程上面的連接全部斷開後,haproxy 進程會主動退出,問題會消失。要在配置變化前用一個長連接卡住舊的 haproxy 進程,不讓它退出,才能穩定復現問題。

為什麼會出現這種情況,坦白講,就和以前遇到的很多問題一樣,沒有查出所以然,也沒有人關心認可這些事......但有效地解決方法找到了,只要在 haproxy 每次更新的時候,對所有的 haproxy 進程再發送一次信號就可以,用** -sf 指定所有已經存在的 haproxy 的進程號**,而不是隻指定上一個 haproxy 進程。


估計已經沒有多少人在用 haproxy 作為 ingress 了,但這個問題現象和原因還是挺有價值的。

前不久在朋友圈看到,haproxy 的最新版本有了重大變化,對用作 ingress 的場景有了更好地支持。這個變化是不是來的有些晚?未來似乎屬於 nginx 和 envoy 。

時間關係,先記錄這一個問題,502 和 504 的情況另外找時間整理。