From 9590b23264b65f2f89a06b39b5abbaa2c8dece23 Mon Sep 17 00:00:00 2001 From: Jan Chaloupka Date: Wed, 2 Dec 2015 14:10:32 +0100 Subject: [PATCH] LowThresholdPercent can not be higher than HighThresholdPercent if LowThresholdPercent > HighThresholdPercent, amountToFree at image_manager.go:208 is negative and image GC will not free memory properly. Justification: 1) LowThresholdPercent > HighThresholdPercent implies (LowThresholdPercent * capacity / 100) > (HighThresholdPercent * capacity / 100) 2) usage is at least (HighThresholdPercent * capacity / 100) 3) amountToFree = usage - (LowThresholdPercent * capacity / 100) Combining 1), 2) and 3) implies amountToFree can be negative. What happens if amountToFree is negative? in freeSpace method, "for _, image := range images " loops at least once and if everything goes fine, "delete(im.imageRecords, image.id)" is executed. When checking for condition "if spaceFreed >= bytesToFree", it is always true as bytesToFree is negative and spaceFreed is positive. The loop is finished, so is image GC. At the end, only the oldest image is deleted. In situations where there is a lot of dead containers, each container corresponing to distinct image, number of unused images can get higher. If two new images get pulled in every 5 minutes, image GC will not work properly and will not free enough space. Secondly, it will take a lot of time to free all unused images (hours depending on a number of unused images). This is an incorrect configuration. Image GC should report it and refuse to work. --- pkg/kubelet/image_manager.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/kubelet/image_manager.go b/pkg/kubelet/image_manager.go index dd31551f453..ab356d1b290 100644 --- a/pkg/kubelet/image_manager.go +++ b/pkg/kubelet/image_manager.go @@ -101,6 +101,9 @@ func newImageManager(runtime container.Runtime, cadvisorInterface cadvisor.Inter if policy.LowThresholdPercent < 0 || policy.LowThresholdPercent > 100 { return nil, fmt.Errorf("invalid LowThresholdPercent %d, must be in range [0-100]", policy.LowThresholdPercent) } + if policy.LowThresholdPercent > policy.HighThresholdPercent { + return nil, fmt.Errorf("LowThresholdPercent %d can not be higher than HighThresholdPercent %d", policy.LowThresholdPercent, policy.HighThresholdPercent) + } im := &realImageManager{ runtime: runtime, policy: policy,