记K8s Pod The node was low on resource: [DiskPressure]. 问题排查

报错Pod The node was low on resource: [DiskPressure]的原因

使用kubectl describe pod podName查看到的k8s日志信息如下。

[root@OneEdge-IOT-028 app]<20210421 18:27:47># kubectl describe pod core-ff846f8f4-t2hgt
Name:               core-ff846f8f4-t2hgt
Namespace:          prod
Priority:           0
PriorityClassName:  <none>
Node:               10.12.4.170/
Start Time:         Wed, 21 Apr 2021 15:40:22 +0800
Labels:             app=core
                    pod-template-hash=ff846f8f4
Annotations:        <none>
Status:             Failed
Reason:             Evicted
Message:            Pod The node was low on resource: [DiskPressure].

通过google找到了一篇解释:

It means available disk space on one of the worker node was less than 10% Here is the default hard limits in k8s codes.

// DefaultEvictionHard includes default options for hard eviction.                       var DefaultEvictionHard = map[string]string{                        "memory.available":  "100Mi",                        "nodefs.available":  "10%",                        "nodefs.inodesFree": "5%",                        "imagefs.available": "15%",

referrence

https://faun.pub/kubelet-pod-the-node-was-low-on-resource-diskpressure-384f590892f5

https://stackoverflow.com/questions/60756958/the-node-was-low-on-resource-diskpressure-but-df-h-shows-47-usage-only

很清晰,我的pod因为资源不足被重启,通过查看pod信息,确实发现我的pod出现了重启现象。

[root@OneEdge-IOT-028 app]<20210421 17:55:18># kubectl get pod -o wide |grep coredata
core-ff846f8f4-5slc2                  0/1     Evicted   0          134m   <none>         10.12.4.170   <none>
core-ff846f8f4-6jwt4                  0/1     Evicted   0          134m   <none>         10.12.4.170   <none>
core-ff846f8f4-7bcmz                  1/1     Running   0          8h     10.100.1.48    10.12.4.166   <none>
core-ff846f8f4-8z8hv                  0/1     Evicted   0          135m   <none>         10.12.4.170   <none>
core-ff846f8f4-9cldd                  0/1     Evicted   0          134m   <none>         10.12.4.170   <none>

其实问题已经很清楚了,就是pod节点资源不足导致的服务重启,如果是想要找Pod The node was low on resource: [DiskPressure]的原因,请看我上面贴的reference。后面是结合自身的业务分析过程,可以不用看,仅记录共自己后序回顾。

但我的服务没有报任何错误信息,且是在进行正常的业务处理,为啥会莫名其妙的自动重启呢?很纳闷。

真正的原因

后面走查代码,查看日志发现服务的日志等级为debug; 貌似服务也没有发现error啊;为啥会莫名其妙地重启呢?注意,日志等级为debug;也就意味着着服务本身会记录大量的日志信息。会不会是因为大量的业务日志导致的磁盘资源空间不足,进而触发k8s的pod调度规则呢?

通过查看pod所在的宿主机资源,发现了一些信息异常现象:

[root@OneEdge-IOT-016 ~]<20210421 17:53:19># df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        40G   25G   16G  61% /    #. 这里发现 根路径下的资源被大量的占用。
devtmpfs        7.8G     0  7.8G   0% /dev
tmpfs           7.8G     0  7.8G   0% /dev/shm
tmpfs           7.8G  853M  7.0G  11% /run
tmpfs           7.8G     0  7.8G   0% /sys/fs/cgroup
/dev/sdb        260G   12G  249G   5% /data

猜测会不会是pod的业务日志写到根路径的磁盘空间了呢?

查看服务pod的log挂载:

[root@OneEdge-IOT-028 app]<20210421 17:32:18># kubectl describe pod core-ff846f8f4-bmvqs
// ...
Volumes:
  log-volume: # 可以发现 pod的卷挂载是 EmptyDir模式,
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:
    SizeLimit:  <unset>
 //....

