本文档介绍 TKE 集群中多场景下可能发生的磁盘爆满问题,并给出对应的排查思路及解决方案,请按照下文中的步骤进行排查并解决。
Kubelet 支持 gc 和驱逐机制,可通过 --image-gc-high-threshold
、--image-gc-low-threshold
、--eviction-hard
、--eviction-soft
及 --eviction-minimum-reclaim
等参数进行控制以实现磁盘空间的释放。当配置不正确,或者节点上有其它非 K8S 管理的进程在不断写数据到磁盘,将会占用大量空间时将导致磁盘爆满。
磁盘爆满将影响 K8S 运行,主要涉及 kubelet 和容器运行时两个关键组件。请按照以下步骤进行分析:
df
命令,查看 kubelet 和容器运行时所使用的目录是否存在于该磁盘。如果容器运行时使用的目录所在磁盘空间爆满,将可能会造成容器运行时无响应。例如,当前容器运行时为 docker,则执行 docker 相关的命令将会一直 hang 住,kubelet 日志也将看到 PLEG unhealthy,而 CRI 调用 timeout 也将导致容器无法创建或销毁,外在现象通常表现为 Pod 一直 ContainerCreating 或一直 Terminating。
/var/run/docker
:用于存储容器运行状态,通过 dockerd 的 --exec-root
参数指定。/var/lib/docker
:用于持久化容器相关的数据。例如,容器镜像、容器可写层数据、容器标准日志输出及通过 docker 创建的 volume 等。Pod 在启动过程中,可能会出现以下类似事件:
Warning FailedCreatePodSandBox 53m kubelet, 172.22.0.44 Failed create pod sandbox: rpc error: code = DeadlineExceeded desc = context deadline exceeded
Warning FailedCreatePodSandBox 2m (x4307 over 16h) kubelet, 10.179.80.31 (combined from similar events): Failed create pod sandbox: rpc error: code = Unknown desc = failed to create a sandbox for pod "apigateway-6dc48bf8b6-l8xrw": Error response from daemon: mkdir /var/lib/docker/aufs/mnt/1f09d6c1c9f24e8daaea5bf33a4230de7dbc758e3b22785e8ee21e3e3d921214-init: no space left on device
Warning Failed 5m1s (x3397 over 17h) kubelet, ip-10-0-151-35.us-west-2.compute.internal (combined from similar events): Error: container create failed: container_linux.go:336: starting container process caused "process_linux.go:399: container init caused \"rootfs_linux.go:58: mounting \\\"/sys\\\" to rootfs \\\"/var/lib/dockerd/storage/overlay/051e985771cc69f3f699895a1dada9ef6483e912b46a99e004af7bb4852183eb/merged\\\" at \\\"/var/lib/dockerd/storage/overlay/051e985771cc69f3f699895a1dada9ef6483e912b46a99e004af7bb4852183eb/merged/sys\\\" caused \\\"no space left on device\\\"\""
Pod 在删除过程中,可能会出现以下类似事件:
Normal Killing 39s (x735 over 15h) kubelet, 10.179.80.31 Killing container with id docker://apigateway:Need to kill Pod
/var/lib/kubelet
:通过 kubelet 的 --root-dir
参数指定,用于存储插件信息、Pod 相关的状态以及挂载的 volume(例如,emptyDir
、ConfigMap
及Secret
)。
Kubelet 使用的目录所在磁盘空间爆满(通常是系统盘),新建 Pod 时无法成功进行 mkdir,导致 Sandbox 也无法创建成功,Pod 通常会出现以下类似事件:
Warning UnexpectedAdmissionError 44m kubelet, 172.22.0.44 Update plugin resources failed due to failed to write checkpoint file "kubelet_internal_checkpoint": write /var/lib/kubelet/device-plugins/.728425055: no space left on device, which is unexpected.
当容器运行时为 docker 时发生磁盘爆满问题,dockerd 也会因此无法正常响应,在停止时会卡住,从而导致无法直接重启 dockerd 来释放空间。需要先手动清理部分文件腾出空间以确保 dockerd 能够停止并重启。恢复步骤如下:
$ cd /var/lib/docker/containers
$ du -sh * # 找到比较大的目录
$ cd dda02c9a7491fa797ab730c1568ba06cba74cecd4e4a82e9d90d00fa11de743c
$ cat /dev/null > dda02c9a7491fa797ab730c1568ba06cba74cecd4e4a82e9d90d00fa11de743c-json.log.9 # 删除log文件
注意:
- 删除文件时,建议使用
cat /dev/null >
方式进行删除,不建议使用rm
。使用rm
方式删除的文件,不能够被 docker 进程释放掉,该文件所占用的空间也就不会被释放。- log 的后缀数字越大表示时间越久远,建议优先删除旧日志。
kubectl drain <node-name>
该步骤可以确保 dockerd 重启时将原节点上 Pod 对应的容器删掉,同时确保容器相关的日志(标准输出)与容器内产生的数据文件(未挂载 volume 及可写层)也会被清理。systemctl restart dockerd
# or systemctl restart docker
kubectl uncordon <node-name>
需确保 kubelet 的 gc 和驱逐相关参数进行配置正确。若配置无问题,即便磁盘达到爆满地步,此时事发节点上的 Pod 也已自动驱逐到其它节点上,不会出现 Pod 一直 ContainerCreating 或 Terminating 的问题。
11月25日,由深信服旗下云计算品牌信服云发起的中国IT正传系列沙龙在全国陆续开展...
成立于2016年的吼吼科技,是一家很有意思的公司。 公司的中文全名是重庆吼吼科技...
云计算技术如今改变了游戏规则。管理和控制云计算的服务商越来越受欢迎,技术领...
Serverless时代的来临 Serverless 顾名思义 是一种“无服务器”架构 因为屏蔽了...
如何获取 SSL证书 ? SSL证书 一般是需要去提供 SSL 证书的平台购买的,购买了之...
TOP云 (west.cn)11月22日消息,据知名 域名 博主兼投资人Jamie Zoch在推特上爆...
一位同学曾给我打比方:宿主机就好比一间大房子,docker 把它变成了N个小隔断。...
导读 时隔数月之后PaddleOCR发版v2.2,又带着新功能和大家见面了。本次更新,为...
调用CreateLaunchTemplate创建一个ECS实例启动模板,简称模板。实例启动模板能免...
作者 佳旭?阿里云容器服务技术专家 引言 Kubernetes 在生产环境应用的普及度越来...