Kubernetes集群随着应用的迭代,会产生很多无用的镜像和容器,因此需要定时清理,分布在每个节点的Kubelet有GC(垃圾收集)的职责,当集群中有断定为垃圾的镜像或容器,那么kubelet会清除掉相关镜像或容器。容器GC间隔为1分钟,镜像GC间隔为5分钟。而这在某些情况下会产生问题,如:私有离线部署环境中,如果某个node节点相关的镜像被清理了,当在这个启动相关容器就会失败,由于是离线,那么拉取镜像也会失败。
解决办法:
- 搭建离线私有镜像仓库;
- 关闭Kubernetes的GC对镜像的自动清理行为。
搭建离线私有镜像仓库
可选harbor和docker的Registry。
harbor有点复杂,不太好弄。
Registry安装很简单
关闭Kubernetes的GC对镜像的自动清理行为
我们可以配置kubelet的GC行为,--image-gc-high-threshold和--image-gc-low-threshold分别制定触发GC的磁盘使用百分比和GC停止的磁盘使用百分比。但是我们并没有找到哪里可以关闭kubernetes GC对镜像对自动清理行为,至少尝试关闭GC这种方法并不科学,如果关闭GC,那么垃圾会越来越多,最终导致磁盘用光,所以应该用其他思路解决这个问题。
这里我们重温一下问题:原来node A中,由于app1的pod副本并没有分配到node A,app1的镜像被GC清理了,当增加app1当pod副本数或者重启app1时,pod分配到node A,发现没有app1当镜像了,启动失败。当然,这都是因为离线环境和没有私有镜像仓库导致的。
关键问题在于镜像被清理了,我们要想办法重新load镜像,由于离线环境,也没有镜像仓库,只能从image的tar文件load出来,因此,我们可以利用pod或container的钩子来实现pod启动前,预先加载镜像。然而,遗憾的是,container的钩子只有postStart和preStop,没有preStart之类的钩子。