kubelet如何做GC(Garbage Collection)
by 伊布
生活处处有GC。
在使用kubernetes的时候,可能会有个疑问:用户在k8s上创建、删除了Deployment就走了,那么在node上残留的docker镜像是谁去删除的?不删除的话,日积月累,迟早耗尽node的硬盘空间。
其实k8s是有Image GC的。不知道你注意到了没有,硬盘空间紧张的时候,会发现下载到某个节点上的image会悄悄消失,其实这就是Image GC在工作。
在每个节点的kubelet配置文件/var/lib/kubelet/config.yaml
imageGCHighThresholdPercent: 85
imageGCLowThresholdPercent: 80
imageMinimumGCAge: 2m0s
策略是这样的:
当硬盘存储使用率超过imageGCHighThresholdPercent
时,会触发Image GC,直到硬盘存储使用率低于imageGCLowThresholdPercent
。
这里说的存储空间指的是image fs,即docker存储image的分区。
相关代码在pkg/kubelet/images/image_gc_manager.go:GarbageCollect
中。
// If over the max threshold, free enough to place us at the lower threshold.
usagePercent := 100 - int(available*100/capacity)
if usagePercent >= im.policy.HighThresholdPercent {
amountToFree := capacity*int64(100-im.policy.LowThresholdPercent)/100 - available
glog.Infof("[imageGCManager]: Disk usage on image filesystem is at %d%% which is over the high threshold (%d%%). Trying to free %d bytes", usagePercent, im.policy.HighThresholdPercent, amountToFree)
freed, err := im.freeSpace(amountToFree, time.Now())
if err != nil {
return err
}
if freed < amountToFree {
err := fmt.Errorf("failed to garbage collect required amount of images. Wanted to free %d bytes, but freed %d bytes", amountToFree, freed)
im.recorder.Eventf(im.nodeRef, v1.EventTypeWarning, events.FreeDiskSpaceFailed, err.Error())
return err
}
}
代码比较简单,判断空间不足则启动freeSpace,也不多free,就free到低水。
freeSpace也不复杂。思路就是从node上所有images中,剔除正在使用的image,按最后使用的时间进行排序,优先处理老image;再剔除发现的时间小于 imageMinimumGCAge
的image,之后调用cri删除该image。
Ref:
Subscribe via RSS