vendor updates

This commit is contained in:
Serguei Bezverkhi
2018-03-06 17:33:18 -05:00
parent 4b3ebc171b
commit e9033989a0
5854 changed files with 248382 additions and 119809 deletions

View File

@ -39,8 +39,7 @@ go_test(
"image_gc_manager_test.go",
"image_manager_test.go",
],
importpath = "k8s.io/kubernetes/pkg/kubelet/images",
library = ":go_default_library",
embed = [":go_default_library"],
deps = [
"//pkg/kubelet/apis/stats/v1alpha1:go_default_library",
"//pkg/kubelet/container:go_default_library",

View File

@ -33,7 +33,6 @@ import (
"k8s.io/client-go/tools/record"
statsapi "k8s.io/kubernetes/pkg/kubelet/apis/stats/v1alpha1"
"k8s.io/kubernetes/pkg/kubelet/container"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/events"
)
@ -55,10 +54,10 @@ type ImageGCManager interface {
// Start async garbage collection of images.
Start()
GetImageList() ([]kubecontainer.Image, error)
GetImageList() ([]container.Image, error)
// Delete all unused images and returns the number of bytes freed. The number of bytes freed is always returned.
DeleteUnusedImages() (int64, error)
// Delete all unused images.
DeleteUnusedImages() error
}
// A policy for garbage collecting images. Policy defines an allowed band in
@ -101,6 +100,9 @@ type realImageGCManager struct {
// imageCache is the cache of latest image list.
imageCache imageCache
// sandbox image exempted from GC
sandboxImage string
}
// imageCache caches latest result of ListImages.
@ -108,21 +110,21 @@ type imageCache struct {
// sync.RWMutex is the mutex protects the image cache.
sync.RWMutex
// images is the image cache.
images []kubecontainer.Image
images []container.Image
}
// set updates image cache.
func (i *imageCache) set(images []kubecontainer.Image) {
func (i *imageCache) set(images []container.Image) {
i.Lock()
defer i.Unlock()
i.images = images
}
// get gets image list from image cache.
func (i *imageCache) get() []kubecontainer.Image {
func (i *imageCache) get() []container.Image {
i.RLock()
defer i.RUnlock()
return i.images
return append([]container.Image{}, i.images...)
}
// Information about the images we track.
@ -137,7 +139,7 @@ type imageRecord struct {
size int64
}
func NewImageGCManager(runtime container.Runtime, statsProvider StatsProvider, recorder record.EventRecorder, nodeRef *v1.ObjectReference, policy ImageGCPolicy) (ImageGCManager, error) {
func NewImageGCManager(runtime container.Runtime, statsProvider StatsProvider, recorder record.EventRecorder, nodeRef *v1.ObjectReference, policy ImageGCPolicy, sandboxImage string) (ImageGCManager, error) {
// Validate policy.
if policy.HighThresholdPercent < 0 || policy.HighThresholdPercent > 100 {
return nil, fmt.Errorf("invalid HighThresholdPercent %d, must be in range [0-100]", policy.HighThresholdPercent)
@ -156,6 +158,7 @@ func NewImageGCManager(runtime container.Runtime, statsProvider StatsProvider, r
recorder: recorder,
nodeRef: nodeRef,
initialized: false,
sandboxImage: sandboxImage,
}
return im, nil
@ -168,7 +171,7 @@ func (im *realImageGCManager) Start() {
if im.initialized {
ts = time.Now()
}
err := im.detectImages(ts)
_, err := im.detectImages(ts)
if err != nil {
glog.Warningf("[imageGCManager] Failed to monitor images: %v", err)
} else {
@ -190,22 +193,29 @@ func (im *realImageGCManager) Start() {
}
// Get a list of images on this node
func (im *realImageGCManager) GetImageList() ([]kubecontainer.Image, error) {
func (im *realImageGCManager) GetImageList() ([]container.Image, error) {
return im.imageCache.get(), nil
}
func (im *realImageGCManager) detectImages(detectTime time.Time) error {
func (im *realImageGCManager) detectImages(detectTime time.Time) (sets.String, error) {
imagesInUse := sets.NewString()
// Always consider the container runtime pod sandbox image in use
imageRef, err := im.runtime.GetImageRef(container.ImageSpec{Image: im.sandboxImage})
if err == nil && imageRef != "" {
imagesInUse.Insert(imageRef)
}
images, err := im.runtime.ListImages()
if err != nil {
return err
return imagesInUse, err
}
pods, err := im.runtime.GetPods(true)
if err != nil {
return err
return imagesInUse, err
}
// Make a set of images in use by containers.
imagesInUse := sets.NewString()
for _, pod := range pods {
for _, container := range pod.Containers {
glog.V(5).Infof("Pod %s/%s, container %s uses image %s(%s)", pod.Namespace, pod.Name, container.Name, container.Image, container.ImageID)
@ -231,7 +241,7 @@ func (im *realImageGCManager) detectImages(detectTime time.Time) error {
}
// Set last used time to now if the image is being used.
if isImageUsed(image, imagesInUse) {
if isImageUsed(image.ID, imagesInUse) {
glog.V(5).Infof("Setting Image ID %s lastUsed to %v", image.ID, now)
im.imageRecords[image.ID].lastUsed = now
}
@ -248,7 +258,7 @@ func (im *realImageGCManager) detectImages(detectTime time.Time) error {
}
}
return nil
return imagesInUse, nil
}
func (im *realImageGCManager) GarbageCollect() error {
@ -298,8 +308,10 @@ func (im *realImageGCManager) GarbageCollect() error {
return nil
}
func (im *realImageGCManager) DeleteUnusedImages() (int64, error) {
return im.freeSpace(math.MaxInt64, time.Now())
func (im *realImageGCManager) DeleteUnusedImages() error {
glog.Infof("attempting to delete unused images")
_, err := im.freeSpace(math.MaxInt64, time.Now())
return err
}
// Tries to free bytesToFree worth of images on the disk.
@ -309,7 +321,7 @@ func (im *realImageGCManager) DeleteUnusedImages() (int64, error) {
// 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) {
err := im.detectImages(freeTime)
imagesInUse, err := im.detectImages(freeTime)
if err != nil {
return 0, err
}
@ -320,6 +332,10 @@ func (im *realImageGCManager) freeSpace(bytesToFree int64, freeTime time.Time) (
// Get all images in eviction order.
images := make([]evictionInfo, 0, len(im.imageRecords))
for image, record := range im.imageRecords {
if isImageUsed(image, imagesInUse) {
glog.V(5).Infof("Image ID %s is being used", image)
continue
}
images = append(images, evictionInfo{
id: image,
imageRecord: *record,
@ -335,7 +351,7 @@ func (im *realImageGCManager) freeSpace(bytesToFree int64, freeTime time.Time) (
// 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
continue
}
// Avoid garbage collect the image if the image is not old enough.
@ -385,9 +401,9 @@ func (ev byLastUsedAndDetected) Less(i, j int) bool {
}
}
func isImageUsed(image container.Image, imagesInUse sets.String) bool {
func isImageUsed(imageID string, imagesInUse sets.String) bool {
// Check the image ID.
if _, ok := imagesInUse[image.ID]; ok {
if _, ok := imagesInUse[imageID]; ok {
return true
}
return false

View File

@ -33,6 +33,7 @@ import (
)
var zero time.Time
var sandboxImage = "k8s.gcr.io/pause-amd64:latest"
func newRealImageGCManager(policy ImageGCPolicy) (*realImageGCManager, *containertest.FakeRuntime, *statstest.StatsProvider) {
fakeRuntime := &containertest.FakeRuntime{}
@ -43,6 +44,7 @@ func newRealImageGCManager(policy ImageGCPolicy) (*realImageGCManager, *containe
imageRecords: make(map[string]*imageRecord),
statsProvider: mockStatsProvider,
recorder: &record.FakeRecorder{},
sandboxImage: sandboxImage,
}, fakeRuntime, mockStatsProvider
}
@ -112,7 +114,7 @@ func TestDetectImagesInitialDetect(t *testing.T) {
}
startTime := time.Now().Add(-time.Millisecond)
err := manager.detectImages(zero)
_, err := manager.detectImages(zero)
assert := assert.New(t)
require.NoError(t, err)
assert.Equal(manager.imageRecordsLen(), 3)
@ -145,7 +147,7 @@ func TestDetectImagesWithNewImage(t *testing.T) {
}},
}
err := manager.detectImages(zero)
_, err := manager.detectImages(zero)
assert := assert.New(t)
require.NoError(t, err)
assert.Equal(manager.imageRecordsLen(), 2)
@ -159,7 +161,7 @@ func TestDetectImagesWithNewImage(t *testing.T) {
detectedTime := zero.Add(time.Second)
startTime := time.Now().Add(-time.Millisecond)
err = manager.detectImages(detectedTime)
_, err = manager.detectImages(detectedTime)
require.NoError(t, err)
assert.Equal(manager.imageRecordsLen(), 3)
noContainer, ok := manager.getImageRecord(imageID(0))
@ -176,6 +178,21 @@ func TestDetectImagesWithNewImage(t *testing.T) {
assert.Equal(zero, noContainer.lastUsed)
}
func TestDeleteUnusedImagesExemptSandboxImage(t *testing.T) {
manager, fakeRuntime, _ := newRealImageGCManager(ImageGCPolicy{})
fakeRuntime.ImageList = []container.Image{
{
ID: sandboxImage,
Size: 1024,
},
}
err := manager.DeleteUnusedImages()
assert := assert.New(t)
assert.Len(fakeRuntime.ImageList, 1)
require.NoError(t, err)
}
func TestDetectImagesContainerStopped(t *testing.T) {
manager, fakeRuntime, _ := newRealImageGCManager(ImageGCPolicy{})
fakeRuntime.ImageList = []container.Image{
@ -190,7 +207,7 @@ func TestDetectImagesContainerStopped(t *testing.T) {
}},
}
err := manager.detectImages(zero)
_, err := manager.detectImages(zero)
assert := assert.New(t)
require.NoError(t, err)
assert.Equal(manager.imageRecordsLen(), 2)
@ -199,7 +216,7 @@ func TestDetectImagesContainerStopped(t *testing.T) {
// Simulate container being stopped.
fakeRuntime.AllPodList = []*containertest.FakePod{}
err = manager.detectImages(time.Now())
_, err = manager.detectImages(time.Now())
require.NoError(t, err)
assert.Equal(manager.imageRecordsLen(), 2)
container1, ok := manager.getImageRecord(imageID(0))
@ -226,14 +243,14 @@ func TestDetectImagesWithRemovedImages(t *testing.T) {
}},
}
err := manager.detectImages(zero)
_, err := manager.detectImages(zero)
assert := assert.New(t)
require.NoError(t, err)
assert.Equal(manager.imageRecordsLen(), 2)
// Simulate both images being removed.
fakeRuntime.ImageList = []container.Image{}
err = manager.detectImages(time.Now())
_, err = manager.detectImages(time.Now())
require.NoError(t, err)
assert.Equal(manager.imageRecordsLen(), 0)
}
@ -274,10 +291,9 @@ func TestDeleteUnusedImagesRemoveAllUnusedImages(t *testing.T) {
}},
}
spaceFreed, err := manager.DeleteUnusedImages()
err := manager.DeleteUnusedImages()
assert := assert.New(t)
require.NoError(t, err)
assert.EqualValues(3072, spaceFreed)
assert.Len(fakeRuntime.ImageList, 1)
}
@ -297,7 +313,8 @@ func TestFreeSpaceRemoveByLeastRecentlyUsed(t *testing.T) {
}
// Make 1 be more recently used than 0.
require.NoError(t, manager.detectImages(zero))
_, err := manager.detectImages(zero)
require.NoError(t, err)
fakeRuntime.AllPodList = []*containertest.FakePod{
{Pod: &container.Pod{
Containers: []*container.Container{
@ -305,13 +322,15 @@ func TestFreeSpaceRemoveByLeastRecentlyUsed(t *testing.T) {
},
}},
}
require.NoError(t, manager.detectImages(time.Now()))
_, err = manager.detectImages(time.Now())
require.NoError(t, err)
fakeRuntime.AllPodList = []*containertest.FakePod{
{Pod: &container.Pod{
Containers: []*container.Container{},
}},
}
require.NoError(t, manager.detectImages(time.Now()))
_, err = manager.detectImages(time.Now())
require.NoError(t, err)
require.Equal(t, manager.imageRecordsLen(), 2)
spaceFreed, err := manager.freeSpace(1024, time.Now())
@ -335,14 +354,17 @@ func TestFreeSpaceTiesBrokenByDetectedTime(t *testing.T) {
}
// Make 1 more recently detected but used at the same time as 0.
require.NoError(t, manager.detectImages(zero))
_, err := manager.detectImages(zero)
require.NoError(t, err)
fakeRuntime.ImageList = []container.Image{
makeImage(0, 1024),
makeImage(1, 2048),
}
require.NoError(t, manager.detectImages(time.Now()))
_, err = manager.detectImages(time.Now())
require.NoError(t, err)
fakeRuntime.AllPodList = []*containertest.FakePod{}
require.NoError(t, manager.detectImages(time.Now()))
_, err = manager.detectImages(time.Now())
require.NoError(t, err)
require.Equal(t, manager.imageRecordsLen(), 2)
spaceFreed, err := manager.freeSpace(1024, time.Now())
@ -448,7 +470,8 @@ func TestGarbageCollectImageNotOldEnough(t *testing.T) {
fakeClock := clock.NewFakeClock(time.Now())
t.Log(fakeClock.Now())
require.NoError(t, manager.detectImages(fakeClock.Now()))
_, err := manager.detectImages(fakeClock.Now())
require.NoError(t, err)
require.Equal(t, manager.imageRecordsLen(), 2)
// no space freed since one image is in used, and another one is not old enough
spaceFreed, err := manager.freeSpace(1024, fakeClock.Now())
@ -517,7 +540,7 @@ func TestValidateImageGCPolicy(t *testing.T) {
}
for _, tc := range testCases {
if _, err := NewImageGCManager(nil, nil, nil, nil, tc.imageGCPolicy); err != nil {
if _, err := NewImageGCManager(nil, nil, nil, nil, tc.imageGCPolicy, ""); err != nil {
if err.Error() != tc.expectErr {
t.Errorf("[%s:]Expected err:%v, but got:%v", tc.name, tc.expectErr, err.Error())
}
@ -525,6 +548,16 @@ 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
}

View File

@ -154,11 +154,12 @@ func applyDefaultImageTag(image string) (string, error) {
_, isTagged := named.(dockerref.Tagged)
_, isDigested := named.(dockerref.Digested)
if !isTagged && !isDigested {
named, err := dockerref.WithTag(named, parsers.DefaultImageTag)
if err != nil {
return "", fmt.Errorf("failed to apply default image tag %q: %v", image, err)
}
image = named.String()
// we just concatenate the image name with the default tag here instead
// of using dockerref.WithTag(named, ...) because that would cause the
// image to be fully qualified as docker.io/$name if it's a short name
// (e.g. just busybox). We don't want that to happen to keep the CRI
// agnostic wrt image names and default hostnames.
image = image + ":" + parsers.DefaultImageTag
}
return image, nil
}

View File

@ -125,7 +125,7 @@ func pullerTestEnv(c pullerTestCase, serialized bool) (puller ImageManager, fake
fakeRuntime = &ctest.FakeRuntime{}
fakeRecorder := &record.FakeRecorder{}
fakeRuntime.ImageList = []Image{{ID: "docker.io/library/present_image:latest"}}
fakeRuntime.ImageList = []Image{{ID: "present_image:latest"}}
fakeRuntime.Err = c.pullerErr
fakeRuntime.InspectErr = c.inspectErr
@ -188,7 +188,7 @@ func TestApplyDefaultImageTag(t *testing.T) {
Input string
Output string
}{
{Input: "root", Output: "docker.io/library/root:latest"},
{Input: "root", Output: "root:latest"},
{Input: "root:tag", Output: "root:tag"},
{Input: "root@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", Output: "root@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"},
} {