Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automated cherry pick of #88915: let image cache do sort on write instead of on read to avoid #89073

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 11 additions & 6 deletions pkg/kubelet/images/image_gc_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,21 +113,26 @@ type imageCache struct {
images []container.Image
}

// set updates image cache.
// set sorts the input list and updates image cache.
// 'i' takes ownership of the list, you should not reference the list again
// after calling this function.
func (i *imageCache) set(images []container.Image) {
i.Lock()
defer i.Unlock()
// The image list needs to be sorted when it gets read and used in
// setNodeStatusImages. We sort the list on write instead of on read,
// because the image cache is more often read than written
sort.Sort(sliceutils.ByImageSize(images))
i.images = images
}

// get gets a sorted (by image size) image list from image cache.
// There is a potentical data race in this function. See PR #60448
// Because there is deepcopy function available currently, move sort
// function inside this function
// get gets image list from image cache.
// NOTE: The caller of get() should not do mutating operations on the
// returned list that could cause data race against other readers (e.g.
// in-place sorting the returned list)
func (i *imageCache) get() []container.Image {
i.Lock()
defer i.Unlock()
sort.Sort(sliceutils.ByImageSize(i.images))
return i.images
}

Expand Down
10 changes: 0 additions & 10 deletions pkg/kubelet/images/image_gc_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -548,16 +548,6 @@ func TestValidateImageGCPolicy(t *testing.T) {
}
}

func TestImageCacheReturnCopiedList(t *testing.T) {
cache := &imageCache{}
testList := []container.Image{{ID: "1"}, {ID: "2"}}
cache.set(testList)
list := cache.get()
assert.Len(t, list, 2)
list[0].ID = "3"
assert.Equal(t, cache.get(), testList)
}

func uint64Ptr(i uint64) *uint64 {
return &i
}
4 changes: 3 additions & 1 deletion pkg/kubelet/nodestatus/setters.go
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,9 @@ func Images(nodeStatusMaxImages int32,
}

for _, image := range containerImages {
names := append(image.RepoDigests, image.RepoTags...)
// make a copy to avoid modifying slice members of the image items in the list
names := append([]string{}, image.RepoDigests...)
names = append(names, image.RepoTags...)
// Report up to MaxNamesPerImageInNodeStatus names per image.
if len(names) > MaxNamesPerImageInNodeStatus {
names = names[0:MaxNamesPerImageInNodeStatus]
Expand Down