k8s /var/lib/kubelet下的坑

666 阅读5分钟

起因

  • 总结一下,就是为什么开了3个月的K8S,在节点的/var/lib/kubelet下面数据达到了75G,导致磁盘压力报警。

开始

Docker存储所在的路径占满,而不应该是POD的存储路径?

默认情况下,docker默认路径为/var/lib/docker

实验1: 向容器下写入数据(非volume)

  • 使用dd命令向容器的/root下面写入1G数据
(base) [root@node46 ~]# kubectl  exec -it my-mysql-689bccf96b-tkshq bash

root@my-mysql-689bccf96b-tkshq:~# dd if=/dev/zero of=/root/root-1g count=1 bs=1G
  • 切换到pod所在节点,查看Docker存储路径
[root@node41 docker]# pwd
/var/lib/docker
[root@node41 docker]# find . -name "root-1g"
./overlay2/f1faa92ec70756a0704d756897d0d47cc12dd5cadbec06f933f7100d81ac5c5b/diff/root/root-1g
./overlay2/f1faa92ec70756a0704d756897d0d47cc12dd5cadbec06f933f7100d81ac5c5b/merged/root/root-1g
  • 切换到pod所在节点,查看POD存储路径
[root@node41 docker]# cd /var/lib/kubelet/
[root@node41 kubelet]# find . -name "root-1g"

综上说明:

  • 向非volume下面写入的数据,确实存在在容器存储路径下面,并且在容器不同的层(容器是分层的,最上层是可写层,其他都是只读层)
  • f1faa92ec70756a0704d756897d0d47cc12dd5cadbec06f933f7100d81ac5c5b不是容器的ID,而是容器其他层的ID(具体,容器分层的问题可以阅读Docker的官方文档)
[root@node41 kubelet]# docker ps | grep mysql
02a8a6ac03ca        c580203d8753                   "docker-entrypoint.s??   17 hours ago        Up 17 hours                                       k8s_mysql_my-mysql-689bccf96b-tkshq_default_3a3f1316-e17d-4d16-a27f-63c367fc02e1_0
fff132361882        k8s.gcr.io/pause:3.2           "/pause"                 17 hours ago        Up 17 hours                                       k8s_POD_my-mysql-689bccf96b-tkshq_default_3a3f1316-e17d-4d16-a27f-63c367fc02e1_0
[root@node41 kubelet]# docker inspect 02a8a6ac03ca | grep f1faa
                "LowerDir": "/var/lib/docker/overlay2/f1faa92ec70756a0704d756897d0d47cc12dd5cadbec06f933f7100d81ac5c5b-init/diff:...:/var/lib/docker/overlay2/2edd4328015fa0b3f1c0e51344836f785716f55bdec69afd6abd54ff97bcdf89/diff",
                "MergedDir": "/var/lib/docker/overlay2/f1faa92ec70756a0704d756897d0d47cc12dd5cadbec06f933f7100d81ac5c5b/merged",
                "UpperDir": "/var/lib/docker/overlay2/f1faa92ec70756a0704d756897d0d47cc12dd5cadbec06f933f7100d81ac5c5b/diff",
                "WorkDir": "/var/lib/docker/overlay2/f1faa92ec70756a0704d756897d0d47cc12dd5cadbec06f933f7100d81ac5c5b/work"

实验2: 向容器下写入数据(PV volume)

  • 使用echo命令向容器的/var/lib/mysql下面写入1G数据(/var/lib/mysql挂载到pv volume上)
root@my-mysql-689bccf96b-tkshq:/var/lib/mysql# echo "test-pv-volume-mysql" >> test-pv-volume-mysql
  • 切换到pod所在节点,查看Docker和POD的存储路径
