在k8s的实际使用中,会在Node节点上残留许多老的镜像和无用的容器,当其堆积很多的时候就会占用节点的资源,造成不必要的资源浪费。针对这种想象,k8s通过kubelet组件可以对这些进行资源回收。其回收策略默认是每分钟对容器执行一次垃圾回收,每5分钟对镜像进行一次垃圾回收。

镜像回收

kubernetes借助cadvisor通过imageManager来管理镜像的生命周期。
镜像生命周期只考虑两个值:HighThresholdPercentLowThresholdPercent

  • HighThresholdPercent:磁盘的上限阈值
  • LowThresholdPercent:磁盘的下限阈值

怎么理解呢?所谓的上限阈值就是磁盘空间的使用率超过了定义的上限,就会触发垃圾回收。而下限阈值则是垃圾回收需要达到的下限。

这里举一个例子:比如有一个鱼塘,塘深100m,设置了两个水位线,其中一个是最高水位85m,也就是说鱼塘里的水不能超过85m,然后还设置了一个水位80m,我们认为这个水位之下是安全的。如果有一天因为暴雨水位超过了85m,那么管理员就会去放水,那放多少合适呢?这时候管理员就会参考安全水位,也就是说只要水位低于80m就认为其安全,所以只要讲水位保持下80m之下即可。

上面的85m就可以理解为磁盘上限,80m就理解为磁盘下限。

对于镜像回收,用户可以通过配置两个参数来进行调节:

  • image-gc-high-threshold
  • image-gc-low-threshold

从名字上看,image-gc-high-threshold就是需要设置的上限,默认是85%,image-gc-low-threshold就是需要设置的下限,默认是80%。

如果需要修改,就调整kubelet参数即可。

容器回收

容器垃圾回收策略考虑三个用户定义变量。

  • MinAge 是容器可以被执行垃圾回收的最小生命周期。
  • MaxPerPodContainer 是每个 pod 内允许存在的死亡容器的最大数量。
  • MaxContainers 是全部死亡容器的最大数量。

可以分别独立地通过将 MinAge 设置为 0,以及将 MaxPerPodContainer 和 MaxContainers 设置为小于 0 来禁用这些变量。

Kubelet 将处理无法辨识的、已删除的以及超出前面提到的参数所设置范围的容器。最老的容器通常会先被移除。MaxPerPodContainerMaxContainer 在某些场景下可能会存在冲突,例如在保证每个 pod 内死亡容器的最大数量(MaxPerPodContainer)的条件下可能会超过允许存在的全部死亡容器的最大数量(MaxContainer)。 MaxPerPodContainer 在这种情况下会被进行调整:最坏的情况是将 MaxPerPodContainer 降级为 1,并驱逐最老的容器。 此外,pod 内已经被删除的容器一旦年龄超过 MinAge 就会被清理。
不被 kubelet 管理的容器不受容器垃圾回收的约束。

用户可以通过配置kubelet以下参数来进行调整:

  • minimum-container-ttl-duration,完成的容器在被垃圾回收之前的最小年龄,默认是 0 分钟,这意味着每个完成的容器都会被执行垃圾回收。
  • maximum-dead-containers-per-container,每个容器要保留的旧实例的最大数量。默认值为 1。
  • maximum-dead-containers,要全局保留的旧容器实例的最大数量。默认值是 -1,这意味着没有全局限制。

容器可能会在其效用过期之前被垃圾回收。这些容器可能包含日志和其他对故障诊断有用的数据。 强烈建议为 maximum-dead-containers-per-container 设置一个足够大的值,以便每个预期容器至少保留一个死亡容器。 由于同样的原因,maximum-dead-containers 也建议使用一个足够大的值。

参考:https://kubernetes.io/zh/docs/concepts/cluster-administration/kubelet-garbage-collection/