kubernetes之故障排查和節點維護(二)


系列目錄

案例現場:

測試環境集群本來正常,突然間歇性地出現服務不能正常訪問,過一會兒刷新頁面又可以正常訪問了.進入到服務所在的pod查看輸出日志並沒有發現異常.使用kubectl get node命令正好發現一個節點是NotReady狀態

為了方便觀察,使用kubectl get node --watch來觀測一段時間,發現k8s-node1節點不斷的在Ready和NotReady狀態之間切換(使用kubectl get node -o wide可以查看節點的ip信息).

進入到出現問題的節點,使用命令journalctl -f -u kubelet來查看kubelet的日志信息,把錯誤日志截出來一段搜索一下,發現問題和這個問題基本上是一樣的,發現這個問題的時間和github上issue提出的時間是在同一天,也沒有看到解決辦法.但是基本能確定是因為集群中k8s-node1上的kubernetes版本不一致造成的(從上面截圖上可以看到,這個節點的版本是1.14.1其它的都是1.13.1,是怎么升上來的不清楚,可能是其它同事誤操作升級導致的)

搜索kubernetes NotReady查看了一些解決經驗,很多都是重啟docker,重啟kubectl等,然后都解決不了問題.於是嘗試重置這個節點.

從集群中刪除Node

由於這個節點上運行着服務,直接刪除掉節點會導致服務不可用.我們首先使用kubectl drain命令來驅逐這個節點上的所有pod

kubectl drain k8s-node1 --delete-local-data --force --ignore-daemonsets

以上命令中--ignore-daemonsets往往需要指定的,這是因為deamonset會忽略unschedulable標簽(使用kubectl drain時會自動給節點打上不可調度標簽),因此deamonset控制器控制的pod被刪除后可能馬上又在此節點上啟動起來,這樣就會成為死循環.因此這里忽略daemonset.

實際在使用kubectl drain時候,命令行一直被阻塞,等了很久還在被阻塞.使用kubectl get pod命令查看pod狀態時.其中一個叫作busybox的pod一直處於Terminating狀態. 使用kubectl delete pod busybox同樣無法刪除它.這時候可以使用命令kubectl delete pods busybox --grace-period=0 --force來強制馬上刪除pod.

這時候控制台阻塞狀態結束.下面執行命令kubectl delete node k8s-node1來刪除這個節點.然后我們重新安裝kubelet,kubeadm和kubectl

卸載舊版本

如果是通過yum方式安裝的,可以通過yum list installed|grep xxx形式來找到已安裝的組件,然后刪除它們.刪除以后重新安裝.

這里之所以要重新安裝是因為版本升級成了較為新的版本,如果版本是一樣的,其它的不確定因素導致節點不穩定,又找不到具體原因,則可以通過kubeadm reset來重置安裝.

重置命令並不會重置設置的iptables規則和IPVS如果想要重置iptables,則需要執行以下命令:

iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X

如果想要重置IPVS,則需要執行以下命令:

ipvsadm -C

這里我能夠基本確定是由於版本不一致導致的,因此我並不重置iptables和IPVS,僅僅是重裝組件.

重新加入集群

重置完成以后,我們把刪除掉的k8s-node1節點使用kubeadm join重新加入到集群中

如果忘記了主節點初始化時候生成的加入token,可以在主節點上執行kubeadm token create --print-join-command重新生成加入token,然后把生成的命令復制到要加入集群的節點上執行.

重新加入集群后,觀察了一段時間,一直是Ready狀態,感覺終於穩定了,但是同事又反饋部署服務時出現以下錯誤

Failed create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "5159f7918d520aee74c5a08c8707f34b61bcf1c340bfc444125331034e1f57f6" network for pod "test-58f4789cb7-7nlk8": NetworkPlugin cni failed to set up pod "test-58f4789cb7-7nlk8_default" network: failed to set bridge addr: "cni0" already has an IP address different from 10.244.4.1/24

幸好有偉大的互聯網,通過搜索,找到以下解決方案

由於這次啟動以后初次部署pod就失敗了,因此此節點上還沒有運行的服務,我們不需要執行kubectl drain,可以直接把這個節點刪除.然后執行以下命令

kubeadm reset
systemctl stop kubelet
systemctl stop docker
rm -rf /var/lib/cni/
rm -rf /var/lib/kubelet/*
rm -rf /etc/cni/
ifconfig cni0 down
ifconfig flannel.1 down
ifconfig docker0 down
ip link delete cni0
ip link delete flannel.1
systemctl start docker

完了以后重新加入集群.這次可以正常工作了.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM