Skip to content

Commit

Permalink
Merge pull request #25088 from ncdc/image-digests
Browse files Browse the repository at this point in the history
Automatic merge from submit-queue

Handle image digests in node status and image GC

Start including Docker image digests in the node status and consider image digests during image
garbage collection.

@kubernetes/rh-cluster-infra @kubernetes/sig-node @smarterclayton 

Fixes #23917
  • Loading branch information
k8s-merge-robot committed May 8, 2016
2 parents 633c27c + f091ea5 commit 071295c
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 11 deletions.
2 changes: 1 addition & 1 deletion pkg/kubelet/container/image_puller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func TestPuller(t *testing.T) {
fakeRecorder := &record.FakeRecorder{}
puller := NewImagePuller(fakeRecorder, fakeRuntime, backOff)

fakeRuntime.ImageList = []Image{{"present_image", nil, 0}}
fakeRuntime.ImageList = []Image{{"present_image", nil, nil, 1}}
fakeRuntime.Err = c.pullerErr
fakeRuntime.InspectErr = c.inspectErr

Expand Down
2 changes: 2 additions & 0 deletions pkg/kubelet/container/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,8 @@ type Image struct {
ID string
// Other names by which this image is known.
RepoTags []string
// Digests by which this image is known.
RepoDigests []string
// The size of the image in bytes.
Size int64
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/kubelet/container/serialized_image_puller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func TestSerializedPuller(t *testing.T) {
fakeRecorder := &record.FakeRecorder{}
puller := NewSerializedImagePuller(fakeRecorder, fakeRuntime, backOff)

fakeRuntime.ImageList = []Image{{"present_image", nil, 0}}
fakeRuntime.ImageList = []Image{{"present_image", nil, nil, 0}}
fakeRuntime.Err = c.pullerErr
fakeRuntime.InspectErr = c.inspectErr

Expand Down
7 changes: 4 additions & 3 deletions pkg/kubelet/dockertools/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,9 @@ func toRuntimeImage(image *dockertypes.Image) (*kubecontainer.Image, error) {
}

return &kubecontainer.Image{
ID: image.ID,
RepoTags: image.RepoTags,
Size: image.VirtualSize,
ID: image.ID,
RepoTags: image.RepoTags,
RepoDigests: image.RepoDigests,
Size: image.VirtualSize,
}, nil
}
8 changes: 5 additions & 3 deletions pkg/kubelet/dockertools/convert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,14 @@ func TestToRuntimeImage(t *testing.T) {
original := &dockertypes.Image{
ID: "aeeea",
RepoTags: []string{"abc", "def"},
RepoDigests: []string{"123", "456"},
VirtualSize: 1234,
}
expected := &kubecontainer.Image{
ID: "aeeea",
RepoTags: []string{"abc", "def"},
Size: 1234,
ID: "aeeea",
RepoTags: []string{"abc", "def"},
RepoDigests: []string{"123", "456"},
Size: 1234,
}

actual, err := toRuntimeImage(original)
Expand Down
13 changes: 11 additions & 2 deletions pkg/kubelet/image_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ func (im *realImageManager) detectImages(detectTime time.Time) error {
imagesInUse := sets.NewString()
for _, pod := range pods {
for _, container := range pod.Containers {
glog.V(5).Infof("Pod %s/%s, container %s uses image %s", pod.Namespace, pod.Name, container.Name, container.Image)
imagesInUse.Insert(container.Image)
}
}
Expand All @@ -174,26 +175,31 @@ func (im *realImageManager) detectImages(detectTime time.Time) error {
im.imageRecordsLock.Lock()
defer im.imageRecordsLock.Unlock()
for _, image := range images {
glog.V(5).Infof("Adding image ID %s to currentImages", image.ID)
currentImages.Insert(image.ID)

// New image, set it as detected now.
if _, ok := im.imageRecords[image.ID]; !ok {
glog.V(5).Infof("Image ID %s is new", image.ID)
im.imageRecords[image.ID] = &imageRecord{
firstDetected: detectTime,
}
}

// Set last used time to now if the image is being used.
if isImageUsed(image, imagesInUse) {
glog.V(5).Infof("Setting Image ID %s lastUsed to %v", image.ID, now)
im.imageRecords[image.ID].lastUsed = now
}

glog.V(5).Infof("Image ID %s has size %d", image.ID, image.Size)
im.imageRecords[image.ID].size = image.Size
}

// Remove old images from our records.
for image := range im.imageRecords {
if !currentImages.Has(image) {
glog.V(5).Infof("Image ID %s is no longer present; removing from imageRecords", image)
delete(im.imageRecords, image)
}
}
Expand Down Expand Up @@ -266,15 +272,18 @@ func (im *realImageManager) freeSpace(bytesToFree int64, freeTime time.Time) (in
var lastErr error
spaceFreed := int64(0)
for _, image := range images {
glog.V(5).Infof("Evaluating image ID %s for possible garbage collection", image.id)
// Images that are currently in used were given a newer lastUsed.
if image.lastUsed.Equal(freeTime) || image.lastUsed.After(freeTime) {
glog.V(5).Infof("Image ID %s has lastUsed=%v which is >= freeTime=%v, not eligible for garbage collection", image.id, image.lastUsed, freeTime)
break
}

// 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 {
glog.V(5).Infof("Image ID %s has age %v which is less than the policy's minAge of %v, not eligible for garbage collection", image.id, freeTime.Sub(image.firstDetected), im.policy.MinAge)
continue
}

Expand Down Expand Up @@ -315,11 +324,11 @@ func (ev byLastUsedAndDetected) Less(i, j int) bool {
}

func isImageUsed(image container.Image, imagesInUse sets.String) bool {
// Check the image ID and all the RepoTags.
// Check the image ID and all the RepoTags and RepoDigests.
if _, ok := imagesInUse[image.ID]; ok {
return true
}
for _, tag := range image.RepoTags {
for _, tag := range append(image.RepoTags, image.RepoDigests...) {
if _, ok := imagesInUse[tag]; ok {
return true
}
Expand Down
28 changes: 28 additions & 0 deletions pkg/kubelet/image_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,34 @@ func TestFreeSpaceImagesAlsoDoesLookupByRepoTags(t *testing.T) {
assert.Len(fakeRuntime.ImageList, 1)
}

func TestFreeSpaceImagesAlsoDoesLookupByRepoDigests(t *testing.T) {
manager, fakeRuntime, _ := newRealImageManager(ImageGCPolicy{})
fakeRuntime.ImageList = []container.Image{
makeImage(0, 1024),
{
ID: "5678",
RepoDigests: []string{"potato", "salad"},
Size: 2048,
},
}
fakeRuntime.AllPodList = []*container.Pod{
{
Containers: []*container.Container{
{
ID: container.ContainerID{Type: "test", ID: "c5678"},
Image: "salad",
},
},
},
}

spaceFreed, err := manager.freeSpace(1024, time.Now())
assert := assert.New(t)
require.NoError(t, err)
assert.EqualValues(1024, spaceFreed)
assert.Len(fakeRuntime.ImageList, 1)
}

func TestGarbageCollectBelowLowThreshold(t *testing.T) {
policy := ImageGCPolicy{
HighThresholdPercent: 90,
Expand Down
2 changes: 1 addition & 1 deletion pkg/kubelet/kubelet.go
Original file line number Diff line number Diff line change
Expand Up @@ -3009,7 +3009,7 @@ func (kl *Kubelet) setNodeStatusImages(node *api.Node) {
} else {
for _, image := range containerImages {
imagesOnNode = append(imagesOnNode, api.ContainerImage{
Names: image.RepoTags,
Names: append(image.RepoTags, image.RepoDigests...),
SizeBytes: image.Size,
})
}
Expand Down

0 comments on commit 071295c

Please sign in to comment.