深入分析kubelet(4)—— ImageGC

2018-09-29  本文已影响0人  陈先生_9e91

深入分析kubelet(4)—— ImageGC

接着上一篇,继续介绍ImageGC过程

code

new

k8s.io\kubernetes\pkg\kubelet\kubelet.go

imageGCPolicy := images.ImageGCPolicy{
    MinAge:               kubeCfg.ImageMinimumGCAge.Duration,
    HighThresholdPercent: int(kubeCfg.ImageGCHighThresholdPercent),
    LowThresholdPercent:  int(kubeCfg.ImageGCLowThresholdPercent),
}
    
images.NewImageGCManager(klet.containerRuntime, klet.StatsProvider, kubeDeps.Recorder, nodeRef, imageGCPolicy, crOptions.PodSandboxImage)

参数说明:
k8s.io\kubernetes\pkg\kubelet\apis\kubeletconfig\types.go

start

// ImageGCPeriod is the period for performing image garbage collection.
    ImageGCPeriod = 5 * time.Minute

// StartGarbageCollection starts garbage collection threads.
func (kl *Kubelet) StartGarbageCollection() {
    go wait.Until(func() {
        kl.imageManager.GarbageCollect()
    }, ImageGCPeriod, wait.NeverStop)
}

每5分钟执行一次image gc

gc

k8s.io\kubernetes\pkg\kubelet\images\image_gc_manager.go

func (im *realImageGCManager) GarbageCollect() error {
    // Get disk usage on disk holding images.
    fsStats, err := im.statsProvider.ImageFsStats()
    
    var capacity, available int64
    if fsStats.CapacityBytes != nil {
        capacity = int64(*fsStats.CapacityBytes)
    }
    if fsStats.AvailableBytes != nil {
        available = int64(*fsStats.AvailableBytes)
    }
    
    // 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
        im.freeSpace(amountToFree, time.Now())
    }
}

获取镜像盘信息,根据策略算出需要释放多少磁盘空间。

// Tries to free bytesToFree worth of images on the disk.
//
// Returns the number of bytes free and an error if any occurred. The number of
// bytes freed is always returned.
// Note that error may be nil and the number of bytes free may be less
// than bytesToFree.
func (im *realImageGCManager) freeSpace(bytesToFree int64, freeTime time.Time) (int64, error) {
    imagesInUse, err := im.detectImages(freeTime)

    // Get all images in eviction order.
    images := make([]evictionInfo, 0, len(im.imageRecords))
    for image, record := range im.imageRecords {
        if isImageUsed(image, imagesInUse) {
            continue
        }
        images = append(images, evictionInfo{
            id:          image,
            imageRecord: *record,
        })
    }
    sort.Sort(byLastUsedAndDetected(images))

    // Delete unused images until we've freed up enough space.
    var deletionErrors []error
    spaceFreed := int64(0)
    for _, image := range images {
        // Images that are currently in used were given a newer lastUsed.
        if image.lastUsed.Equal(freeTime) || image.lastUsed.After(freeTime) {
            continue
        }

        // Avoid garbage collect the image if the image is not old enough.
        // In such a case, the image may have just been pulled down, and will be used by a container right away.
        if freeTime.Sub(image.firstDetected) < im.policy.MinAge {
            continue
        }

        // Remove image. Continue despite errors.
        im.runtime.RemoveImage(container.ImageSpec{Image: image.id})
        
        spaceFreed += image.size

        if spaceFreed >= bytesToFree {
            break
        }
}

找到没有正在使用的镜像,按照上次使用时间排序,删除最久没有使用过的镜像。上次使用时间差必须大于MinAge,最后通过CRI删除镜像。

如果释放资源不满足要求,会返回错误。

上一篇下一篇

猜你喜欢

热点阅读