diff --git a/README.md b/README.md index 2479a8310..6af68990b 100644 --- a/README.md +++ b/README.md @@ -259,6 +259,9 @@ never evicted because these pods won't be recreated. * Pods associated with DaemonSets are never evicted. * Pods with local storage are never evicted. * Best efforts pods are evicted before Burstable and Guaranteed pods. +* All types of pods with annotation descheduler.alpha.kubernetes.io/evict are evicted. This +annotation is used to override checks which prevent eviction and user can select which pod is evicted. +User should know how and if the pod will be recreated. ### Pod disruption Budget (PDB) Pods subject to Pod Disruption Budget (PDB) are not evicted if descheduling violates its pod diff --git a/pkg/descheduler/pod/pods.go b/pkg/descheduler/pod/pods.go index 26b85f400..cf653d460 100644 --- a/pkg/descheduler/pod/pods.go +++ b/pkg/descheduler/pod/pods.go @@ -17,7 +17,7 @@ limitations under the License. package pod import ( - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" clientset "k8s.io/client-go/kubernetes" @@ -26,6 +26,10 @@ import ( "k8s.io/kubernetes/pkg/kubelet/types" ) +const ( + evictPodAnnotationKey = "descheduler.alpha.kubernetes.io/evict" +) + // checkLatencySensitiveResourcesForAContainer checks if there are any latency sensitive resources like GPUs. func checkLatencySensitiveResourcesForAContainer(rl v1.ResourceList) bool { if rl == nil { @@ -54,7 +58,7 @@ func IsLatencySensitivePod(pod *v1.Pod) bool { // IsEvictable checks if a pod is evictable or not. func IsEvictable(pod *v1.Pod, evictLocalStoragePods bool) bool { ownerRefList := OwnerRef(pod) - if IsMirrorPod(pod) || (!evictLocalStoragePods && IsPodWithLocalStorage(pod)) || len(ownerRefList) == 0 || IsDaemonsetPod(ownerRefList) || IsCriticalPod(pod) { + if !HaveEvictAnnotation(pod) && (IsMirrorPod(pod) || (!evictLocalStoragePods && IsPodWithLocalStorage(pod)) || len(ownerRefList) == 0 || IsDaemonsetPod(ownerRefList) || IsCriticalPod(pod)) { return false } return true @@ -127,6 +131,12 @@ func IsMirrorPod(pod *v1.Pod) bool { return found } +// HaveEvictAnnotation checks if the pod have evict annotation +func HaveEvictAnnotation(pod *v1.Pod) bool { + _, found := pod.ObjectMeta.Annotations[evictPodAnnotationKey] + return found +} + func IsPodWithLocalStorage(pod *v1.Pod) bool { for _, volume := range pod.Spec.Volumes { if volume.HostPath != nil || volume.EmptyDir != nil {