From 62799e33ee155a6585fe13fb1cdfe48e6d6634b7 Mon Sep 17 00:00:00 2001 From: Pavithra Ramesh Date: Tue, 26 Oct 2021 23:31:11 -0700 Subject: [PATCH] Remove nodes with Cluster Autoscaler taint from LB backends. --- .../cloud-provider/controllers/service/controller.go | 11 +++++++++++ .../controllers/service/controller_test.go | 3 +++ 2 files changed, 14 insertions(+) diff --git a/staging/src/k8s.io/cloud-provider/controllers/service/controller.go b/staging/src/k8s.io/cloud-provider/controllers/service/controller.go index f9984727703..bf9ea0fba9d 100644 --- a/staging/src/k8s.io/cloud-provider/controllers/service/controller.go +++ b/staging/src/k8s.io/cloud-provider/controllers/service/controller.go @@ -55,6 +55,9 @@ const ( // should be changed appropriately. minRetryDelay = 5 * time.Second maxRetryDelay = 300 * time.Second + // ToBeDeletedTaint is a taint used by the CLuster Autoscaler before marking a node for deletion. Defined in + // https://github.com/kubernetes/autoscaler/blob/e80ab518340f88f364fe3ef063f8303755125971/cluster-autoscaler/utils/deletetaint/delete.go#L36 + ToBeDeletedTaint = "ToBeDeletedByClusterAutoscaler" ) type cachedService struct { @@ -671,6 +674,14 @@ func (s *Controller) getNodeConditionPredicate() NodeConditionPredicate { return false } + // Remove nodes that are about to be deleted by the cluster autoscaler. + for _, taint := range node.Spec.Taints { + if taint.Key == ToBeDeletedTaint { + klog.V(4).Infof("Ignoring node %v with autoscaler taint %+v", node.Name, taint) + return false + } + } + // If we have no info, don't accept if len(node.Status.Conditions) == 0 { return false diff --git a/staging/src/k8s.io/cloud-provider/controllers/service/controller_test.go b/staging/src/k8s.io/cloud-provider/controllers/service/controller_test.go index 2dd7d49c41a..d869e2099d6 100644 --- a/staging/src/k8s.io/cloud-provider/controllers/service/controller_test.go +++ b/staging/src/k8s.io/cloud-provider/controllers/service/controller_test.go @@ -1580,6 +1580,9 @@ func Test_getNodeConditionPredicate(t *testing.T) { {want: true, input: &v1.Node{Status: validNodeStatus, ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{}}}}, {want: false, input: &v1.Node{Status: validNodeStatus, ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{v1.LabelNodeExcludeBalancers: ""}}}}, + + {want: false, input: &v1.Node{Status: v1.NodeStatus{Conditions: []v1.NodeCondition{{Type: v1.NodeReady, Status: v1.ConditionTrue}}}, + Spec: v1.NodeSpec{Taints: []v1.Taint{{Key: ToBeDeletedTaint, Value: fmt.Sprint(time.Now().Unix()), Effect: v1.TaintEffectNoSchedule}}}}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {