共计 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 异常复盘就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。