[root@node1 kubelet]# pwd
/var/lib/kubelet
[root@node1 kubelet]# find . -name "test-pv-volume-mysql"
./pods/3a3f1316-e17d-4d16-a27f-63c367fc02e1/volumes/kubernetes.io~csi/pvc-b52c4ed0-993f-4a21-a5ca-4633f5d9d2ee/mount/test-pv-volume-mysql
[root@node1 kubelet]# cd ./pods/3a3f1316-e17d-4d16-a27f-63c367fc02e1/volumes/kubernetes.io~csi/pvc-b52c4ed0-993f-4a21-a5ca-4633f5d9d2ee/mount/
[root@node1 mount]# cat test-pv-volume-mysql 
test-pv-volume-mysql
[root@node1 mount]# find /var/lib/docker  -name "test-pv-volume-mysql"
[root@node1 mount]#

综上说明:

  • 在容器中向PV volume写入数据时,会出现在POD的存储路径下(/var/lib/kubelet),Docker路径下不会出现。
  • 在宿主机挂载PV volume下,会出现一份同样的数据,这样相当于存储了两份数据。我在Longhorn,nfs,moosefs提供的PV下面全部做过实验,都会出现相同的数据。
  • 删除POD,所在节点上/var/lib/kubelet下对应的数据会删除,但是PV下面的不会删除。重新调度并运行的新POD所在节点下面的/var/lib/kubelet会生成新的数据。

实验3: 向容器下写入数据(HostPath volume)

实验的方式时一样的,这里就不再重复一遍了。结果就是:

  • 在容器中向HostPath volume写入数据时,POD,Docker所在的路径下都不会出现,只会出现在POD所在节点对应的挂载位置。

结论

  • 无论是是容器内写数据还是PV volume下写数据,都是会出现两份数据。即使是这样,非常不建议向容器中写数据,因为一旦POD重建,数据是无法恢复的。
  • HostPath 和PV 相比,HostPath只会出现一份数据,节省了存储空间,但是需要共享存储系统,K8S中的节点需要挂载相同的目录下。
  • 生产环境中,Docker和POD存储路径要设置在尽可能大的磁盘上,以防磁盘压力,导致POD驱逐,造成集群雪崩

思考

一直没想明白的一件事,为什么 PV volume这种模式下,会在/var/lib/kubelet对应的目录下存储一份完全相同的数据呢?

希望各位大佬可以给指点迷津!


pv volume的存储其实也是存储一份文件,因此不是k8s的坑,是自己太“坑”了。把再次尝试的内容放出来给大家看看。

## longhorn 块存储
[root@node41 mount]# mount | grep 3a3f13
/dev/longhorn/pvc-b52c4ed0-993f-4a21-a5ca-4633f5d9d2ee on /var/lib/kubelet/pods/3a3f1316-e17d-4d16-a27f-63c367fc02e1/volumes/kubernetes.io~csi/pvc-b52c4ed0-993f-4a21-a5ca-4633f5d9d2ee/mount type ext4 (rw,relatime,data=ordered)
[root@node41 mount]# ls -al /dev/longhorn/pvc-b52c4ed0-993f-4a21-a5ca-4633f5d9d2ee 
brw-rw---- 1 root root 8, 0 Nov  3 14:30 /dev/longhorn/pvc-b52c4ed0-993f-4a21-a5ca-4633f5d9d2ee

## nfs 文件存储系统
root@t90:~# mount | grep da9ef3f
192.168.4.32:/mnt/data/nfs/pvc-5cacb9aa-18ed-11eb-af6a-e8611ff82490 on /var/lib/kubelet/pods/da9ef3f4-18ed-11eb-af6a-e8611ff82490/volumes/kubernetes.io~nfs/pvc-5cacb9aa-18ed-11eb-af6a-e8611ff82490 type nfs4 (rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.4.90,local_lock=none,addr=192.168.4.32)
root@t90:~# df -h | grep da9ef3f
192.168.4.32:/mnt/data/nfs/pvc-5cacb9aa-18ed-11eb-af6a-e8611ff82490   22T  185G   22T   1% /var/lib/kubelet/pods/