Skip to content

Commit da455d5

Browse files
authored
Merge pull request kubernetes#3682 from RainbowMango/pr_delete_nodes_from_cluster
[CA]delete nodes from cluster after scale down
2 parents 91c5796 + cc49d1a commit da455d5

File tree

2 files changed

+61
-6
lines changed

2 files changed

+61
-6
lines changed

cluster-autoscaler/cloudprovider/huaweicloud/examples/cluster-autoscaler-svcaccount.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ rules:
1919
verbs: ["get", "update"]
2020
- apiGroups: [""]
2121
resources: ["nodes"]
22-
verbs: ["watch", "list", "get", "update"]
22+
verbs: ["watch", "list", "get", "update", "delete"]
2323
- apiGroups: [""]
2424
resources:
2525
- "pods"

cluster-autoscaler/cloudprovider/huaweicloud/huaweicloud_auto_scaling_group.go

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,16 @@ limitations under the License.
1717
package huaweicloud
1818

1919
import (
20+
"context"
2021
"fmt"
2122

2223
apiv1 "k8s.io/api/core/v1"
24+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25+
"k8s.io/apimachinery/pkg/util/sets"
2326
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider"
2427
huaweicloudsdkasmodel "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huaweicloud-sdk-go-v3/services/as/v1/model"
28+
"k8s.io/client-go/kubernetes"
29+
"k8s.io/client-go/tools/clientcmd"
2530
"k8s.io/klog/v2"
2631
schedulerframework "k8s.io/kubernetes/pkg/scheduler/framework/v1alpha1"
2732
)
@@ -98,13 +103,26 @@ func (asg *AutoScalingGroup) DeleteNodes(nodes []*apiv1.Node) error {
98103
return err
99104
}
100105

101-
instanceIds := make([]string, 0, len(instances))
106+
instanceSet := sets.NewString()
102107
for _, instance := range instances {
103-
for _, n := range nodes {
104-
if n.Spec.ProviderID == instance.Id {
105-
instanceIds = append(instanceIds, instance.Id)
106-
}
108+
instanceSet.Insert(instance.Id)
109+
}
110+
111+
instanceIds := make([]string, 0, len(instances))
112+
nodeNames := make([]string, 0, len(instances))
113+
for _, node := range nodes {
114+
providerID := node.Spec.ProviderID
115+
116+
// If one of the nodes not belongs to this auto scaling group, means there is something wrong happened,
117+
// so, we should reject the whole deleting request.
118+
if !instanceSet.Has(providerID) {
119+
klog.Errorf("delete node not belongs this node group is not allowed. group: %s, node: %s", asg.groupID, providerID)
120+
return fmt.Errorf("node does not belong to this node group")
107121
}
122+
123+
klog.V(1).Infof("going to remove node from scaling group. group: %s, node: %s", asg.groupID, providerID)
124+
instanceIds = append(instanceIds, providerID)
125+
nodeNames = append(nodeNames, node.Name)
108126
}
109127

110128
err = asg.cloudServiceManager.DeleteScalingInstances(asg.groupID, instanceIds)
@@ -113,6 +131,12 @@ func (asg *AutoScalingGroup) DeleteNodes(nodes []*apiv1.Node) error {
113131
return err
114132
}
115133

134+
err = asg.deleteNodesFromCluster(nodeNames)
135+
if err != nil {
136+
klog.Warningf("failed to delete nodes from cluster. error: %v", err)
137+
return err
138+
}
139+
116140
return nil
117141
}
118142

@@ -202,3 +226,34 @@ func (asg *AutoScalingGroup) Autoprovisioned() bool {
202226
func (asg *AutoScalingGroup) String() string {
203227
return fmt.Sprintf("group: %s min=%d max=%d", asg.groupID, asg.minInstanceNumber, asg.maxInstanceNumber)
204228
}
229+
230+
func (asg *AutoScalingGroup) deleteNodesFromCluster(nodeNames []string) error {
231+
restConfig, err := clientcmd.BuildConfigFromFlags("", "")
232+
if err != nil {
233+
klog.Warningf("Failed to delete nodes from cluster due to can not get config. error: %v", err)
234+
return err
235+
}
236+
237+
kubeClient, err := kubernetes.NewForConfig(restConfig)
238+
if err != nil {
239+
klog.Warningf("Failed to delete nodes from cluster due to can not get kube-client. error: %v", err)
240+
return err
241+
}
242+
243+
var failedNodes []string
244+
for _, nodeName := range nodeNames {
245+
err := kubeClient.CoreV1().Nodes().Delete(context.TODO(), nodeName, metav1.DeleteOptions{})
246+
if err != nil {
247+
klog.Warningf("Failed to delete node from cluster. node: %s, error: %s", nodeName, err)
248+
failedNodes = append(failedNodes, nodeName)
249+
continue
250+
}
251+
klog.V(1).Infof("deleted one node from cluster. node name: %s", nodeName)
252+
}
253+
254+
if len(failedNodes) != 0 {
255+
return fmt.Errorf("failed to delete %d node(s) from cluster", len(failedNodes))
256+
}
257+
258+
return nil
259+
}

0 commit comments

Comments
 (0)