K8S容器空间不足问题分析和解决

如上图,今天测试环境的K8S平台出现了一个问题,其中的一个容器报错:Free disk space below threshold. Available: 3223552 bytes (threshold: 10485760B),意思服务器硬盘空间不够了。这个问题怎么产生的,又怎么解决的呢?

一、问题分析

这个容器是部署在k8s集群的一个工作节点,该工作节点的磁盘使用率已经达到了99%,但是Kubernetes的垃圾回收机制似乎没有生效,可能有以下几个原因:

1、镜像垃圾回收阈值设置过高
  • 默认情况下,--image-gc-high-threshold的值为85,表示只有当磁盘使用率达到85%时才会触发镜像垃圾回收。
  • 如果你的节点磁盘使用率在达到85%之前就已经接近满载,那么垃圾回收机制可能无法及时释放足够的空间。

2、死亡容器和未使用镜像占用空间较小

  • Kubernetes的垃圾回收机制主要针对已停止的容器(dead containers)和未使用的镜像。
  • 如果你的节点上运行的大部分容器都是活动的,并且镜像都在被使用,那么垃圾回收可能无法释放太多空间。

3、其他非容器相关的文件占用了大量磁盘空间

  • Kubernetes的垃圾回收只会清理停止的容器和未使用的镜像,但不会删除其他文件。
  • 如果你的节点上有大量非容器相关的文件(如日志文件、数据文件等)占用了磁盘空间,垃圾回收机制无法处理这些文件。

4、垃圾回收机制的执行频率不足

  • Kubernetes的垃圾回收机制是周期性运行的,默认情况下每分钟运行一次。
  • 如果你的节点磁盘使用率增长非常快,垃圾回收的执行频率可能跟不上磁盘空间的消耗速度。

二、解决问题

为了解决这个问题,可以尝试以下几种方法:

1、手动清理

  • 你可以使用docker container prune命令删除所有停止的容器。
  • 使用docker image prune命令删除所有悬空(dangling)镜像,即没有被任何容器引用的镜像。

2、调整参数

将--image-gc-high-threshold--image-gc-low-threshold两个参数的值进行调整,使其更接近实际的磁盘使用情况。例如,你可以将--image-gc-high-threshold设置为75,将--image-gc-low-threshold设置为70,以便在磁盘使用率较高时更积极地进行垃圾回收。

3、定期清理

识别并清理节点上占用大量磁盘空间的非容器相关文件,如日志文件、临时文件等。

4、扩容

考虑增加节点的磁盘容量或向集群中添加更多节点,以分散工作负载和存储压力。

5、优化应用

如果可能,尝试优化应用程序和工作负载,减少不必要的磁盘空间使用。

本次问题处理中,我们先用手动删除所有停止的容器和镜像,然后调整了--image-gc-high-threshold和--image-gc-low-threshold参数的值,改为75,最后配置了一个监控任务,磁盘空间超过80%就提示告警。

请注意,在对生产环境进行任何更改之前,务必仔细评估可能的影响并制定合适的策略。根据你的具体情况和需求,选择最适合的方法来解决节点磁盘空间不足的问题。

三、相关知识

除了上面使用的方法,我们要在Kubernetes中自动清理过期的容器和镜像,还可可以利用Kubernetes的内置机制和一些第三方工具。下面是几种方法:

1、配置容器的 restartPolicyterminationGracePeriodSeconds

  • 对于一次性任务或短期任务,可以将Pod的 restartPolicy 设置为 NeverOnFailure,确保容器退出后不会自动重启。
  • 设置合适的 terminationGracePeriodSeconds 值,控制容器优雅终止的宽限期,超过该时间后Kubernetes会强制删除容器。

2、使用 TTL Controller 自动清理已完成的Job

  • Kubernetes的 TTL Controller 可以自动清理已完成的Job及其关联的Pod。
  • 在Job的spec中设置 .spec.ttlSecondsAfterFinished 字段,指定Job完成后的TTL时间,超过该时间Job和Pod会被自动删除。

3、利用第三方工具如 kube-janitordescheduler

  • kube-janitor 是一个自动清理Kubernetes资源的工具,可以根据配置的规则定期清理过期的资源,包括Pod、Job、ConfigMap等。
  • descheduler 可以根据策略驱逐Pod,释放节点资源,可以用于清理长时间运行的Pod。

4、使用自定义脚本或控制器

  • 可以编写自定义脚本或控制器,定期查询和清理过期的容器和镜像。
  • 可以利用Kubernetes API或客户端库如 client-go 来实现自定义逻辑。

以上是一些常见的方法,可以根据具体需求选择合适的方案。同时,也要注意配置适当的资源限制和请求,避免不必要的资源浪费。定期监控集群的资源使用情况,及时调整和优化。

相关推荐
aherhuo5 小时前
kubevirt网络
linux·云原生·容器·kubernetes
陌北v15 小时前
Docker Compose 配置指南
运维·docker·容器·docker-compose
catoop6 小时前
K8s 无头服务(Headless Service)
云原生·容器·kubernetes
阿里嘎多学长6 小时前
docker怎么部署高斯数据库
运维·数据库·docker·容器
小峰编程6 小时前
独一无二,万字详谈——Linux之文件管理
linux·运维·服务器·云原生·云计算·ai原生
小马爱打代码7 小时前
云原生服务网格Istio实战
云原生
liuxuzxx7 小时前
1.24.1-Istio安装
kubernetes·istio·service mesh
G_whang7 小时前
windos 安装docker
运维·docker·容器
道一云黑板报7 小时前
Flink集群批作业实践:七析BI批作业执行
大数据·分布式·数据分析·flink·kubernetes
运维小文8 小时前
K8S中的PV、PVC介绍和使用
docker·云原生·容器·kubernetes·存储