使用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:
Node: 10.12.4.170/
Start Time: Wed, 21 Apr 2021 15:40:22 +0800
Labels: app=core
pod-template-hash=ff846f8f4
Annotations:
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 10.12.4.170
core-ff846f8f4-6jwt4 0/1 Evicted 0 134m 10.12.4.170
core-ff846f8f4-7bcmz 1/1 Running 0 8h 10.100.1.48 10.12.4.166
core-ff846f8f4-8z8hv 0/1 Evicted 0 135m 10.12.4.170
core-ff846f8f4-9cldd 0/1 Evicted 0 134m 10.12.4.170
其实问题已经很清楚了,就是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:
//....
什么是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/
宿主机上的路径为
/var/lib/kubelet/pods//Volumes/Kubernetes.io~emptydir/
.spec.vloumes
声明pod的volumes信息
.spec.containers.volumesMounts
声明container如何使用pod的volumes
多个container共享一个volumes的时候,通过.spec.containers.volumeMounts.subPath
隔离不同容器在同个volumes上数据存储的路径