diff --git a/cluster-autoscaler/config/autoscaling_options.go b/cluster-autoscaler/config/autoscaling_options.go index 585cdc1d636b..9aa9d7d23358 100644 --- a/cluster-autoscaler/config/autoscaling_options.go +++ b/cluster-autoscaler/config/autoscaling_options.go @@ -121,6 +121,8 @@ type AutoscalingOptions struct { GRPCExpanderCert string // GRPCExpanderURL is the url of the gRPC server when using the gRPC expander GRPCExpanderURL string + // IncludeSimilarNodegroupsInExpanderOptions is whether CA will include similar nodegroups in it's request to the gRPC expander + IncludeSimilarNodegroupsInExpanderOptions bool // IgnoreMirrorPodsUtilization is whether CA will ignore Mirror pods when calculating resource utilization for scaling down IgnoreMirrorPodsUtilization bool // MaxGracefulTerminationSec is maximum number of seconds scale down waits for pods to terminate before diff --git a/cluster-autoscaler/core/scaleup/orchestrator/orchestrator.go b/cluster-autoscaler/core/scaleup/orchestrator/orchestrator.go index a9d5ed1e9592..8e15ad079d94 100644 --- a/cluster-autoscaler/core/scaleup/orchestrator/orchestrator.go +++ b/cluster-autoscaler/core/scaleup/orchestrator/orchestrator.go @@ -174,6 +174,7 @@ func (o *ScaleUpOrchestrator) ScaleUp( } // Pick some expansion option. + // We have to be aware of the flag here? bestOption := o.autoscalingContext.ExpanderStrategy.BestOption(options, nodeInfos) if bestOption == nil || bestOption.NodeCount <= 0 { return &status.ScaleUpStatus{ diff --git a/cluster-autoscaler/expander/grpcplugin/grpc_client.go b/cluster-autoscaler/expander/grpcplugin/grpc_client.go index b31de9fa4020..3e58bb146adc 100644 --- a/cluster-autoscaler/expander/grpcplugin/grpc_client.go +++ b/cluster-autoscaler/expander/grpcplugin/grpc_client.go @@ -37,7 +37,8 @@ const ( ) type grpcclientstrategy struct { - grpcClient protos.ExpanderClient + grpcClient protos.ExpanderClient + includeSimilarNodegroups bool } // NewFilter returns an expansion filter that creates a gRPC client, and calls out to a gRPC server @@ -79,7 +80,7 @@ func (g *grpcclientstrategy) BestOptions(expansionOptions []expander.Option, nod } // Transform inputs to gRPC inputs - grpcOptionsSlice, nodeGroupIDOptionMap := populateOptionsForGRPC(expansionOptions) + grpcOptionsSlice, nodeGroupIDOptionMap := populateOptionsForGRPC(expansionOptions, false) grpcNodeMap := populateNodeInfoForGRPC(nodeInfo) // call gRPC server to get BestOption @@ -106,16 +107,29 @@ func (g *grpcclientstrategy) BestOptions(expansionOptions []expander.Option, nod } // populateOptionsForGRPC creates a map of nodegroup ID and options, as well as a slice of Options objects for the gRPC call -func populateOptionsForGRPC(expansionOptions []expander.Option) ([]*protos.Option, map[string]expander.Option) { +func populateOptionsForGRPC(expansionOptions []expander.Option, includeSimilarNodegroups bool) ([]*protos.Option, map[string]expander.Option) { grpcOptionsSlice := []*protos.Option{} nodeGroupIDOptionMap := make(map[string]expander.Option) for _, option := range expansionOptions { + similarNodegroupIds := []string{} nodeGroupIDOptionMap[option.NodeGroup.Id()] = option - grpcOptionsSlice = append(grpcOptionsSlice, newOptionMessage(option.NodeGroup.Id(), int32(option.NodeCount), option.Debug, option.Pods)) + if includeSimilarNodegroups { + similarNodegroupIds = getSimilarNodegroupIds(option) + } + + grpcOptionsSlice = append(grpcOptionsSlice, newOptionMessage(option.NodeGroup.Id(), int32(option.NodeCount), option.Debug, option.Pods, similarNodegroupIds)) } return grpcOptionsSlice, nodeGroupIDOptionMap } +func getSimilarNodegroupIds(option expander.Option) []string { + var similarNodegroupIds []string + for _, sng := range option.SimilarNodeGroups { + similarNodegroupIds = append(similarNodegroupIds, sng.Id()) + } + return similarNodegroupIds +} + // populateNodeInfoForGRPC looks at the corresponding v1.Node object per NodeInfo object, and populates the grpcNodeInfoMap with these to pass over grpc func populateNodeInfoForGRPC(nodeInfos map[string]*schedulerframework.NodeInfo) map[string]*v1.Node { grpcNodeInfoMap := make(map[string]*v1.Node) @@ -142,6 +156,6 @@ func transformAndSanitizeOptionsFromGRPC(bestOptionsResponseOptions []*protos.Op return options } -func newOptionMessage(nodeGroupId string, nodeCount int32, debug string, pods []*v1.Pod) *protos.Option { - return &protos.Option{NodeGroupId: nodeGroupId, NodeCount: nodeCount, Debug: debug, Pod: pods} +func newOptionMessage(nodeGroupId string, nodeCount int32, debug string, pods []*v1.Pod, similarNodegroupIds []string) *protos.Option { + return &protos.Option{NodeGroupId: nodeGroupId, NodeCount: nodeCount, Debug: debug, Pod: pods, SimilarNodegroupIds: similarNodegroupIds} } diff --git a/cluster-autoscaler/expander/grpcplugin/grpc_client_test.go b/cluster-autoscaler/expander/grpcplugin/grpc_client_test.go index 65b94a17d54b..33399345d33d 100644 --- a/cluster-autoscaler/expander/grpcplugin/grpc_client_test.go +++ b/cluster-autoscaler/expander/grpcplugin/grpc_client_test.go @@ -118,7 +118,7 @@ func TestPopulateOptionsForGrpc(t *testing.T) { }, } for _, tc := range testCases { - grpcOptionsSlice, nodeGroupIDOptionMap := populateOptionsForGRPC(tc.opts) + grpcOptionsSlice, nodeGroupIDOptionMap := populateOptionsForGRPC(tc.opts, false) assert.Equal(t, tc.expectedOpts, grpcOptionsSlice) assert.Equal(t, tc.expectedMap, nodeGroupIDOptionMap) } @@ -176,7 +176,7 @@ func TestBestOptionsValid(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mockClient := mocks.NewMockExpanderClient(ctrl) - g := &grpcclientstrategy{mockClient} + g := &grpcclientstrategy{grpcClient: mockClient} nodeInfos := makeFakeNodeInfos() grpcNodeInfoMap := make(map[string]*v1.Node) @@ -202,7 +202,7 @@ func TestBestOptionsErrors(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mockClient := mocks.NewMockExpanderClient(ctrl) - g := grpcclientstrategy{mockClient} + g := grpcclientstrategy{grpcClient: mockClient} badProtosOption := protos.Option{ NodeGroupId: "badID", @@ -220,7 +220,7 @@ func TestBestOptionsErrors(t *testing.T) { }{ { desc: "Bad gRPC client config", - client: grpcclientstrategy{nil}, + client: grpcclientstrategy{grpcClient: nil}, nodeInfo: makeFakeNodeInfos(), mockResponse: protos.BestOptionsResponse{}, errResponse: nil, diff --git a/cluster-autoscaler/expander/grpcplugin/protos/expander.pb.go b/cluster-autoscaler/expander/grpcplugin/protos/expander.pb.go index 3c071d2f37d7..185ecef8c040 100644 --- a/cluster-autoscaler/expander/grpcplugin/protos/expander.pb.go +++ b/cluster-autoscaler/expander/grpcplugin/protos/expander.pb.go @@ -1,32 +1,17 @@ -/* -Copyright 2021 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v5.26.1 +// source: expander.proto package protos import ( - context "context" - reflect "reflect" - sync "sync" - - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" v1 "k8s.io/api/core/v1" + reflect "reflect" + sync "sync" ) const ( @@ -49,7 +34,7 @@ type BestOptionsRequest struct { func (x *BestOptionsRequest) Reset() { *x = BestOptionsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_msgTypes[0] + mi := &file_expander_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -62,7 +47,7 @@ func (x *BestOptionsRequest) String() string { func (*BestOptionsRequest) ProtoMessage() {} func (x *BestOptionsRequest) ProtoReflect() protoreflect.Message { - mi := &file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_msgTypes[0] + mi := &file_expander_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -75,7 +60,7 @@ func (x *BestOptionsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BestOptionsRequest.ProtoReflect.Descriptor instead. func (*BestOptionsRequest) Descriptor() ([]byte, []int) { - return file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_rawDescGZIP(), []int{0} + return file_expander_proto_rawDescGZIP(), []int{0} } func (x *BestOptionsRequest) GetOptions() []*Option { @@ -103,7 +88,7 @@ type BestOptionsResponse struct { func (x *BestOptionsResponse) Reset() { *x = BestOptionsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_msgTypes[1] + mi := &file_expander_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -116,7 +101,7 @@ func (x *BestOptionsResponse) String() string { func (*BestOptionsResponse) ProtoMessage() {} func (x *BestOptionsResponse) ProtoReflect() protoreflect.Message { - mi := &file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_msgTypes[1] + mi := &file_expander_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -129,7 +114,7 @@ func (x *BestOptionsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use BestOptionsResponse.ProtoReflect.Descriptor instead. func (*BestOptionsResponse) Descriptor() ([]byte, []int) { - return file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_rawDescGZIP(), []int{1} + return file_expander_proto_rawDescGZIP(), []int{1} } func (x *BestOptionsResponse) GetOptions() []*Option { @@ -145,16 +130,17 @@ type Option struct { unknownFields protoimpl.UnknownFields // only need the ID of node to uniquely identify the nodeGroup, used in the nodeInfo map. - NodeGroupId string `protobuf:"bytes,1,opt,name=nodeGroupId,proto3" json:"nodeGroupId,omitempty"` - NodeCount int32 `protobuf:"varint,2,opt,name=nodeCount,proto3" json:"nodeCount,omitempty"` - Debug string `protobuf:"bytes,3,opt,name=debug,proto3" json:"debug,omitempty"` - Pod []*v1.Pod `protobuf:"bytes,4,rep,name=pod,proto3" json:"pod,omitempty"` + NodeGroupId string `protobuf:"bytes,1,opt,name=nodeGroupId,proto3" json:"nodeGroupId,omitempty"` + NodeCount int32 `protobuf:"varint,2,opt,name=nodeCount,proto3" json:"nodeCount,omitempty"` + Debug string `protobuf:"bytes,3,opt,name=debug,proto3" json:"debug,omitempty"` + Pod []*v1.Pod `protobuf:"bytes,4,rep,name=pod,proto3" json:"pod,omitempty"` + SimilarNodegroupIds []string `protobuf:"bytes,5,rep,name=similarNodegroupIds,proto3" json:"similarNodegroupIds,omitempty"` } func (x *Option) Reset() { *x = Option{} if protoimpl.UnsafeEnabled { - mi := &file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_msgTypes[2] + mi := &file_expander_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -167,7 +153,7 @@ func (x *Option) String() string { func (*Option) ProtoMessage() {} func (x *Option) ProtoReflect() protoreflect.Message { - mi := &file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_msgTypes[2] + mi := &file_expander_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -180,7 +166,7 @@ func (x *Option) ProtoReflect() protoreflect.Message { // Deprecated: Use Option.ProtoReflect.Descriptor instead. func (*Option) Descriptor() ([]byte, []int) { - return file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_rawDescGZIP(), []int{2} + return file_expander_proto_rawDescGZIP(), []int{2} } func (x *Option) GetNodeGroupId() string { @@ -211,69 +197,76 @@ func (x *Option) GetPod() []*v1.Pod { return nil } -var File_cluster_autoscaler_expander_grpcplugin_protos_expander_proto protoreflect.FileDescriptor - -var file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_rawDesc = []byte{ - 0x0a, 0x3c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2d, 0x61, 0x75, 0x74, 0x6f, 0x73, 0x63, - 0x61, 0x6c, 0x65, 0x72, 0x2f, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x2f, 0x67, 0x72, - 0x70, 0x63, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, - 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, - 0x67, 0x72, 0x70, 0x63, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x1a, 0x22, 0x6b, 0x38, 0x73, 0x2e, - 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x67, - 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xdf, - 0x01, 0x0a, 0x12, 0x42, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x70, 0x6c, 0x75, - 0x67, 0x69, 0x6e, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x45, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x4d, 0x61, 0x70, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x70, 0x6c, 0x75, 0x67, 0x69, - 0x6e, 0x2e, 0x42, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x4d, 0x61, 0x70, 0x1a, 0x54, 0x0a, 0x0c, 0x4e, 0x6f, - 0x64, 0x65, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6b, 0x38, - 0x73, 0x2e, 0x69, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x22, 0x43, 0x0a, 0x13, 0x42, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, +func (x *Option) GetSimilarNodegroupIds() []string { + if x != nil { + return x.SimilarNodegroupIds + } + return nil +} + +var File_expander_proto protoreflect.FileDescriptor + +var file_expander_proto_rawDesc = []byte{ + 0x0a, 0x0e, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x0a, 0x67, 0x72, 0x70, 0x63, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x1a, 0x22, 0x6b, 0x38, + 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x31, + 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0xdf, 0x01, 0x0a, 0x12, 0x42, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x6f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x89, 0x01, 0x0a, 0x06, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x20, 0x0a, 0x0b, 0x6e, 0x6f, 0x64, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x6f, 0x64, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x62, 0x75, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x64, 0x65, 0x62, 0x75, 0x67, 0x12, 0x29, 0x0a, 0x03, 0x70, 0x6f, 0x64, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6b, 0x38, 0x73, 0x2e, 0x69, 0x6f, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x52, 0x03, 0x70, 0x6f, - 0x64, 0x32, 0x5c, 0x0a, 0x08, 0x45, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x50, 0x0a, - 0x0b, 0x42, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x2e, 0x67, - 0x72, 0x70, 0x63, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x42, 0x65, 0x73, 0x74, 0x4f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, - 0x72, 0x70, 0x63, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x42, 0x65, 0x73, 0x74, 0x4f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, - 0x2f, 0x5a, 0x2d, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2d, 0x61, 0x75, 0x74, 0x6f, 0x73, - 0x63, 0x61, 0x6c, 0x65, 0x72, 0x2f, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x2f, 0x67, - 0x72, 0x70, 0x63, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x45, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x4d, 0x61, 0x70, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x2e, 0x42, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x61, 0x70, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x4d, 0x61, 0x70, 0x1a, 0x54, 0x0a, 0x0c, + 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2e, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, + 0x6b, 0x38, 0x73, 0x2e, 0x69, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x22, 0x43, 0x0a, 0x13, 0x42, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x07, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x72, 0x70, + 0x63, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xbb, 0x01, 0x0a, 0x06, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x6e, 0x6f, 0x64, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x6f, 0x64, 0x65, 0x47, 0x72, 0x6f, + 0x75, 0x70, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x62, 0x75, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x64, 0x65, 0x62, 0x75, 0x67, 0x12, 0x29, 0x0a, 0x03, 0x70, 0x6f, 0x64, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6b, 0x38, 0x73, 0x2e, 0x69, 0x6f, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x52, 0x03, + 0x70, 0x6f, 0x64, 0x12, 0x30, 0x0a, 0x13, 0x73, 0x69, 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x4e, 0x6f, + 0x64, 0x65, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x13, 0x73, 0x69, 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x4e, 0x6f, 0x64, 0x65, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x49, 0x64, 0x73, 0x32, 0x5c, 0x0a, 0x08, 0x45, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, + 0x72, 0x12, 0x50, 0x0a, 0x0b, 0x42, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x1e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x42, 0x65, + 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1f, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x42, 0x65, + 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x42, 0x2f, 0x5a, 0x2d, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2d, 0x61, + 0x75, 0x74, 0x6f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x2f, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, + 0x65, 0x72, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( - file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_rawDescOnce sync.Once - file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_rawDescData = file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_rawDesc + file_expander_proto_rawDescOnce sync.Once + file_expander_proto_rawDescData = file_expander_proto_rawDesc ) -func file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_rawDescGZIP() []byte { - file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_rawDescOnce.Do(func() { - file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_rawDescData = protoimpl.X.CompressGZIP(file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_rawDescData) +func file_expander_proto_rawDescGZIP() []byte { + file_expander_proto_rawDescOnce.Do(func() { + file_expander_proto_rawDescData = protoimpl.X.CompressGZIP(file_expander_proto_rawDescData) }) - return file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_rawDescData + return file_expander_proto_rawDescData } -var file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_goTypes = []interface{}{ +var file_expander_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_expander_proto_goTypes = []interface{}{ (*BestOptionsRequest)(nil), // 0: grpcplugin.BestOptionsRequest (*BestOptionsResponse)(nil), // 1: grpcplugin.BestOptionsResponse (*Option)(nil), // 2: grpcplugin.Option @@ -281,7 +274,7 @@ var file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_goTypes = (*v1.Pod)(nil), // 4: k8s.io.api.core.v1.Pod (*v1.Node)(nil), // 5: k8s.io.api.core.v1.Node } -var file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_depIdxs = []int32{ +var file_expander_proto_depIdxs = []int32{ 2, // 0: grpcplugin.BestOptionsRequest.options:type_name -> grpcplugin.Option 3, // 1: grpcplugin.BestOptionsRequest.nodeMap:type_name -> grpcplugin.BestOptionsRequest.NodeMapEntry 2, // 2: grpcplugin.BestOptionsResponse.options:type_name -> grpcplugin.Option @@ -296,13 +289,13 @@ var file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_depIdxs = 0, // [0:5] is the sub-list for field type_name } -func init() { file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_init() } -func file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_init() { - if File_cluster_autoscaler_expander_grpcplugin_protos_expander_proto != nil { +func init() { file_expander_proto_init() } +func file_expander_proto_init() { + if File_expander_proto != nil { return } if !protoimpl.UnsafeEnabled { - file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_expander_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BestOptionsRequest); i { case 0: return &v.state @@ -314,7 +307,7 @@ func file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_init() { return nil } } - file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_expander_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BestOptionsResponse); i { case 0: return &v.state @@ -326,7 +319,7 @@ func file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_init() { return nil } } - file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_expander_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Option); i { case 0: return &v.state @@ -343,98 +336,18 @@ func file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_rawDesc, + RawDescriptor: file_expander_proto_rawDesc, NumEnums: 0, NumMessages: 4, NumExtensions: 0, NumServices: 1, }, - GoTypes: file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_goTypes, - DependencyIndexes: file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_depIdxs, - MessageInfos: file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_msgTypes, + GoTypes: file_expander_proto_goTypes, + DependencyIndexes: file_expander_proto_depIdxs, + MessageInfos: file_expander_proto_msgTypes, }.Build() - File_cluster_autoscaler_expander_grpcplugin_protos_expander_proto = out.File - file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_rawDesc = nil - file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_goTypes = nil - file_cluster_autoscaler_expander_grpcplugin_protos_expander_proto_depIdxs = nil -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConnInterface - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion6 - -// ExpanderClient is the client API for Expander service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type ExpanderClient interface { - BestOptions(ctx context.Context, in *BestOptionsRequest, opts ...grpc.CallOption) (*BestOptionsResponse, error) -} - -type expanderClient struct { - cc grpc.ClientConnInterface -} - -func NewExpanderClient(cc grpc.ClientConnInterface) ExpanderClient { - return &expanderClient{cc} -} - -func (c *expanderClient) BestOptions(ctx context.Context, in *BestOptionsRequest, opts ...grpc.CallOption) (*BestOptionsResponse, error) { - out := new(BestOptionsResponse) - err := c.cc.Invoke(ctx, "/grpcplugin.Expander/BestOptions", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// ExpanderServer is the server API for Expander service. -type ExpanderServer interface { - BestOptions(context.Context, *BestOptionsRequest) (*BestOptionsResponse, error) -} - -// UnimplementedExpanderServer can be embedded to have forward compatible implementations. -type UnimplementedExpanderServer struct { -} - -func (*UnimplementedExpanderServer) BestOptions(context.Context, *BestOptionsRequest) (*BestOptionsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method BestOptions not implemented") -} - -func RegisterExpanderServer(s *grpc.Server, srv ExpanderServer) { - s.RegisterService(&_Expander_serviceDesc, srv) -} - -func _Expander_BestOptions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(BestOptionsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ExpanderServer).BestOptions(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/grpcplugin.Expander/BestOptions", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ExpanderServer).BestOptions(ctx, req.(*BestOptionsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -var _Expander_serviceDesc = grpc.ServiceDesc{ - ServiceName: "grpcplugin.Expander", - HandlerType: (*ExpanderServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "BestOptions", - Handler: _Expander_BestOptions_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "cluster-autoscaler/expander/grpcplugin/protos/expander.proto", + File_expander_proto = out.File + file_expander_proto_rawDesc = nil + file_expander_proto_goTypes = nil + file_expander_proto_depIdxs = nil } diff --git a/cluster-autoscaler/expander/grpcplugin/protos/expander.proto b/cluster-autoscaler/expander/grpcplugin/protos/expander.proto index 5a08e8ff301b..ef696516f986 100644 --- a/cluster-autoscaler/expander/grpcplugin/protos/expander.proto +++ b/cluster-autoscaler/expander/grpcplugin/protos/expander.proto @@ -27,4 +27,5 @@ message Option { int32 nodeCount = 2; string debug = 3; repeated k8s.io.api.core.v1.Pod pod = 4; + repeated string similarNodegroupIds = 5; } diff --git a/cluster-autoscaler/expander/grpcplugin/protos/expander_grpc.pb.go b/cluster-autoscaler/expander/grpcplugin/protos/expander_grpc.pb.go new file mode 100644 index 000000000000..c162b1d2c38f --- /dev/null +++ b/cluster-autoscaler/expander/grpcplugin/protos/expander_grpc.pb.go @@ -0,0 +1,105 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v5.26.1 +// source: expander.proto + +package protos + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// ExpanderClient is the client API for Expander service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ExpanderClient interface { + BestOptions(ctx context.Context, in *BestOptionsRequest, opts ...grpc.CallOption) (*BestOptionsResponse, error) +} + +type expanderClient struct { + cc grpc.ClientConnInterface +} + +func NewExpanderClient(cc grpc.ClientConnInterface) ExpanderClient { + return &expanderClient{cc} +} + +func (c *expanderClient) BestOptions(ctx context.Context, in *BestOptionsRequest, opts ...grpc.CallOption) (*BestOptionsResponse, error) { + out := new(BestOptionsResponse) + err := c.cc.Invoke(ctx, "/grpcplugin.Expander/BestOptions", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ExpanderServer is the server API for Expander service. +// All implementations must embed UnimplementedExpanderServer +// for forward compatibility +type ExpanderServer interface { + BestOptions(context.Context, *BestOptionsRequest) (*BestOptionsResponse, error) + mustEmbedUnimplementedExpanderServer() +} + +// UnimplementedExpanderServer must be embedded to have forward compatible implementations. +type UnimplementedExpanderServer struct { +} + +func (UnimplementedExpanderServer) BestOptions(context.Context, *BestOptionsRequest) (*BestOptionsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method BestOptions not implemented") +} +func (UnimplementedExpanderServer) mustEmbedUnimplementedExpanderServer() {} + +// UnsafeExpanderServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ExpanderServer will +// result in compilation errors. +type UnsafeExpanderServer interface { + mustEmbedUnimplementedExpanderServer() +} + +func RegisterExpanderServer(s grpc.ServiceRegistrar, srv ExpanderServer) { + s.RegisterService(&Expander_ServiceDesc, srv) +} + +func _Expander_BestOptions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BestOptionsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ExpanderServer).BestOptions(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpcplugin.Expander/BestOptions", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ExpanderServer).BestOptions(ctx, req.(*BestOptionsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Expander_ServiceDesc is the grpc.ServiceDesc for Expander service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Expander_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "grpcplugin.Expander", + HandlerType: (*ExpanderServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "BestOptions", + Handler: _Expander_BestOptions_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "expander.proto", +} diff --git a/cluster-autoscaler/main.go b/cluster-autoscaler/main.go index 285a6af58c97..3262753a380f 100644 --- a/cluster-autoscaler/main.go +++ b/cluster-autoscaler/main.go @@ -176,8 +176,9 @@ var ( expanderFlag = flag.String("expander", expander.RandomExpanderName, "Type of node group expander to be used in scale up. Available values: ["+strings.Join(expander.AvailableExpanders, ",")+"]. Specifying multiple values separated by commas will call the expanders in succession until there is only one option remaining. Ties still existing after this process are broken randomly.") - grpcExpanderCert = flag.String("grpc-expander-cert", "", "Path to cert used by gRPC server over TLS") - grpcExpanderURL = flag.String("grpc-expander-url", "", "URL to reach gRPC expander server.") + grpcExpanderCert = flag.String("grpc-expander-cert", "", "Path to cert used by gRPC server over TLS") + grpcExpanderURL = flag.String("grpc-expander-url", "", "URL to reach gRPC expander server.") + includeSimilarNodegroupsInExpanderOptions = flag.Bool("include-similar-nodegroups-in-expander-options", false, "if true, similar nodegroups will be included in the BestOptions request to the expander") ignoreDaemonSetsUtilization = flag.Bool("ignore-daemonsets-utilization", false, "Should CA ignore DaemonSet pods when calculating resource utilization for scaling down") @@ -300,60 +301,61 @@ func createAutoscalingOptions() config.AutoscalingOptions { IgnoreDaemonSetsUtilization: *ignoreDaemonSetsUtilization, MaxNodeProvisionTime: *maxNodeProvisionTime, }, - CloudConfig: *cloudConfig, - CloudProviderName: *cloudProviderFlag, - NodeGroupAutoDiscovery: *nodeGroupAutoDiscoveryFlag, - MaxTotalUnreadyPercentage: *maxTotalUnreadyPercentage, - OkTotalUnreadyCount: *okTotalUnreadyCount, - ScaleUpFromZero: *scaleUpFromZero, - ParallelScaleUp: *parallelScaleUp, - EstimatorName: *estimatorFlag, - ExpanderNames: *expanderFlag, - GRPCExpanderCert: *grpcExpanderCert, - GRPCExpanderURL: *grpcExpanderURL, - IgnoreMirrorPodsUtilization: *ignoreMirrorPodsUtilization, - MaxBulkSoftTaintCount: *maxBulkSoftTaintCount, - MaxBulkSoftTaintTime: *maxBulkSoftTaintTime, - MaxEmptyBulkDelete: *maxEmptyBulkDeleteFlag, - MaxGracefulTerminationSec: *maxGracefulTerminationFlag, - MaxPodEvictionTime: *maxPodEvictionTime, - MaxNodesTotal: *maxNodesTotal, - MaxCoresTotal: maxCoresTotal, - MinCoresTotal: minCoresTotal, - MaxMemoryTotal: maxMemoryTotal, - MinMemoryTotal: minMemoryTotal, - GpuTotal: parsedGpuTotal, - NodeGroups: *nodeGroupsFlag, - EnforceNodeGroupMinSize: *enforceNodeGroupMinSize, - NodeInfosProcessorPodTemplates: *podTemplatesProcessor, - ScaleDownDelayAfterAdd: *scaleDownDelayAfterAdd, - ScaleDownDelayAfterDelete: *scaleDownDelayAfterDelete, - ScaleDownDelayAfterFailure: *scaleDownDelayAfterFailure, - ScaleDownEnabled: *scaleDownEnabled, - ScaleDownUnreadyEnabled: *scaleDownUnreadyEnabled, - ScaleDownNonEmptyCandidatesCount: *scaleDownNonEmptyCandidatesCount, - ScaleDownCandidatesPoolRatio: *scaleDownCandidatesPoolRatio, - ScaleDownCandidatesPoolMinCount: *scaleDownCandidatesPoolMinCount, - SchedulerConfig: parsedSchedConfig, - WriteStatusConfigMap: *writeStatusConfigMapFlag, - StatusConfigMapName: *statusConfigMapName, - BalanceSimilarNodeGroups: *balanceSimilarNodeGroupsFlag, - ConfigNamespace: *namespace, - ClusterName: *clusterName, - NodeAutoprovisioningEnabled: *nodeAutoprovisioningEnabled, - MaxAutoprovisionedNodeGroupCount: *maxAutoprovisionedNodeGroupCount, - UnremovableNodeRecheckTimeout: *unremovableNodeRecheckTimeout, - ExpendablePodsPriorityCutoff: *expendablePodsPriorityCutoff, - Regional: *regional, - NewPodScaleUpDelay: *newPodScaleUpDelay, - IgnoredTaints: *ignoreTaintsFlag, - BalancingExtraIgnoredLabels: *balancingIgnoreLabelsFlag, - BalancingLabels: *balancingLabelsFlag, - KubeConfigPath: *kubeConfigFile, - KubeClientBurst: *kubeClientBurst, - KubeClientQPS: *kubeClientQPS, - NodeDeletionDelayTimeout: *nodeDeletionDelayTimeout, - AWSUseStaticInstanceList: *awsUseStaticInstanceList, + CloudConfig: *cloudConfig, + CloudProviderName: *cloudProviderFlag, + NodeGroupAutoDiscovery: *nodeGroupAutoDiscoveryFlag, + MaxTotalUnreadyPercentage: *maxTotalUnreadyPercentage, + OkTotalUnreadyCount: *okTotalUnreadyCount, + ScaleUpFromZero: *scaleUpFromZero, + ParallelScaleUp: *parallelScaleUp, + EstimatorName: *estimatorFlag, + ExpanderNames: *expanderFlag, + GRPCExpanderCert: *grpcExpanderCert, + GRPCExpanderURL: *grpcExpanderURL, + IncludeSimilarNodegroupsInExpanderOptions: *includeSimilarNodegroupsInExpanderOptions, + IgnoreMirrorPodsUtilization: *ignoreMirrorPodsUtilization, + MaxBulkSoftTaintCount: *maxBulkSoftTaintCount, + MaxBulkSoftTaintTime: *maxBulkSoftTaintTime, + MaxEmptyBulkDelete: *maxEmptyBulkDeleteFlag, + MaxGracefulTerminationSec: *maxGracefulTerminationFlag, + MaxPodEvictionTime: *maxPodEvictionTime, + MaxNodesTotal: *maxNodesTotal, + MaxCoresTotal: maxCoresTotal, + MinCoresTotal: minCoresTotal, + MaxMemoryTotal: maxMemoryTotal, + MinMemoryTotal: minMemoryTotal, + GpuTotal: parsedGpuTotal, + NodeGroups: *nodeGroupsFlag, + EnforceNodeGroupMinSize: *enforceNodeGroupMinSize, + NodeInfosProcessorPodTemplates: *podTemplatesProcessor, + ScaleDownDelayAfterAdd: *scaleDownDelayAfterAdd, + ScaleDownDelayAfterDelete: *scaleDownDelayAfterDelete, + ScaleDownDelayAfterFailure: *scaleDownDelayAfterFailure, + ScaleDownEnabled: *scaleDownEnabled, + ScaleDownUnreadyEnabled: *scaleDownUnreadyEnabled, + ScaleDownNonEmptyCandidatesCount: *scaleDownNonEmptyCandidatesCount, + ScaleDownCandidatesPoolRatio: *scaleDownCandidatesPoolRatio, + ScaleDownCandidatesPoolMinCount: *scaleDownCandidatesPoolMinCount, + SchedulerConfig: parsedSchedConfig, + WriteStatusConfigMap: *writeStatusConfigMapFlag, + StatusConfigMapName: *statusConfigMapName, + BalanceSimilarNodeGroups: *balanceSimilarNodeGroupsFlag, + ConfigNamespace: *namespace, + ClusterName: *clusterName, + NodeAutoprovisioningEnabled: *nodeAutoprovisioningEnabled, + MaxAutoprovisionedNodeGroupCount: *maxAutoprovisionedNodeGroupCount, + UnremovableNodeRecheckTimeout: *unremovableNodeRecheckTimeout, + ExpendablePodsPriorityCutoff: *expendablePodsPriorityCutoff, + Regional: *regional, + NewPodScaleUpDelay: *newPodScaleUpDelay, + IgnoredTaints: *ignoreTaintsFlag, + BalancingExtraIgnoredLabels: *balancingIgnoreLabelsFlag, + BalancingLabels: *balancingLabelsFlag, + KubeConfigPath: *kubeConfigFile, + KubeClientBurst: *kubeClientBurst, + KubeClientQPS: *kubeClientQPS, + NodeDeletionDelayTimeout: *nodeDeletionDelayTimeout, + AWSUseStaticInstanceList: *awsUseStaticInstanceList, GCEOptions: config.GCEOptions{ ConcurrentRefreshes: *concurrentGceRefreshes, MigInstancesMinRefreshWaitTime: *gceMigInstancesMinRefreshWaitTime,