记一则K8S Node NotReady故障

开发 测试
第一反应就是ping下节点看是否宕机了?ping正常,于是登录到该节点查看kubelet状态。发现kubelet报runtime不可用,查看containerd的状态,一直在不断的重启,而且启动不成功。为了尽快恢复业务,决定先将containerd的数据目录清空后重新拉起。

报障:

    今日上午,值班同学发现airflow无法使用。查看时其部署的Node节点NotReady了。

分析:

    马上查看K8S集群节点的状态,发现这个节点已经是NotReady状态了。第一反应就是ping下节点看是否宕机了?ping正常,于是登录到该节点查看kubelet状态。发现kubelet报runtime不可用,查看containerd的状态,一直在不断的重启,而且启动不成功。为了尽快恢复业务,决定先将containerd的数据目录清空后重新拉起。于是删除containerd数据目录下的文件夹:

# ls -lrth /xpu-k8s-data/containerd/
total 0
drwx------ 2 root root  6 Apr 28 10:54 io.containerd.snapshotter.v1.btrfs
drwx------ 3 root root 31 Apr 28 10:54 io.containerd.snapshotter.v1.aufs
drwx------ 3 root root 31 Apr 28 10:54 io.containerd.snapshotter.v1.native
drwx--x--x 2 root root 29 Apr 28 10:54 io.containerd.metadata.v1.bolt
drwx--x--x 2 root root  6 Apr 28 10:54 io.containerd.runtime.v1.linux
drwxr-xr-x 4 root root 45 Apr 28 10:54 io.containerd.content.v1.content
drwx------ 3 root root 54 Apr 28 10:54 io.containerd.snapshotter.v1.overlayfs
drwx--x--x 3 root root 28 Apr 28 10:54 io.containerd.runtime.v2.task
drwxr-xr-x 4 root root 53 Apr 28 10:55 io.containerd.grpc.v1.cri
drwx------ 2 root root  6 Apr 28 14:49 tmpmounts
# rm -rf /xpu-k8s-data/containerd/*

    发现执行的时间很长,超过几分钟。通过du命令统计该目录的大小也很久,我判断是这个目录下的小文件太多了。于是我ctrl+c掉rm和du命令。直接将该目录改个名字后重新创建一个目录。然后重新拉起containerd和kubelet进程后节点Ready了。pod也正常了。

    然后接着再来删除之前的数据目录,执行删除后经过30min-60min才删除完成。通过rm -rfv 参数可以看到打印出来删除的文件信息,是pod中存在大量的python,go的.cache和.git的小文件。查看containerd的报错:

图片

图片

    猜测是因为小文件数量过多,导致节点containerd停止后重启失败,不断重启导致节点NotReady的。

    恢复一段时间后,airflow跑任务时,拉起个别的pod没有问题,但是当同时拉起几十个pod跑任务的时候有很多的pod无法启动。报如下错误:

图片

    该节点的pod网段IP地址已经用完,无法分配IP了。集群设计的时候给每个Node的子网掩码是25。可以部署125个pod。但是现在节点上的pod才十几个。猜测是之前节点故障的时候,直接删除了元数据后拉起containerd导致原来的pod在系统上的网络信息没有被删除。导致IP被占用了。我们的集群采用了flannel组件,并且开启了--kube-subnet-mgr参数。所以IP分配信息不会记录到etcd,而是直接记录到Node节点上的。

# ps -ef | grep flannel
root      6450 45116  0 14:59 pts/4    00:00:00 grep --color=auto flannel
root     53065 52700  0 13:02 ?        00:00:43 /opt/bin/flanneld --ip-masq --kube-subnet-mgr

    Pod在Node上的网络信息主要有两点:

        1)容器在Node侧的vethxxx接口;

        2)容器在Node侧的IP地址;

    所以,只要我们删除旧Pod的容器残留在Node上的以上网络信息应该就可以恢复了。

解决:

    1)找到容器在Node侧的vethxxx接口并删除

        我们知道,veth对一侧在容器里面,一侧在Node侧。通过命令ip addr可以查看到。这里我们需要找到不存在容器遗留在Node的vethxxx接口。

图片

    如上图所示,每个vethxxx接口都有一个Node侧的index ID(第一列数字),而vethxxx@if后面的数字3是该veth接口对应在容器侧的eth0网卡在容器内的index ID。容器和Node的veth接口对应关系如下:

图片

    通过这样的方式找到其映射关系的。有了这个信息之后,我就可以去到该Node上所有的容器中拿到eth0对应的在Node的index ID,从而在Node侧过滤找出已经无效的vethxxx接口并删掉。操作如下:

for pid in $(for i in $(crictl ps | awk '{print $1}'); do crictl inspect $i | grep -i pid|grep , | awk '{print $2}' | sed 's/,//';done);do nsenter -t $pid --net ;done

    由于Node上现有的容器不多,十几个所以通过这种方式逐一登录拿到对应的index ID。如果容器较多,需要结合expect工具做自动识别处理。这里没有做。拿到所有有效的veth的index ID后报错到veth_yes文件中,把Node侧所有的veth信息报错到veth_all文件中:

ip add | grep veth > veth_all

    然后根据有效的index ID把其信息从veth_all中删除,得到所有要删除的vethxxx接口信息并删除:

// 删除有效的veth信息
#!/bin/bash
for i in $(cat veth_yes)
do
  grep $i veth_all; sed -i "/$i/d" veth_all
done


// 删除所有无效的vethxxx接口信息
#!/bin/bash
for i in $(cat veth_all | awk '{print $2}' | awk -F@ '{print $1}')
do
  ip link delete $i
done

    删除后,Node侧只剩下当前running容器的vethxxx接口了。 

    2)找到容器在Node侧记录的IP地址并删除

    veth接口处理完,那么IP地址没有释放该如何处理呢?

   查阅资料后得知,IPAM插件已分配的IP地址保存在/var/lib/cni/networks/cbr0文件中。如下:

图片

    于是,将其中未真正在使用的IP地址文件删除即可。删除后如下:

图片

    此时,所有无法分配IP的Pod都可以正常获取IP从creating状态变为Running状态了。

    至此,问题修复!略略略略略~~~

责任编辑:武晓燕 来源: 举个栗栗
相关推荐

2021-08-20 11:35:04

服务运维 故障

2021-04-23 08:35:16

k8s故障检测

2022-04-22 13:32:01

K8s容器引擎架构

2023-12-05 08:33:44

滴滴故障k8s

2024-02-20 16:55:14

K8S云计算

2024-03-18 15:44:48

K8S故障运维

2011-04-11 09:53:06

Oracle

2023-11-06 07:16:22

WasmK8s模块

2023-09-06 08:12:04

k8s云原生

2024-03-12 15:47:12

Kubernetes容器K8S

2024-03-27 14:54:21

KubernetesK8S集群

2011-05-27 10:02:42

Shell

2009-10-21 09:58:28

桌面LinuxLinux操作系统

2010-07-21 16:53:33

telnet命令

2009-06-15 14:00:44

Java小程序验证

2010-07-26 15:14:04

telnet服务

2023-12-01 15:58:00

Kubernetes集群DevOps

2024-01-07 19:43:50

K8S节点

2020-05-12 10:20:39

K8s kubernetes中间件

2022-09-05 08:26:29

Kubernetes标签
点赞
收藏

51CTO技术栈公众号