什么是k8s 的emptyDir?

这篇文章

https://www.infoq.cn/article/ah1n57f8tge2wisquj00

写道:

emptyDir 类型的 Volume 在 Pod 分配到 Node 上时被创建,Kubernetes 会在 Node 上自动分配一个目录,因此无需指定宿主机 Node 上对应的目录文件。 这个目录的初始内容为空,当 Pod 从 Node 上移除时,emptyDir 中的数据会被永久删除。

因为目录是随机的,因此是可能写道/root下的磁盘空间的。验证

进入一个正在运行的pod容器中,查看日志文件路径,以及日志文件资源占用情况。

[root@OneEdge-IOT-028 app]<20210421 17:43:36># kubectl exec -it core-ff846f8f4-bmvqs -c  app  /bin/sh
$
$ cd logs
$ pwd
/data/app/logs
$ ls -al
total 17179944
-rw-r--r-- 1 app  app  17592262098 Apr 21 17:01 20210421.log
$ du -h  # 查看当前日志文件大小,发现被写了17GB的磁盘空间
17G	.
$ exit
[root@OneEdge-IOT-028 app]<20210421 17:53:36>#

再结合上面查看的虚拟机根路径的资源占用,可以推断是因为pod将日志文件写到了根路径的磁盘空间中。

[root@OneEdge-IOT-016 ~]<20210421 17:53:19># df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        40G   25G   16G  61% /    #. 这里发现 根路径下的资源被大量的占用。
devtmpfs        7.8G     0  7.8G   0% /dev
tmpfs           7.8G     0  7.8G   0% /dev/shm
tmpfs           7.8G  853M  7.0G  11% /run
tmpfs           7.8G     0  7.8G   0% /sys/fs/cgroup
/dev/sdb        260G   12G  249G   5% /data

验证》删除当前虚拟机中正在运行的pod;如果资源虚拟机资源得到释放,则验证猜想成功

[root@OneEdge-IOT-016 ~]<20210421 17:55:38># df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        40G  8.0G   33G  20% /      # 发现根路径的磁盘空间确实得到了释放  25= 8+17 
devtmpfs        7.8G     0  7.8G   0% /dev
tmpfs           7.8G     0  7.8G   0% /dev/shm
tmpfs           7.8G  853M  7.0G  11% /run
tmpfs           7.8G     0  7.8G   0% /sys/fs/cgroup
/dev/sdb        260G   12G  249G   5% /data

通过前后数据对比,发现日志确实是写到根路径挂载的磁盘空间中去了。这里就完全清晰了。

服务在被压测,产生了大量的debug日志,进而导致logs文件越来越大。一直占用根路径磁盘空间,当use%超过85%时,会触发k8s的驱逐pod指令,导致pod被驱逐。至此,服务异常重启的原因被找到了。

新的问题

为啥emptyDir会挂载到虚拟机根路径的磁盘空间?

这个还没有找到原因。后记
referrence

https://haojianxun.github.io/2018/08/06/kubernetes%E4%B8%AD%E7%9A%84volumes%E6%8C%82%E8%BD%BD%E7%B1%BB%E5%9E%8B%E4%B8%BAemptydir,%E5%9C%A8%E5%AE%BF%E4%B8%BB%E6%9C%BA%E4%B8%8A%E7%9A%84%E8%B7%AF%E5%BE%84%E5%9C%A8%E5%93%AA/

kubernetes中的volumes挂载类型为emptydir,在宿主机上的路径在哪

宿主机上的路径为

/var/lib/kubelet/pods/<PODID>/Volumes/Kubernetes.io~emptydir/<VOLUME_NAME>

pod volumesd 的使用

.spec.vloumes声明pod的volumes信息

.spec.containers.volumesMounts声明container如何使用pod的volumes

多个container共享一个volumes的时候,通过.spec.containers.volumeMounts.subPath隔离不同容器在同个volumes上数据存储的路径

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