1
0
mirror of https://github.com/kubernetes-sigs/descheduler.git synced 2026-01-28 06:29:29 +01:00

Owner ref switch

Signed-off-by: ravisantoshgudimetla <ravisantoshgudimetla@gmail.com>
This commit is contained in:
ravisantoshgudimetla
2018-01-04 23:56:23 +05:30
parent fd961557d0
commit bf29a6073f
7 changed files with 57 additions and 62 deletions

View File

@@ -19,7 +19,6 @@ package pod
import ( import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/api/v1/helper/qos" "k8s.io/kubernetes/pkg/api/v1/helper/qos"
@@ -54,11 +53,8 @@ func IsLatencySensitivePod(pod *v1.Pod) bool {
// IsEvictable checks if a pod is evictable or not. // IsEvictable checks if a pod is evictable or not.
func IsEvictable(pod *v1.Pod) bool { func IsEvictable(pod *v1.Pod) bool {
sr, err := CreatorRef(pod) ownerRefList := OwnerRef(pod)
if err != nil { if IsMirrorPod(pod) || IsPodWithLocalStorage(pod) || len(ownerRefList) == 0 || IsDaemonsetPod(ownerRefList) || IsCriticalPod(pod) {
sr = nil
}
if IsMirrorPod(pod) || IsPodWithLocalStorage(pod) || sr == nil || IsDaemonsetPod(sr) || IsCriticalPod(pod) || IsLatencySensitivePod(pod) {
return false return false
} }
return true return true
@@ -116,9 +112,11 @@ func IsGuaranteedPod(pod *v1.Pod) bool {
return qos.GetPodQOS(pod) == v1.PodQOSGuaranteed return qos.GetPodQOS(pod) == v1.PodQOSGuaranteed
} }
func IsDaemonsetPod(sr *v1.SerializedReference) bool { func IsDaemonsetPod(ownerRefList []metav1.OwnerReference) bool {
if sr != nil { for _, ownerRef := range ownerRefList {
return sr.Reference.Kind == "DaemonSet" if ownerRef.Kind == "DaemonSet" {
return true
}
} }
return false return false
} }
@@ -139,15 +137,7 @@ func IsPodWithLocalStorage(pod *v1.Pod) bool {
return false return false
} }
// CreatorRef returns the kind of the creator reference of the pod. // OwnerRef returns the ownerRefList for the pod.
func CreatorRef(pod *v1.Pod) (*v1.SerializedReference, error) { func OwnerRef(pod *v1.Pod) []metav1.OwnerReference {
creatorRef, found := pod.ObjectMeta.Annotations[v1.CreatedByAnnotation] return pod.ObjectMeta.GetOwnerReferences()
if !found {
return nil, nil
}
var sr v1.SerializedReference
if err := runtime.DecodeInto(api.Codecs.UniversalDecoder(), []byte(creatorRef), &sr); err != nil {
return nil, err
}
return &sr, nil
} }

View File

@@ -35,14 +35,16 @@ func TestPodTypes(t *testing.T) {
p5 := test.BuildTestPod("p5", 400, 0, n1.Name) p5 := test.BuildTestPod("p5", 400, 0, n1.Name)
p6 := test.BuildTestPod("p6", 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.Spec.Containers[0].Resources.Requests[v1.ResourceNvidiaGPU] = *resource.NewMilliQuantity(3, resource.DecimalSI)
p6.Annotations = test.GetNormalPodAnnotation()
p1.Annotations = test.GetReplicaSetAnnotation() p6.ObjectMeta.OwnerReferences = test.GetNormalPodOwnerRefList()
p1.ObjectMeta.OwnerReferences = test.GetReplicaSetOwnerRefList()
// The following 4 pods won't get evicted. // The following 4 pods won't get evicted.
// A daemonset. // A daemonset.
p2.Annotations = test.GetDaemonSetAnnotation() //p2.Annotations = test.GetDaemonSetAnnotation()
p2.ObjectMeta.OwnerReferences = test.GetDaemonSetOwnerRefList()
// A pod with local storage. // A pod with local storage.
p3.Annotations = test.GetNormalPodAnnotation() p3.ObjectMeta.OwnerReferences = test.GetNormalPodOwnerRefList()
p3.Spec.Volumes = []v1.Volume{ p3.Spec.Volumes = []v1.Volume{
{ {
Name: "sample", Name: "sample",
@@ -67,12 +69,12 @@ func TestPodTypes(t *testing.T) {
if !IsPodWithLocalStorage(p3) { if !IsPodWithLocalStorage(p3) {
t.Errorf("Expected p3 to be a pod with local storage.") t.Errorf("Expected p3 to be a pod with local storage.")
} }
sr, _ := CreatorRef(p2) ownerRefList := OwnerRef(p2)
if !IsDaemonsetPod(sr) { if !IsDaemonsetPod(ownerRefList) {
t.Errorf("Expected p2 to be a daemonset pod.") t.Errorf("Expected p2 to be a daemonset pod.")
} }
sr, _ = CreatorRef(p1) ownerRefList = OwnerRef(p1)
if IsDaemonsetPod(sr) || IsPodWithLocalStorage(p1) || IsCriticalPod(p1) || IsMirrorPod(p1) { if IsDaemonsetPod(ownerRefList) || IsPodWithLocalStorage(p1) || IsCriticalPod(p1) || IsMirrorPod(p1) {
t.Errorf("Expected p1 to be a normal pod.") t.Errorf("Expected p1 to be a normal pod.")
} }
if !IsLatencySensitivePod(p6) { if !IsLatencySensitivePod(p6) {

View File

@@ -83,9 +83,12 @@ func FindDuplicatePods(pods []*v1.Pod) DuplicatePodsMap {
for _, pod := range pods { for _, pod := range pods {
// Ignoring the error here as in the ListDuplicatePodsOnNode function we call ListEvictablePodsOnNode // Ignoring the error here as in the ListDuplicatePodsOnNode function we call ListEvictablePodsOnNode
// which checks for error. // which checks for error.
sr, _ := podutil.CreatorRef(pod) ownerRefList := podutil.OwnerRef(pod)
s := strings.Join([]string{sr.Reference.Kind, sr.Reference.Namespace, sr.Reference.Name}, "/") for _, ownerRef := range ownerRefList {
dpm[s] = append(dpm[s], pod) // ownerRef doesn't need namespace since the assumption is owner needs to be in the same namespace.
s := strings.Join([]string{ownerRef.Kind, ownerRef.Name}, "/")
dpm[s] = append(dpm[s], pod)
}
} }
return dpm return dpm
} }

View File

@@ -39,15 +39,15 @@ func TestFindDuplicatePods(t *testing.T) {
p7 := test.BuildTestPod("p7", 100, 0, node.Name) p7 := test.BuildTestPod("p7", 100, 0, node.Name)
// All the following pods expect for one will be evicted. // All the following pods expect for one will be evicted.
p1.Annotations = test.GetReplicaSetAnnotation() p1.ObjectMeta.OwnerReferences = test.GetReplicaSetOwnerRefList()
p2.Annotations = test.GetReplicaSetAnnotation() p2.ObjectMeta.OwnerReferences = test.GetReplicaSetOwnerRefList()
p3.Annotations = test.GetReplicaSetAnnotation() p3.ObjectMeta.OwnerReferences = test.GetReplicaSetOwnerRefList()
// The following 4 pods won't get evicted. // The following 4 pods won't get evicted.
// A daemonset. // A daemonset.
p4.Annotations = test.GetDaemonSetAnnotation() p4.ObjectMeta.OwnerReferences = test.GetDaemonSetOwnerRefList()
// A pod with local storage. // A pod with local storage.
p5.Annotations = test.GetNormalPodAnnotation() p5.ObjectMeta.OwnerReferences = test.GetNormalPodOwnerRefList()
p5.Spec.Volumes = []v1.Volume{ p5.Spec.Volumes = []v1.Volume{
{ {
Name: "sample", Name: "sample",

View File

@@ -55,16 +55,16 @@ func TestLowNodeUtilization(t *testing.T) {
p7 := test.BuildTestPod("p7", 400, 0, n1.Name) p7 := test.BuildTestPod("p7", 400, 0, n1.Name)
p8 := test.BuildTestPod("p8", 400, 0, n1.Name) p8 := test.BuildTestPod("p8", 400, 0, n1.Name)
p1.Annotations = test.GetReplicaSetAnnotation() p1.ObjectMeta.OwnerReferences = test.GetReplicaSetOwnerRefList()
p2.Annotations = test.GetReplicaSetAnnotation() p2.ObjectMeta.OwnerReferences = test.GetReplicaSetOwnerRefList()
p3.Annotations = test.GetReplicaSetAnnotation() p3.ObjectMeta.OwnerReferences = test.GetReplicaSetOwnerRefList()
p4.Annotations = test.GetReplicaSetAnnotation() p4.ObjectMeta.OwnerReferences = test.GetReplicaSetOwnerRefList()
p5.Annotations = test.GetReplicaSetAnnotation() p5.ObjectMeta.OwnerReferences = test.GetReplicaSetOwnerRefList()
// The following 4 pods won't get evicted. // The following 4 pods won't get evicted.
// A daemonset. // A daemonset.
p6.Annotations = test.GetDaemonSetAnnotation() p6.ObjectMeta.OwnerReferences = test.GetDaemonSetOwnerRefList()
// A pod with local storage. // A pod with local storage.
p7.Annotations = test.GetNormalPodAnnotation() p7.ObjectMeta.OwnerReferences = test.GetNormalPodOwnerRefList()
p7.Spec.Volumes = []v1.Volume{ p7.Spec.Volumes = []v1.Volume{
{ {
Name: "sample", Name: "sample",
@@ -81,7 +81,7 @@ func TestLowNodeUtilization(t *testing.T) {
p8.Namespace = "kube-system" p8.Namespace = "kube-system"
p8.Annotations = test.GetCriticalPodAnnotation() p8.Annotations = test.GetCriticalPodAnnotation()
p9 := test.BuildTestPod("p9", 400, 0, n1.Name) p9 := test.BuildTestPod("p9", 400, 0, n1.Name)
p9.Annotations = test.GetReplicaSetAnnotation() p9.ObjectMeta.OwnerReferences = test.GetReplicaSetOwnerRefList()
fakeClient := &fake.Clientset{} fakeClient := &fake.Clientset{}
fakeClient.Fake.AddReactor("list", "pods", func(action core.Action) (bool, runtime.Object, error) { fakeClient.Fake.AddReactor("list", "pods", func(action core.Action) (bool, runtime.Object, error) {
list := action.(core.ListAction) list := action.(core.ListAction)

View File

@@ -33,9 +33,9 @@ func TestPodAntiAffinity(t *testing.T) {
p2 := test.BuildTestPod("p2", 100, 0, node.Name) p2 := test.BuildTestPod("p2", 100, 0, node.Name)
p3 := test.BuildTestPod("p3", 100, 0, node.Name) p3 := test.BuildTestPod("p3", 100, 0, node.Name)
p3.Labels = map[string]string{"foo": "bar"} p3.Labels = map[string]string{"foo": "bar"}
p1.Annotations = test.GetNormalPodAnnotation() p1.ObjectMeta.OwnerReferences = test.GetNormalPodOwnerRefList()
p2.Annotations = test.GetNormalPodAnnotation() p2.ObjectMeta.OwnerReferences = test.GetNormalPodOwnerRefList()
p3.Annotations = test.GetNormalPodAnnotation() p3.ObjectMeta.OwnerReferences = test.GetNormalPodOwnerRefList()
p1.Spec.Affinity = &v1.Affinity{ p1.Spec.Affinity = &v1.Affinity{
PodAntiAffinity: &v1.PodAntiAffinity{ PodAntiAffinity: &v1.PodAntiAffinity{
RequiredDuringSchedulingIgnoredDuringExecution: []v1.PodAffinityTerm{ RequiredDuringSchedulingIgnoredDuringExecution: []v1.PodAffinityTerm{

View File

@@ -62,25 +62,25 @@ func GetMirrorPodAnnotation() map[string]string {
} }
} }
// GetNormalPodAnnotation returns the annotation needed for a pod. // GetNormalPodOwnerRefList returns the ownerRef needed for a pod.
func GetNormalPodAnnotation() map[string]string { func GetNormalPodOwnerRefList() []metav1.OwnerReference {
return map[string]string{ ownerRefList := make([]metav1.OwnerReference, 0)
"kubernetes.io/created-by": "{\"kind\":\"SerializedReference\",\"apiVersion\":\"v1\",\"reference\":{\"kind\":\"Pod\"}}", ownerRefList = append(ownerRefList, metav1.OwnerReference{Kind: "Pod", APIVersion: "v1"})
} return ownerRefList
} }
// GetReplicaSetAnnotation returns the annotation needed for replicaset pod. // GetReplicaSetOwnerRefList returns the ownerRef needed for replicaset pod.
func GetReplicaSetAnnotation() map[string]string { func GetReplicaSetOwnerRefList() []metav1.OwnerReference {
return map[string]string{ ownerRefList := make([]metav1.OwnerReference, 0)
"kubernetes.io/created-by": "{\"kind\":\"SerializedReference\",\"apiVersion\":\"v1\",\"reference\":{\"kind\":\"ReplicaSet\"}}", ownerRefList = append(ownerRefList, metav1.OwnerReference{Kind: "ReplicaSet", APIVersion: "v1"})
} return ownerRefList
} }
// GetDaemonSetAnnotation returns the annotation needed for daemonset pod. // GetDaemonSetOwnerRefList returns the ownerRef needed for daemonset pod.
func GetDaemonSetAnnotation() map[string]string { func GetDaemonSetOwnerRefList() []metav1.OwnerReference {
return map[string]string{ ownerRefList := make([]metav1.OwnerReference, 0)
"kubernetes.io/created-by": "{\"kind\":\"SerializedReference\",\"apiVersion\":\"v1\",\"reference\":{\"kind\":\"DaemonSet\"}}", ownerRefList = append(ownerRefList, metav1.OwnerReference{Kind: "DaemonSet", APIVersion: "v1"})
} return ownerRefList
} }
// GetCriticalPodAnnotation returns the annotation needed for critical pod. // GetCriticalPodAnnotation returns the annotation needed for critical pod.