ansible的一個bug經歷

使用ansible在大規模(幾百臺以上規模比較容易遭遇)部署機器的時候,有時候會碰到ansible進程hang在某個點上,這個點不必定每次都同樣。
研究了一個下午,發現hang住的時候,CI/CD的agent上並無報錯日誌,被執行host上也沒有ansible的日誌輸出,而且不管等待多長時間也不會退出。git

期初懷疑是版本問題,由於以前線上一直用的2.7版本,最近剛切換到2.9,可是實際上這個部署的job在使用2.9版本的時候已經成功過很多次。而後檢查CI/CD上部署job的VCS配置,發現雖然有更新,可是並無什麼很大的可能明顯致使這種狀況發生的changes。github

啓動google大法,發現ansible的github上有人提過一個issue,一個很老的2017年9月的issue,https://github.com/ansible/ansible/issues/30411
這個issue最後一個comment是提交了一個PR(居然是20天前剛提交的),這個PR給task執行增長了一個硬超時,已經merge,雖然沒有解釋爲何會hang住,可是起碼提供了一個解決方案。並且裏面的comments提到了一個關鍵的復現方法,一個簡單的"df"命令就可讓ansible進程hang住。
因而我找了兩臺機器,裝了nfs,client端掛載了server端的一個目錄,而後把server端的nfs進程stop掉,這時候在client中執行"df"命令,效果等同於進程hang住,原理也很簡單,由於nfs連接斷掉了,"df"在等待返回,等不到就「假死」在那裏。
再而後,我配置了一個只有一條shell命令的ansible playbook,讓多臺機器(其中包括了這個nfs client節點)同時運行,結果果真是ansible在執行到這個nfs client節點的時候hang住不再動了,而且若是我從新啓動nfs server端,ansible當即就回正常執行完,說明ansible進程沒有「死」,只是一直在「等待」。shell

如今在回過頭來思考,結論應該是批量開機器的時候,由於咱們用的是AWS,在規模很大的狀況下,常常有實例會由於各類特例問題致使某些task掛起在機器上,而這個時候因爲ansible沒有超時機制,而且!最關鍵的來了,ansible沒有收到任何錯誤值和返回值,因而就一直在「等待」,等到海枯石爛。
短時間的解決方法,若是是雲平臺,幹掉那些「不正常」的機器,從新run一次job,通常都會解決。
長期的話,超時是一個可行的方案,並且ansible還須要真正的解決是並行問題,不要讓一個機器的問題致使整個job的失敗(某一個實例有問題,那就提示出來,其餘的繼續跑)。ide

相關文章
相關標籤/搜索