共計 2060 個字符,預計需要花費 6 分鐘才能閱讀完成。
這篇文章給大家介紹如何進行 K8S 中的 runtime 異常復盤,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
一、概述
收到線上 k8s 的 events 報警:
看到這個報警,趕緊看下服務,發現服務目前正常,但有一個正發布的服務,銷毀不了老的 pod,我懷疑 node 節點可能是不可用了。果不其然,在控制節點上查看 node 狀態,為 not ready。
二、檢查
報的內核報警,但是其實不應該導致 node 節點不可用,故趕緊深究一下,先將 node 節點打上污點,不可調度。
當集群節點進入 NotReady 狀態的時候,我們需要做的第一件事情,肯定是檢查運行在節點上的 kubelet 是否正常。在這個問題出現的時候,使用 systemctl 命令查看 kubelet 狀態,發現它作為 systemd 管理的一個 daemon,是運行正常的。當我們用 journalctl 查看 kubelet 日志的時候,發現下邊的錯誤。
Dec 11 19:38:45 ali-worker-k8s-001 kubelet[20140]: E1211 19:38:45.239546 20140 kubelet.go:1551] error killing pod: failed to KillPodSandbox for 31321cfc
-1bbe-11ea-893e-00163e14447d with KillPodSandboxError: rpc error: code = DeadlineExceeded desc = context deadline exceeded
order-oms-64544b9c65-4lq5d_sec-mall 這個 pod 殺不掉,導致了 docker 死鎖,所以判斷是 containerd 的問題
問了下阿里的大佬
shim 其實扮演父進程,回收容器里進程的角色,跟 systemd 去回收系統進程一樣。linux 上如果 systemd 卡主了,就會有一堆 defunct。shim 老版本的同步機制,就用了一個 32 大小的 channel,理論上超過 32 個進程一起退出,就會 overflow
于是我 exec 進入容器,果然發現進程很多,都是多于 32,于是選擇升級 containerd 解決問題
具體操作步驟如下
1、下載 1.2.10 containerd
wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.10-3.2.el7.x86_64.rpm
2、停止 kubelet 進程
systemctl stop kubelet
3、停止 containerd
systemctl stop containerd
4、更新 rpm 版本
rpm -Uvh containerd.io-1.2.10-3.2.el7.x86_64.rpm
5、啟動 containerd,檢查版本
systemctl start containerd
ctr version
6、啟動 docker,檢查容器進程
systemctl start docker
docker ps
7、啟動 kubelet
systemctl start kubelet
8、調度 pod 到該節點,驗證是否正常
三、網上看到的另一個 bug 是 systemd 的問題
1、什么是 PLEG
這個報錯很清楚的告訴我們,容器 runtime 是不工作的,且 PLEG 是不健康的。這里容器 runtime 指的就是 docker daemon。Kubelet 通過直接操作 docker daemon 來控制容器的生命周期。而這里的 PLEG,指的是 pod lifecycle event generator。PLEG 是 kubelet 用來檢查容器 runtime 的健康檢查機制。這件事情本來可以由 kubelet 使用 polling 的方式來做。但是 polling 有其成本上的缺陷,所以 PLEG 應用而生。PLEG 嘗試以一種“中斷”的形式,來實現對容器 runtime 的健康檢查,雖然實際上,它同時用了 polling 和”中斷”兩種機制。
基本上看到上邊的報錯,我們可以確認,容器 runtime 出了問題。在有問題的節點上,通過 docker 命令嘗試運行新的容器,命令會沒有響應。這說明上邊的報錯是準確的.
2、容器 runtime
容器 runtime 包括 docker daemon,containerd,containerd-shim 以及 runC。組件 containerd 負責集群節點上容器的生命周期管理,并向上為 docker daemon 提供 gRPC 接口。
故也升級了下 systemd。升級 systemd,直接 yum update systemd 就可以。
其中如果遇到容器起不來網絡插件的情況,可以 ip link del dev cni0,會自動重啟的。
關于如何進行 K8S 中的 runtime 異常復盤就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。