K8s 删除控制与GC原理
使用OwnerReferences和Finalizers做资源删除控制,并介绍k8s GC原理
目录
Control Deletion
Owner Referneces
一个常见的例子:ReplicaSet是Pod的Owner,ReplicaSet维持Pod数量,而Pod通过其metadata.ownerReferences字段链接到ReplicaSet;同样的ReplicaSet和Deployments也属于从属关系。
K8s资源默认使用级联删除,当我们删除Deployment时,与它所关联的ReplicaSet和Pod等也会一并被删除。
我们也可以指定非级联删除,那么Owner对象删除之后留下的资源会被称为孤儿对象。
级联删除分为前台(Foreground)和后台(Background)两种模式,默认是Background。
前台删除:(整个过程完成之前,被删除对象一直是可见的)
- 首先修改被删除的对象的metadata.deletionTimestamp字段;
- 然后设置对象的metadata.finalizers字段值为foregroundDeletion;
- 等待依赖项全部删除完成,最后清理该对象。
后台删除:
- 对象会被立即删除,controller会负责继续清理其依赖项。
Finalizers
Finalizers是k8s的删除拦截机制。Finalizers只是一个标记,Controller在回收资源时并不关心它的具体值,它只关心该资源是否有Finalizers这个Key。值中存放的更多是备注信息,提醒操作者需要注意释放的资源等。
拥有Finalizers的对象的删除会被分为三个步骤:
- 将被删除对象的metadata.deletionTimestamp更新为当前时间
- 禁止对象被删除,直到其
metadata.finalizers
字段为空 - 返回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:
空间使用率阈值,高于该值则触发GCLowThresholdPercent:
触发GC后空间使用率要降到的目标值
分别表示磁盘使用率的上限和下限,当磁盘使用超过上限时便会触发GC,直至磁盘使用率达到下限为止,如果未能释放出足够的空间,则会记录Warning事件。
Image GC
Image GC程序会从容器运行时异步获取所有镜像列表并缓存起来,同时另一个GC协程会每隔五分钟对镜像状态进行更新维护:
沙盒镜像和正在运行的容器使用中的镜像会被添加到正在使用列表,并且更新扫描镜像的以下信息
- 添加未缓存的镜像
- 如果是“正在使用的镜像”,更新它的“最近使用时间”为当前时间
- 更新镜像的大小
- 如果镜像已经不存在,则从缓存中移除
Image GC策略
- ImageGCHighThresholdPercent
- ImageGCLowThresholdPercent
- ImageMinimumGCAge:用来保护刚创建的Image不会被GC误清理
当GC程序根据设定的磁盘使用上限,决定清理无效镜像时:
- 首先会根据设定的下限和当前空间占用计算需要清理的空间大小,
- 接着根据所维护的所有镜像列表和正在使用列表找出未被使用的镜像。
- 然后根据镜像的“最近使用时间”排序,优先清理最久未被使用的镜像(LRU)
- 累计已清理的空间大小,直至达到目标。
需要注意的是,k8s并不会强制删除镜像,对于一个死亡容器所使用的镜像,GC会去尝试删除,但因为存在引用,删除操作会失败。
Container GC
容器 GC策略
- MinAge:最小存活时间,小于该值的容器不会被回收
- MaxPerPodContainer:每个Pod允许存在的死亡容器数量
- MaxContainers:整个集群运行存在的死亡容器数量
当容器因为异常而退出时,会成为死亡容器,此时Kubelet 可能会帮我们创建一个新的,当死亡容器数量达到设定值时,会优先清理最古老的死亡容器。
值得一提的是MaxContainers和MaxPerPodContainer在处理时可能会发生冲突:
集群中死亡容器数量已经超过阈值而每个Pod中的死亡容器数量却是符合要求的,此时kubelet会调整MaxPerPodContainer的值并开启清理。
当MaxPerPodContainer被设置为1时,每一个Pod的死亡容器只要Age超过了MinAge,就会被立刻清理。
更多推荐
所有评论(0)