plumb context from CRI calls through kubelet

This commit is contained in:
David Ashpole
2022-10-27 20:03:05 +00:00
parent 6e31c6531f
commit f43b4f1b95
115 changed files with 1440 additions and 1183 deletions

View File

@@ -17,6 +17,7 @@ limitations under the License.
package eviction
import (
"context"
"fmt"
"sort"
"sync"
@@ -230,6 +231,7 @@ func (m *managerImpl) IsUnderPIDPressure() bool {
// synchronize is the main control loop that enforces eviction thresholds.
// Returns the pod that was killed, or nil if no pod was killed.
func (m *managerImpl) synchronize(diskInfoProvider DiskInfoProvider, podFunc ActivePodsFunc) []*v1.Pod {
ctx := context.Background()
// if we have nothing to do, just return
thresholds := m.config.Thresholds
if len(thresholds) == 0 && !m.localStorageCapacityIsolation {
@@ -240,7 +242,7 @@ func (m *managerImpl) synchronize(diskInfoProvider DiskInfoProvider, podFunc Act
// build the ranking functions (if not yet known)
// TODO: have a function in cadvisor that lets us know if global housekeeping has completed
if m.dedicatedImageFs == nil {
hasImageFs, ok := diskInfoProvider.HasDedicatedImageFs()
hasImageFs, ok := diskInfoProvider.HasDedicatedImageFs(ctx)
if ok != nil {
return nil
}
@@ -251,7 +253,7 @@ func (m *managerImpl) synchronize(diskInfoProvider DiskInfoProvider, podFunc Act
activePods := podFunc()
updateStats := true
summary, err := m.summaryProvider.Get(updateStats)
summary, err := m.summaryProvider.Get(ctx, updateStats)
if err != nil {
klog.ErrorS(err, "Eviction manager: failed to get summary stats")
return nil
@@ -343,7 +345,7 @@ func (m *managerImpl) synchronize(diskInfoProvider DiskInfoProvider, podFunc Act
m.recorder.Eventf(m.nodeRef, v1.EventTypeWarning, "EvictionThresholdMet", "Attempting to reclaim %s", resourceToReclaim)
// check if there are node-level resources we can reclaim to reduce pressure before evicting end-user pods.
if m.reclaimNodeLevelResources(thresholdToReclaim.Signal, resourceToReclaim) {
if m.reclaimNodeLevelResources(ctx, thresholdToReclaim.Signal, resourceToReclaim) {
klog.InfoS("Eviction manager: able to reduce resource pressure without evicting pods.", "resourceName", resourceToReclaim)
return nil
}
@@ -418,17 +420,17 @@ func (m *managerImpl) waitForPodsCleanup(podCleanedUpFunc PodCleanedUpFunc, pods
}
// reclaimNodeLevelResources attempts to reclaim node level resources. returns true if thresholds were satisfied and no pod eviction is required.
func (m *managerImpl) reclaimNodeLevelResources(signalToReclaim evictionapi.Signal, resourceToReclaim v1.ResourceName) bool {
func (m *managerImpl) reclaimNodeLevelResources(ctx context.Context, signalToReclaim evictionapi.Signal, resourceToReclaim v1.ResourceName) bool {
nodeReclaimFuncs := m.signalToNodeReclaimFuncs[signalToReclaim]
for _, nodeReclaimFunc := range nodeReclaimFuncs {
// attempt to reclaim the pressured resource.
if err := nodeReclaimFunc(); err != nil {
if err := nodeReclaimFunc(ctx); err != nil {
klog.InfoS("Eviction manager: unexpected error when attempting to reduce resource pressure", "resourceName", resourceToReclaim, "err", err)
}
}
if len(nodeReclaimFuncs) > 0 {
summary, err := m.summaryProvider.Get(true)
summary, err := m.summaryProvider.Get(ctx, true)
if err != nil {
klog.ErrorS(err, "Eviction manager: failed to get summary stats after resource reclaim")
return false

View File

@@ -17,6 +17,7 @@ limitations under the License.
package eviction
import (
"context"
"fmt"
"testing"
"time"
@@ -67,7 +68,7 @@ type mockDiskInfoProvider struct {
}
// HasDedicatedImageFs returns the mocked value
func (m *mockDiskInfoProvider) HasDedicatedImageFs() (bool, error) {
func (m *mockDiskInfoProvider) HasDedicatedImageFs(_ context.Context) (bool, error) {
return m.dedicatedImageFs, nil
}
@@ -81,7 +82,7 @@ type mockDiskGC struct {
}
// DeleteUnusedImages returns the mocked values.
func (m *mockDiskGC) DeleteUnusedImages() error {
func (m *mockDiskGC) DeleteUnusedImages(_ context.Context) error {
m.imageGCInvoked = true
if m.summaryAfterGC != nil && m.fakeSummaryProvider != nil {
m.fakeSummaryProvider.result = m.summaryAfterGC
@@ -90,7 +91,7 @@ func (m *mockDiskGC) DeleteUnusedImages() error {
}
// DeleteAllUnusedContainers returns the mocked value
func (m *mockDiskGC) DeleteAllUnusedContainers() error {
func (m *mockDiskGC) DeleteAllUnusedContainers(_ context.Context) error {
m.containerGCInvoked = true
if m.summaryAfterGC != nil && m.fakeSummaryProvider != nil {
m.fakeSummaryProvider.result = m.summaryAfterGC

View File

@@ -17,6 +17,7 @@ limitations under the License.
package eviction
import (
"context"
"fmt"
"reflect"
"sort"
@@ -1185,11 +1186,11 @@ type fakeSummaryProvider struct {
result *statsapi.Summary
}
func (f *fakeSummaryProvider) Get(updateStats bool) (*statsapi.Summary, error) {
func (f *fakeSummaryProvider) Get(ctx context.Context, updateStats bool) (*statsapi.Summary, error) {
return f.result, nil
}
func (f *fakeSummaryProvider) GetCPUAndMemoryStats() (*statsapi.Summary, error) {
func (f *fakeSummaryProvider) GetCPUAndMemoryStats(ctx context.Context) (*statsapi.Summary, error) {
return f.result, nil
}

View File

@@ -21,6 +21,7 @@ limitations under the License.
package eviction
import (
context "context"
reflect "reflect"
time "time"
@@ -129,18 +130,18 @@ func (m *MockDiskInfoProvider) EXPECT() *MockDiskInfoProviderMockRecorder {
}
// HasDedicatedImageFs mocks base method.
func (m *MockDiskInfoProvider) HasDedicatedImageFs() (bool, error) {
func (m *MockDiskInfoProvider) HasDedicatedImageFs(ctx context.Context) (bool, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "HasDedicatedImageFs")
ret := m.ctrl.Call(m, "HasDedicatedImageFs", ctx)
ret0, _ := ret[0].(bool)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// HasDedicatedImageFs indicates an expected call of HasDedicatedImageFs.
func (mr *MockDiskInfoProviderMockRecorder) HasDedicatedImageFs() *gomock.Call {
func (mr *MockDiskInfoProviderMockRecorder) HasDedicatedImageFs(ctx interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasDedicatedImageFs", reflect.TypeOf((*MockDiskInfoProvider)(nil).HasDedicatedImageFs))
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasDedicatedImageFs", reflect.TypeOf((*MockDiskInfoProvider)(nil).HasDedicatedImageFs), ctx)
}
// MockImageGC is a mock of ImageGC interface.
@@ -167,17 +168,17 @@ func (m *MockImageGC) EXPECT() *MockImageGCMockRecorder {
}
// DeleteUnusedImages mocks base method.
func (m *MockImageGC) DeleteUnusedImages() error {
func (m *MockImageGC) DeleteUnusedImages(ctx context.Context) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DeleteUnusedImages")
ret := m.ctrl.Call(m, "DeleteUnusedImages", ctx)
ret0, _ := ret[0].(error)
return ret0
}
// DeleteUnusedImages indicates an expected call of DeleteUnusedImages.
func (mr *MockImageGCMockRecorder) DeleteUnusedImages() *gomock.Call {
func (mr *MockImageGCMockRecorder) DeleteUnusedImages(ctx interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUnusedImages", reflect.TypeOf((*MockImageGC)(nil).DeleteUnusedImages))
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUnusedImages", reflect.TypeOf((*MockImageGC)(nil).DeleteUnusedImages), ctx)
}
// MockContainerGC is a mock of ContainerGC interface.
@@ -204,17 +205,17 @@ func (m *MockContainerGC) EXPECT() *MockContainerGCMockRecorder {
}
// DeleteAllUnusedContainers mocks base method.
func (m *MockContainerGC) DeleteAllUnusedContainers() error {
func (m *MockContainerGC) DeleteAllUnusedContainers(ctx context.Context) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DeleteAllUnusedContainers")
ret := m.ctrl.Call(m, "DeleteAllUnusedContainers", ctx)
ret0, _ := ret[0].(error)
return ret0
}
// DeleteAllUnusedContainers indicates an expected call of DeleteAllUnusedContainers.
func (mr *MockContainerGCMockRecorder) DeleteAllUnusedContainers() *gomock.Call {
func (mr *MockContainerGCMockRecorder) DeleteAllUnusedContainers(ctx interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAllUnusedContainers", reflect.TypeOf((*MockContainerGC)(nil).DeleteAllUnusedContainers))
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAllUnusedContainers", reflect.TypeOf((*MockContainerGC)(nil).DeleteAllUnusedContainers), ctx)
}
// MockCgroupNotifier is a mock of CgroupNotifier interface.

View File

@@ -18,6 +18,7 @@ limitations under the License.
package eviction
import (
"context"
"time"
v1 "k8s.io/api/core/v1"
@@ -71,19 +72,19 @@ type Manager interface {
// DiskInfoProvider is responsible for informing the manager how disk is configured.
type DiskInfoProvider interface {
// HasDedicatedImageFs returns true if the imagefs is on a separate device from the rootfs.
HasDedicatedImageFs() (bool, error)
HasDedicatedImageFs(ctx context.Context) (bool, error)
}
// ImageGC is responsible for performing garbage collection of unused images.
type ImageGC interface {
// DeleteUnusedImages deletes unused images.
DeleteUnusedImages() error
DeleteUnusedImages(ctx context.Context) error
}
// ContainerGC is responsible for performing garbage collection of unused containers.
type ContainerGC interface {
// DeleteAllUnusedContainers deletes all unused containers, even those that belong to pods that are terminated, but not deleted.
DeleteAllUnusedContainers() error
DeleteAllUnusedContainers(ctx context.Context) error
}
// KillPodFunc kills a pod.
@@ -131,7 +132,7 @@ type thresholdsObservedAt map[evictionapi.Threshold]time.Time
type nodeConditionsObservedAt map[v1.NodeConditionType]time.Time
// nodeReclaimFunc is a function that knows how to reclaim a resource from the node without impacting pods.
type nodeReclaimFunc func() error
type nodeReclaimFunc func(ctx context.Context) error
// nodeReclaimFuncs is an ordered list of nodeReclaimFunc
type nodeReclaimFuncs []nodeReclaimFunc