From d341a5b9d31c6d2a61d1cbcf68b9736054534197 Mon Sep 17 00:00:00 2001 From: Fabio Kung Date: Wed, 22 Apr 2020 12:02:40 -0700 Subject: [PATCH] kube-scheduler: compatibility with ServerSideApply avoid moving Pods that have been assumed back to the scheduling queue in case they have annotations modified with ServerSideApply, which causes Pod.ObjectMeta.ManagedFields to be modified automatically --- pkg/scheduler/eventhandlers.go | 3 ++ pkg/scheduler/eventhandlers_test.go | 79 +++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/pkg/scheduler/eventhandlers.go b/pkg/scheduler/eventhandlers.go index f6d8bb1c96a..0b4f6d99011 100644 --- a/pkg/scheduler/eventhandlers.go +++ b/pkg/scheduler/eventhandlers.go @@ -335,6 +335,9 @@ func (sched *Scheduler) skipPodUpdate(pod *v1.Pod) bool { // Annotations must be excluded for the reasons described in // https://github.com/kubernetes/kubernetes/issues/52914. p.Annotations = nil + // Same as above, when annotations are modified with ServerSideApply, + // ManagedFields may also change and must be excluded + p.ManagedFields = nil return p } assumedPodCopy, podCopy := f(assumedPod), f(pod) diff --git a/pkg/scheduler/eventhandlers_test.go b/pkg/scheduler/eventhandlers_test.go index 1d267ba8ffc..406f7d7089b 100644 --- a/pkg/scheduler/eventhandlers_test.go +++ b/pkg/scheduler/eventhandlers_test.go @@ -80,6 +80,85 @@ func TestSkipPodUpdate(t *testing.T) { }, expected: true, }, + { + name: "with ServerSideApply changes on Annotations", + pod: &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod-0", + Annotations: map[string]string{"a": "b"}, + ResourceVersion: "0", + ManagedFields: []metav1.ManagedFieldsEntry{ + { + Manager: "some-actor", + Operation: metav1.ManagedFieldsOperationApply, + APIVersion: "v1", + FieldsType: "FieldsV1", + FieldsV1: &metav1.FieldsV1{ + Raw: []byte(` + "f:metadata": { + "f:annotations": { + "f:a: {} + } + } + `), + }, + }, + }, + }, + Spec: v1.PodSpec{ + NodeName: "node-0", + }, + }, + isAssumedPodFunc: func(*v1.Pod) bool { + return true + }, + getPodFunc: func(*v1.Pod) *v1.Pod { + return &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod-0", + Annotations: map[string]string{"a": "c", "d": "e"}, + ResourceVersion: "1", + ManagedFields: []metav1.ManagedFieldsEntry{ + { + Manager: "some-actor", + Operation: metav1.ManagedFieldsOperationApply, + APIVersion: "v1", + FieldsType: "FieldsV1", + FieldsV1: &metav1.FieldsV1{ + Raw: []byte(` + "f:metadata": { + "f:annotations": { + "f:a: {} + "f:d: {} + } + } + `), + }, + }, + { + Manager: "some-actor", + Operation: metav1.ManagedFieldsOperationApply, + APIVersion: "v1", + FieldsType: "FieldsV1", + FieldsV1: &metav1.FieldsV1{ + Raw: []byte(` + "f:metadata": { + "f:annotations": { + "f:a: {} + } + } + `), + }, + }, + }, + }, + Spec: v1.PodSpec{ + NodeName: "node-1", + }, + } + }, + expected: true, + }, { name: "with changes on Labels", pod: &v1.Pod{