Skip to content

Commit e948a67

Browse files
authored
Merge pull request kubernetes#84415 from langyenan/fix-evict-admit
reject pods when under disk pressure
2 parents 46e286e + 22d8e05 commit e948a67

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

pkg/kubelet/eviction/eviction_manager.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,10 @@ func (m *managerImpl) Admit(attrs *lifecycle.PodAdmitAttributes) lifecycle.PodAd
137137
if kubelettypes.IsCriticalPod(attrs.Pod) {
138138
return lifecycle.PodAdmitResult{Admit: true}
139139
}
140-
// the node has memory pressure, admit if not best-effort
141-
if hasNodeCondition(m.nodeConditions, v1.NodeMemoryPressure) {
140+
141+
// Conditions other than memory pressure reject all pods
142+
nodeOnlyHasMemoryPressureCondition := hasNodeCondition(m.nodeConditions, v1.NodeMemoryPressure) && len(m.nodeConditions) == 1
143+
if nodeOnlyHasMemoryPressureCondition {
142144
notBestEffort := v1.PodQOSBestEffort != v1qos.GetPodQOS(attrs.Pod)
143145
if notBestEffort {
144146
return lifecycle.PodAdmitResult{Admit: true}

pkg/kubelet/eviction/eviction_manager_test.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,52 @@ func TestMemoryPressure(t *testing.T) {
391391
}
392392
}
393393

394+
func makeContainersByQOS(class v1.PodQOSClass) []v1.Container {
395+
resource := newResourceList("100m", "1Gi", "")
396+
switch class {
397+
case v1.PodQOSGuaranteed:
398+
return []v1.Container{newContainer("guaranteed-container", resource, resource)}
399+
case v1.PodQOSBurstable:
400+
return []v1.Container{newContainer("burtable-container", resource, nil)}
401+
case v1.PodQOSBestEffort:
402+
fallthrough
403+
default:
404+
return []v1.Container{newContainer("best-effort-container", nil, nil)}
405+
}
406+
}
407+
408+
func TestAdmitUnderNodeConditions(t *testing.T) {
409+
manager := &managerImpl{}
410+
pods := []*v1.Pod{
411+
newPod("guaranteed-pod", scheduling.DefaultPriorityWhenNoDefaultClassExists, makeContainersByQOS(v1.PodQOSGuaranteed), nil),
412+
newPod("burstable-pod", scheduling.DefaultPriorityWhenNoDefaultClassExists, makeContainersByQOS(v1.PodQOSBurstable), nil),
413+
newPod("best-effort-pod", scheduling.DefaultPriorityWhenNoDefaultClassExists, makeContainersByQOS(v1.PodQOSBestEffort), nil),
414+
}
415+
416+
expected := []bool{true, true, true}
417+
for i, pod := range pods {
418+
if result := manager.Admit(&lifecycle.PodAdmitAttributes{Pod: pod}); expected[i] != result.Admit {
419+
t.Errorf("Admit pod: %v, expected: %v, actual: %v", pod, expected[i], result.Admit)
420+
}
421+
}
422+
423+
manager.nodeConditions = []v1.NodeConditionType{v1.NodeMemoryPressure}
424+
expected = []bool{true, true, false}
425+
for i, pod := range pods {
426+
if result := manager.Admit(&lifecycle.PodAdmitAttributes{Pod: pod}); expected[i] != result.Admit {
427+
t.Errorf("Admit pod: %v, expected: %v, actual: %v", pod, expected[i], result.Admit)
428+
}
429+
}
430+
431+
manager.nodeConditions = []v1.NodeConditionType{v1.NodeMemoryPressure, v1.NodeDiskPressure}
432+
expected = []bool{false, false, false}
433+
for i, pod := range pods {
434+
if result := manager.Admit(&lifecycle.PodAdmitAttributes{Pod: pod}); expected[i] != result.Admit {
435+
t.Errorf("Admit pod: %v, expected: %v, actual: %v", pod, expected[i], result.Admit)
436+
}
437+
}
438+
}
439+
394440
// parseQuantity parses the specified value (if provided) otherwise returns 0 value
395441
func parseQuantity(value string) resource.Quantity {
396442
if len(value) == 0 {

0 commit comments

Comments
 (0)