存储的限制方法
通过上文的介绍,我们可以看到,除了容器镜像是系统机制控制的,其它的内容都跟应用程序有关。
应用程序完全可以控制自己使用的存储空间,比如少写点日志,将数据保存到远程存储,及时删除使用完毕的临时数据,使用LRU等算法控制存储空间的使用量,等等。不过完全依赖开发者的自觉也不是一件很可靠的事,万一有BUG呢?所以K8S也提供了一些机制来限制容器可以使用的存储空间。
K8S的GC
K8S有一套自己的GC控制逻辑,它可以清除不再使用的镜像和容器。这里我们重点看下对镜像的清理。
这个清理工作是 kubelet 执行的,它有三个参数来控制如何执行清理:
- imageMinimumGCAge 未使用镜像进行垃圾回收时,其存在的时间要大于这个阈值,默认是2分钟。
- imageGCHighThresholdPercent 镜像占用的磁盘空间比例超过这个阈值时,启动垃圾回收。默认85。
- ImageGCLowThresholdPercent 镜像占用的磁盘空间比例低于这个阈值时,停止垃圾回收。默认80。
可以根据自己的镜像大小和数量的水平来更改这几个阈值。
日志总量限制
K8S对写入标准输出的日志有一个轮转机制,默认情况下每个容器的日志文件最多可以有5个,每个文件最大允许10Mi,如此每个容器最多保留最新的50Mi日志,再加上Node也可以对Pod数量进行限制,日志使用的本地存储空间就变得可控了。这个控制也是 kubelet 来执行的,有两个参数:
- containerLogMaxSize 单个日志文件的最大尺寸,默认为10Mi。
- containerLogMaxFiles 每个容器的日志文件上限,默认为5。
以上文的 pod-log-stdout 这个Pod为例,它的日志输出量很多就会超过10Mi,我们可以实际验证下。
不过如果没有意外,意外将要发生了,K8S的限制不起作用。这是因为我们使用的容器运行时是docker,docker有自己的日志处理方式,这套机制可能过于封闭,K8S无法适配或者不愿意适配。可以更改docker deamon的配置来解决这个问题,在K8S Node中编辑这个文件 /etc/docker/daemon.json (如果没有则新建),增加关于日志的配置:
{ "log-opts": { "max-size": "10m", "max-file": "5" } }
然后重启Node上的docker:systemctl restart docker。注意还需要重新创建这个Pod,因为这个配置只对新的容器生效。
在docker运行时下,容器日志实际上位于 /var/lib/docker/containers 中,先找到容器Id,然后就可以观察到这些日志的变化了: