kubelet节点磁盘爆满处理记录
2024-02-26 15:13:18

前几天在做一个需求的时候,突然发现某个节点上的集群无法访问了,在此记录一下出现的现象以及处理方式。

环境

一套 k8s 环境,其中有 4 个节点,其中一个节点属于 ci 专用。

现象

  • 前端页面访问失败,无响应
  • 访问 Jenkins 页面,无响应

回顾事件

当时是在晚上九点,我在调试一个流水线的 Jenkinsfile 脚本,点了一次运行以后,就去处理别的事情,等 ci 了,过了一段时间,我回来看的时候,发现页面访问不了了,无论是 k8s 集群的前端页面,还是 Jenkins 的前端页面都无法访问。

由于当时已经离开公司了,是在家里远程处理的,所以那天晚上就先搁置了,等到第二天上午再去处理的。第二天在公司里的时候,我登录到 master 节点去看,首先我使用 curl 测试了一下 apiserver,发现是有响应的,那么大概率就是前端的那个 deployment 有问题了;于是我用 describe 看了下前端 deployment 的状态,发现报了一个错误,拉取不到镜像;这个问题人给我看傻了,我们的 harbor 仓库更换过了,所以拉取不到是正常的,但是那台机器以前是有本地镜像的,莫名其妙的本地镜像被删了 :rofl:;这个问题处理起立简单,我换了个新的地址就解决了,登录进去以后,发现 ci 的那个节点还是处于无法调度的状态,不可用,于是又去检查另一个节点。

首先我去看了一下 kubelet 的状态,具体的错误记不清了,可能是类似这样的:

1
Warning  FailedCreatePodSandBox 53m kubelet, 172.22.0.44  Failed create pod sandbox: rpc error: code = DeadlineExceeded desc = context deadline exceeded

我拿着信息在网上搜索了一圈,第一条结果就是说可能是磁盘满了,于是我看了一眼磁盘,果然,/var/lib/docker/var/lib/kubelet 是挂载到 / 下面的,总共就只有 100 G,磁盘满了,所以 pod 也启动不起来,但是 /home 目录下还有十几个 T 的空间没有使用,于是我就准备把这两目录都迁移到 /home 目录。

迁移步骤

  1. **驱逐节点上的 pod
1
kubectl drain <node-name>
  1. 停止 docker、kubelet
1
systemctl stop docker && systemctl stop kubelet
  1. 迁移目录

注意:迁移目录时,使用 cp 或者 rsync 命令时,记得使用 “-p”参数,保持文件权限,曾经我就在迁移目录没注意这个问题,导致线上的服务给干崩了,还好这只是我们部门内部的服务,影响比较小。

创建新的目录:

我直接在 home 目录在建了个 var 目录,这种方式不推荐,假如有人需要创建一个名为 var 的用户,可能会产生冲突(这个没试过)

1
2
mkdir -pv /home/var/lib/docker
mkdir -pv /home/var/lib/kubelet

拷贝旧文件:

1
2
cp -p /var/lib/docker /home/var/lib/docker
cp -p /var/lib/kubelet /home/var/lib/kubelet

拷贝的过程可能会要等很久,安心等待…

  1. 修改配置

kubelet 和 docker,都需要修改配置文件,将修改后的存储地址挂载进去。有关 docker 不同版本修改配置的一些区别,请看 两种方法迁移 Docker 的默认安装(存储)目录

  • Docker 配置

    1
    vim /etc/docker/daemon.json

    增加如下配置:

    1
    "data-root": "/store/software/docker",
  • kubelet 配置

    主要是修改 root-dit 参数,参见 官方文档

参考文档