diff --git a/pkg/descheduler/pod/pods.go b/pkg/descheduler/pod/pods.go index 7268df79d..813804e38 100644 --- a/pkg/descheduler/pod/pods.go +++ b/pkg/descheduler/pod/pods.go @@ -27,13 +27,38 @@ import ( "k8s.io/kubernetes/pkg/kubelet/types" ) +// checkLatencySensitiveResourcesForAContainer checks if there are any latency sensitive resources like GPUs. +func checkLatencySensitiveResourcesForAContainer(rl v1.ResourceList) bool { + if rl == nil { + return false + } + for rName := range rl { + if rName == v1.ResourceNvidiaGPU { + return true + } + // TODO: Add support for other high value resources like hugepages etc. once kube is rebased to 1.8. + } + return false +} + +// IsLatencySensitivePod checks if a pod consumes high value devices like GPUs, hugepages or when cpu pinning enabled. +func IsLatencySensitivePod(pod *v1.Pod) bool { + for _, container := range pod.Spec.Containers { + resourceList := container.Resources.Requests + if checkLatencySensitiveResourcesForAContainer(resourceList) { + return true + } + } + return false +} + // IsEvictable checks if a pod is evictable or not. func IsEvictable(pod *v1.Pod) bool { sr, err := CreatorRef(pod) if err != nil { sr = nil } - if IsMirrorPod(pod) || IsPodWithLocalStorage(pod) || sr == nil || IsDaemonsetPod(sr) || IsCriticalPod(pod) { + if IsMirrorPod(pod) || IsPodWithLocalStorage(pod) || sr == nil || IsDaemonsetPod(sr) || IsCriticalPod(pod) || IsLatencySensitivePod(pod) { return false } return true diff --git a/pkg/descheduler/pod/pods_test.go b/pkg/descheduler/pod/pods_test.go index 336566aca..8f678b80b 100644 --- a/pkg/descheduler/pod/pods_test.go +++ b/pkg/descheduler/pod/pods_test.go @@ -33,6 +33,9 @@ func TestPodTypes(t *testing.T) { p3 := test.BuildTestPod("p3", 400, 0, n1.Name) p4 := test.BuildTestPod("p4", 400, 0, n1.Name) p5 := test.BuildTestPod("p5", 400, 0, n1.Name) + p6 := test.BuildTestPod("p6", 400, 0, n1.Name) + p6.Spec.Containers[0].Resources.Requests[v1.ResourceNvidiaGPU] = *resource.NewMilliQuantity(3, resource.DecimalSI) + p6.Annotations = test.GetNormalPodAnnotation() p1.Annotations = test.GetReplicaSetAnnotation() // The following 4 pods won't get evicted. @@ -72,5 +75,8 @@ func TestPodTypes(t *testing.T) { if IsDaemonsetPod(sr) || IsPodWithLocalStorage(p1) || IsCriticalPod(p1) || IsMirrorPod(p1) { t.Errorf("Expected p1 to be a normal pod.") } + if !IsLatencySensitivePod(p6) { + t.Errorf("Expected p6 to be latency sensitive pod") + } } diff --git a/test/test_utils.go b/test/test_utils.go index 68bee88bb..7ce8bdead 100644 --- a/test/test_utils.go +++ b/test/test_utils.go @@ -24,9 +24,7 @@ import ( "k8s.io/kubernetes/pkg/api/v1" ) -// TODO:@ravisantoshgudimetla. As of now building some test pods here. This needs to -// move to utils after refactor. -// buildTestPod creates a test pod with given parameters. +// BuildTestPod creates a test pod with given parameters. func BuildTestPod(name string, cpu int64, memory int64, nodeName string) *v1.Pod { pod := &v1.Pod{ ObjectMeta: metav1.ObjectMeta{