@@ -37,6 +37,7 @@ import (
3737
3838 "github.com/cloudpilot-ai/karpenter-provider-alicloud/pkg/apis/v1alpha1"
3939 "github.com/cloudpilot-ai/karpenter-provider-alicloud/pkg/operator/options"
40+ "github.com/cloudpilot-ai/karpenter-provider-alicloud/pkg/providers/ack"
4041 "github.com/cloudpilot-ai/karpenter-provider-alicloud/pkg/providers/imagefamily"
4142 "github.com/cloudpilot-ai/karpenter-provider-alicloud/pkg/providers/vswitch"
4243 "github.com/cloudpilot-ai/karpenter-provider-alicloud/pkg/utils/alierrors"
@@ -57,26 +58,24 @@ type Provider interface {
5758}
5859
5960type DefaultProvider struct {
60- ecsClient * ecsclient.Client
61- region string
62- clusterEndpoint string
61+ ecsClient * ecsclient.Client
62+ region string
6363
64- imageFamily imagefamily.Resolver
65-
66- vSwitchProvider vswitch .Provider
64+ imageFamilyResolver imagefamily.Resolver
65+ vSwitchProvider vswitch. Provider
66+ ackProvider ack .Provider
6767}
6868
69- func NewDefaultProvider (ctx context. Context , region , clusterEndpoint string , ecsClient * ecsclient.Client ,
70- imageFamily imagefamily.Resolver ,
71- vSwitchProvider vswitch .Provider ) * DefaultProvider {
69+ func NewDefaultProvider (region string , ecsClient * ecsclient.Client ,
70+ imageFamilyResolver imagefamily.Resolver , vSwitchProvider vswitch. Provider ,
71+ ackProvider ack .Provider ) * DefaultProvider {
7272 return & DefaultProvider {
73- ecsClient : ecsClient ,
74- region : region ,
75- clusterEndpoint : clusterEndpoint ,
76-
77- imageFamily : imageFamily ,
73+ ecsClient : ecsClient ,
74+ region : region ,
7875
79- vSwitchProvider : vSwitchProvider ,
76+ imageFamilyResolver : imageFamilyResolver ,
77+ vSwitchProvider : vSwitchProvider ,
78+ ackProvider : ackProvider ,
8079 }
8180}
8281
@@ -387,7 +386,7 @@ func (p *DefaultProvider) getProvisioningGroup(ctx context.Context, nodeClass *v
387386 break
388387 }
389388
390- vSwitchID := p .getVSwitchID (launchtemplate .InstanceTypes [i ], zonalVSwitchs , requirements )
389+ vSwitchID := p .getVSwitchID (launchtemplate .InstanceTypes [i ], zonalVSwitchs , requirements , capacityType )
391390 if vSwitchID == "" {
392391 return nil , errors .New ("vSwitchID not found" )
393392 }
@@ -409,6 +408,13 @@ func (p *DefaultProvider) getProvisioningGroup(ctx context.Context, nodeClass *v
409408 })
410409 }
411410
411+ labels := lo .Assign (nodeClaim .Labels , map [string ]string {karpv1 .CapacityTypeLabelKey : capacityType })
412+ userData , err := p .ackProvider .GetNodeRegisterScript (ctx , labels )
413+ if err != nil {
414+ log .FromContext (ctx ).Error (err , "Failed to resolve user data for node" )
415+ return nil , err
416+ }
417+
412418 createAutoProvisioningGroupRequest := & ecsclient.CreateAutoProvisioningGroupRequest {
413419 RegionId : tea .String (p .region ),
414420 TotalTargetCapacity : tea .String ("1" ),
@@ -420,6 +426,7 @@ func (p *DefaultProvider) getProvisioningGroup(ctx context.Context, nodeClass *v
420426 LaunchConfiguration : & ecsclient.CreateAutoProvisioningGroupRequestLaunchConfiguration {
421427 ImageId : tea .String (launchtemplate .ImageID ),
422428 SecurityGroupIds : launchtemplate .SecurityGroupIds ,
429+ UserData : tea .String (userData ),
423430
424431 // TODO: AutoProvisioningGroup is not compatible with SecurityGroupIds, waiting for Aliyun developers to fix it,
425432 // so here we only take the first one.
@@ -456,7 +463,12 @@ func (p *DefaultProvider) checkODFallback(nodeClaim *karpv1.NodeClaim, instanceT
456463 return nil
457464}
458465
459- func (p * DefaultProvider ) getVSwitchID (instanceType * cloudprovider.InstanceType , zonalVSwitchs map [string ]* vswitch.VSwitch , reqs scheduling.Requirements ) string {
466+ func (p * DefaultProvider ) getVSwitchID (instanceType * cloudprovider.InstanceType ,
467+ zonalVSwitchs map [string ]* vswitch.VSwitch , reqs scheduling.Requirements , capacityType string ) string {
468+ cheapestVSwitchID := ""
469+ cheapestPrice := math .MaxFloat64
470+
471+ // For different AZ, the spot price may differ. So we need to get the cheapest vSwitch in the zone
460472 for i := range instanceType .Offerings {
461473 if reqs .Compatible (instanceType .Offerings [i ].Requirements , scheduling .AllowUndefinedWellKnownLabels ) != nil {
462474 continue
@@ -465,9 +477,17 @@ func (p *DefaultProvider) getVSwitchID(instanceType *cloudprovider.InstanceType,
465477 if ! ok {
466478 continue
467479 }
468- return vswitch .ID
480+ if capacityType == karpv1 .CapacityTypeOnDemand {
481+ return vswitch .ID
482+ }
483+
484+ if instanceType .Offerings [i ].Price < cheapestPrice {
485+ cheapestVSwitchID = vswitch .ID
486+ cheapestPrice = instanceType .Offerings [i ].Price
487+ }
469488 }
470- return ""
489+
490+ return cheapestVSwitchID
471491}
472492
473493type LaunchTemplate struct {
@@ -477,12 +497,14 @@ type LaunchTemplate struct {
477497 SystemDisk * v1alpha1.SystemDisk
478498}
479499
480- func (p * DefaultProvider ) EnsureAll (ctx context.Context , nodeClass * v1alpha1.ECSNodeClass , nodeClaim * karpv1.NodeClaim , instanceTypes []* cloudprovider.InstanceType , capacityType string , tags map [string ]string ) ([]* LaunchTemplate , error ) {
500+ func (p * DefaultProvider ) EnsureAll (ctx context.Context , nodeClass * v1alpha1.ECSNodeClass ,
501+ nodeClaim * karpv1.NodeClaim , instanceTypes []* cloudprovider.InstanceType ,
502+ capacityType string , tags map [string ]string ) ([]* LaunchTemplate , error ) {
481503 imageOptions , err := p .resolveImageOptions (ctx , nodeClass , lo .Assign (nodeClaim .Labels , map [string ]string {karpv1 .CapacityTypeLabelKey : capacityType }), tags )
482504 if err != nil {
483505 return nil , err
484506 }
485- resolvedLaunchTemplates , err := p .imageFamily .Resolve (ctx , nodeClass , nodeClaim , instanceTypes , capacityType , imageOptions )
507+ resolvedLaunchTemplates , err := p .imageFamilyResolver .Resolve (ctx , nodeClass , nodeClaim , instanceTypes , capacityType , imageOptions )
486508 if err != nil {
487509 return nil , err
488510 }
@@ -526,11 +548,10 @@ func (p *DefaultProvider) resolveImageOptions(ctx context.Context, nodeClass *v1
526548 return nil , fmt .Errorf ("no security groups are present in the status" )
527549 }
528550 return & imagefamily.Options {
529- ClusterName : options .FromContext (ctx ).ClusterName ,
530- ClusterEndpoint : p .clusterEndpoint ,
531- SecurityGroups : nodeClass .Status .SecurityGroups ,
532- Tags : tags ,
533- Labels : labels ,
534- NodeClassName : nodeClass .Name ,
551+ ClusterName : options .FromContext (ctx ).ClusterName ,
552+ SecurityGroups : nodeClass .Status .SecurityGroups ,
553+ Tags : tags ,
554+ Labels : labels ,
555+ NodeClassName : nodeClass .Name ,
535556 }, nil
536557}
0 commit comments