线上k8s1.12版本故障复盘

概述

本来面临双十二这一天,线上出问题就会很紧张,本想今天应该没啥大问题,但很不巧,在11号晚上7点50时候,收到了k8s的events报警。

看到这个报警,赶紧看下服务,发现服务目前正常,但有一个正发布的服务,销毁不了老的pod,我怀疑node节点可能是不可用了。果不其然,在控制节点上查看node状态,为not ready。

检查

报的内核报警,但是其实不应该导致node节点不可用,故赶紧深究一下,先将node节点打上污点,不可调度。

当集群节点进入NotReady状态的时候,我们需要做的第一件事情,肯定是检查运行在节点上的kubelet是否正常。在这个问题出现的时候,使用systemctl命令查看kubelet状态,发现它作为systemd管理的一个daemon,是运行正常的。当我们用journalctl查看kubelet日志的时候,发现下边的错误。

1
2
  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的问题

问了下阿里的大佬

1
shim其实扮演父进程,回收容器里进程的角色,跟systemd去回收系统进程一样。linux上如果systemd卡主了,就会有一堆defunct。shim老版本的同步机制,就用了一个32大小的channel,理论上超过32个进程一起退出,就会overflow

于是我exec进入容器,果然发现进程很多,都是多于32,于是选择升级containerd解决问题

具体操作步骤如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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的问题

什么是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命令尝试运行新的容器,命令会没有响应。这说明上边的报错是准确的.

容器runtime

容器runtime包括docker daemon,containerd,containerd-shim以及runC。组件containerd负责集群节点上容器的生命周期管理,并向上为docker daemon提供gRPC接口。

故也升级了下systemd。升级systemd,直接yum update systemd就可以。

其中如果遇到容器起不来网络插件的情况,可以ip link del dev cni0,会自动重启的

Donate