起因及分析
前幾天發現某系統的微信推送功能突然沒有了。由於都沒有改過任何代碼,所以估計問題出在K8S或者網絡方面。
由於之前做過一次災備演練,所以先從災備演練的過程着手回溯。當時演練的時候,強行關閉了A節點,造成之前在A節點上的服務會自動漂移到B節點。
結果發現B節點是之前做過測試的節點,上面有很多之前舊版本的鏡像。由於之前的鏡像是用版本號區分的,現在已經改爲按照日期+時間的方式打tag區分,造成漂移過去的服務自動加載了這些舊的鏡像。
由此問題的原因找到!
涉及到公司信息,就不截圖給大家了
解決
如何解決呢?
思路是這樣的,找出錯誤加載的鏡像,然後找到對應的服務,利用K8S的特點,將對應的容器實例設置爲0,再刪除錯誤的鏡像,然後再將對應的容器實例設置爲1,服務即會自動加載正確的鏡像重啓,恢復系統。
步驟
經過統計,共發現有20箇舊的鏡像。一個一個的排除,效率太低。
- 爲此,利用K8S的容錯機制,即一旦鏡像被加載,就無法刪除,就執行了這20個鏡像的刪除操作,一下子過濾出來8個鏡像。
- 經過與正確的鏡像的MD5值做對比,排除了2個正確的鏡像,剩下6個鏡像需要刪除。
- 在刪除的過程,發現只要把B節點設置爲髒節點,如下代碼:
kubectl taint node node1 key1=value1:NoSchedule
則此節點上被中止的容器會被強制漂移到其他節點。另外還有兩個命令,這裏用不到:
kubectl taint node node1 key1=value1:NoExecute
kubectl taint node node1 key2=value2:PreferNoSchedule
- 按照6個服務從次到主的順序,依次逐個處理,由於K8S的特性,很快就恢復了正常的服務。
反思
經過這次故障,更加要注重鏡像的管理和版本控制,在任何節點上,都不要保留舊的版本,以免產生上述問題。