Rails container 在 Google Kubernetes Engine 上不正常關閉

最近在部署rails專案到GKE上,發現rolling update在關掉container時會跳出「Pod errors: Error with exit code 1」,然後狀態變成紅色的

雖然只是要被關閉的pod壞掉不影響更新流程,但偶爾會造成服務中斷,看起來不是件好事

最初推測是puma在關閉的時候有什麼問題,找到一個issue說bundler在1.16版以前跑「bundle exec」會造成puma收到SIGTERM後回傳exit code 1

這現象剛好很符合遇到的情境,但我用的是1.16版以後的bundler,而且測試發現,bash上跑的puma收到SIGTERM會正確的回傳code 143,唯有放在container裡用docker開起來,傳送SIGTERM才會遇到code 1的結果

當時完全沒有頭緒,過了幾天同事剛好提到說他以前有看過一個叫做dumb-init的東西

dumb-init是設計給container用的init process,有回收process和轉送signal的功能,至於為什麼container還需要init process的原因可以看這一篇文章的說明

查了之後覺得可能很有幫助,畢竟bundler跟puma都曾有過signal處理不好的問題,而且在bash上可以正確關閉,代表直接把puma放在PID 1會缺某種東西

一試用下去,puma還真的能正確回傳code 143了,正想說可以放上GKE的時候,GKE又亮紅燈了....

他對143這個回答也不高興Orz

code 143是由128 + 15組成,signal 15也就是SIGTERM,不一定是異常的狀態

為了要讓GKE滿意,只好想怎麼把code變成0

翻了翻手冊並測試確定puma在收到SIGINT時會回傳code 0,剛好dumb-init有支援signal rewrite,可以直接把SIGTERM改成SIGINT傳給puma

於是最終透過dumb-init成功解決了exit code造成GKE不爽的問題

另外有個值得注意的地方是docker的entrypoint跟cmd分別等於kubernetes的command跟args,如果設錯會產生不同的效果,細節可以看手冊的Notes

留言

粗體斜體刪除線連結引用圖片程式碼

注意:您的電子信箱將不會被公開,且網站連結不會被搜尋引擎採計

{124} {123} {122} {121} {120} {119} {118} {117} {116} {115} {114} {113} {112} {111} {100} {025} {024} {023} {022} {021} {020} {019} {018} {017} {016} {015} {014} {013} {012} {011} {010} {009} {008} {007} {006} {005} {004} {003} {002} {001}