目录

Control Deletion

Owner Referneces

Finalizers

Garbage Collection

Image GC

Container GC


Control Deletion

Owner Referneces

一个常见的例子:ReplicaSet是Pod的Owner,ReplicaSet维持Pod数量,而Pod通过其metadata.ownerReferences字段链接到ReplicaSet;同样的ReplicaSet和Deployments也属于从属关系。

K8s资源默认使用级联删除,当我们删除Deployment时,与它所关联的ReplicaSet和Pod等也会一并被删除。

我们也可以指定非级联删除,那么Owner对象删除之后留下的资源会被称为孤儿对象。

级联删除分为前台(Foreground)和后台(Background)两种模式,默认是Background。

前台删除:(整个过程完成之前,被删除对象一直是可见的)    

  1. 首先修改被删除的对象的metadata.deletionTimestamp字段;
  2. 然后设置对象的metadata.finalizers字段值为foregroundDeletion;
  3. 等待依赖项全部删除完成,最后清理该对象。

后台删除:

  • 对象会被立即删除,controller会负责继续清理其依赖项。

Finalizers

Finalizers是k8s的删除拦截机制。Finalizers只是一个标记,Controller在回收资源时并不关心它的具体值,它只关心该资源是否有Finalizers这个Key。值中存放的更多是备注信息,提醒操作者需要注意释放的资源等。

拥有Finalizers的对象的删除会被分为三个步骤:

  1. 将被删除对象的metadata.deletionTimestamp更新为当前时间
  2. 禁止对象被删除,直到其 metadata.finalizers 字段为空
  3. 返回202状态

一个常见的 Finalizer 的例子是 kubernetes.io/pv-protection。

以下命令可以移除资源的Finalizers,之后对象会自动进入删除队列,从注册表中最终删除。 

kubectl patch configmap configmapName -n namespace --type json -p '[ { "op": "remove", "path": "/metadata/finalizers" } ]'

Garbage Collection

Kubelet 每隔 1 分钟进行一次容器扫描,每隔 5 分钟进行一次镜像扫描。Kubelet 有两个启动参数:

  • HighThresholdPercent:空间使用率阈值,高于该值则触发GC
  • LowThresholdPercent:触发GC后空间使用率要降到的目标值

分别表示磁盘使用率的上限和下限,当磁盘使用超过上限时便会触发GC,直至磁盘使用率达到下限为止,如果未能释放出足够的空间,则会记录Warning事件。

Image GC

Image GC程序会从容器运行时异步获取所有镜像列表并缓存起来,同时另一个GC协程会每隔五分钟对镜像状态进行更新维护:

沙盒镜像和正在运行的容器使用中的镜像会被添加到正在使用列表,并且更新扫描镜像的以下信息

  • 添加未缓存的镜像
  • 如果是“正在使用的镜像”,更新它的“最近使用时间”为当前时间
  • 更新镜像的大小
  • 如果镜像已经不存在,则从缓存中移除

Image GC策略

  • ImageGCHighThresholdPercent
  • ImageGCLowThresholdPercent
  • ImageMinimumGCAge:用来保护刚创建的Image不会被GC误清理

当GC程序根据设定的磁盘使用上限,决定清理无效镜像时:

  1. 首先会根据设定的下限和当前空间占用计算需要清理的空间大小,
  2. 接着根据所维护的所有镜像列表正在使用列表找出未被使用的镜像。
  3. 然后根据镜像的“最近使用时间”排序,优先清理最久未被使用的镜像(LRU)
  4. 累计已清理的空间大小,直至达到目标。

需要注意的是,k8s并不会强制删除镜像,对于一个死亡容器所使用的镜像,GC会去尝试删除,但因为存在引用,删除操作会失败。

Container GC

容器 GC策略

  • MinAge:最小存活时间,小于该值的容器不会被回收
  • MaxPerPodContainer:每个Pod允许存在的死亡容器数量
  • MaxContainers:整个集群运行存在的死亡容器数量

当容器因为异常而退出时,会成为死亡容器,此时Kubelet 可能会帮我们创建一个新的,当死亡容器数量达到设定值时,会优先清理最古老的死亡容器。

值得一提的是MaxContainersMaxPerPodContainer在处理时可能会发生冲突:

集群中死亡容器数量已经超过阈值而每个Pod中的死亡容器数量却是符合要求的,此时kubelet会调整MaxPerPodContainer的值并开启清理。

MaxPerPodContainer被设置为1时,每一个Pod的死亡容器只要Age超过了MinAge,就会被立刻清理

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