Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions pkg/apis/crds/karpenter.azure.com_aksnodeclasses.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,23 @@ spec:
rule: self.all(k, !k.contains('\\'))
- message: tags values must be less than 256 characters
rule: self.all(k, size(self[k]) <= 256)
vmSizeProperties:
description: |-
vmSizeProperties configures VM size customization options such as vCPU-to-physical-core ratio.
This allows disabling hyperthreading (SMT) by setting vCPUsPerCore to 1.
For more details see https://learn.microsoft.com/en-us/azure/virtual-machines/vm-customization
properties:
vCPUsPerCore:
description: |-
vCPUsPerCore specifies the vCPU to physical core ratio.
Setting this to 1 disables hyperthreading (SMT).
Setting this to 2 or omitting enables hyperthreading (default).
Note: Can only be set at VM creation time, not on running VMs.
format: int32
maximum: 2
minimum: 1
type: integer
type: object
vnetSubnetID:
description: |-
vnetSubnetID is the subnet used by nics provisioned with this nodeclass.
Expand Down Expand Up @@ -1668,6 +1685,23 @@ spec:
rule: self.all(k, !k.contains('\\'))
- message: tags values must be less than 256 characters
rule: self.all(k, size(self[k]) <= 256)
vmSizeProperties:
description: |-
vmSizeProperties configures VM size customization options such as vCPU-to-physical-core ratio.
This allows disabling hyperthreading (SMT) by setting vCPUsPerCore to 1.
For more details see https://learn.microsoft.com/en-us/azure/virtual-machines/vm-customization
properties:
vCPUsPerCore:
description: |-
vCPUsPerCore specifies the vCPU to physical core ratio.
Setting this to 1 disables hyperthreading (SMT).
Setting this to 2 or omitting enables hyperthreading (default).
Note: Can only be set at VM creation time, not on running VMs.
format: int32
maximum: 2
minimum: 1
type: integer
type: object
vnetSubnetID:
description: |-
vnetSubnetID is the subnet used by nics provisioned with this nodeclass.
Expand Down
18 changes: 18 additions & 0 deletions pkg/apis/v1alpha2/aksnodeclass.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,24 @@ type AKSNodeClassSpec struct {
// https://learn.microsoft.com/en-us/azure/aks/custom-node-configuration
// +optional
LinuxOSConfig *LinuxOSConfiguration `json:"linuxOSConfig,omitempty"`
// vmSizeProperties configures VM size customization options such as vCPU-to-physical-core ratio.
// This allows disabling hyperthreading (SMT) by setting vCPUsPerCore to 1.
// For more details see https://learn.microsoft.com/en-us/azure/virtual-machines/vm-customization
// +optional
VMSizeProperties *VMSizeProperties `json:"vmSizeProperties,omitempty"`
}

// VMSizeProperties specifies VM size customization options.
// See: https://learn.microsoft.com/en-us/azure/virtual-machines/vm-customization
type VMSizeProperties struct {
// vCPUsPerCore specifies the vCPU to physical core ratio.
// Setting this to 1 disables hyperthreading (SMT).
// Setting this to 2 or omitting enables hyperthreading (default).
// Note: Can only be set at VM creation time, not on running VMs.
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=2
// +optional
VCPUsPerCore *int32 `json:"vCPUsPerCore,omitempty"`
}

// TODO: Add link for the aka.ms/nap/aksnodeclass-enable-host-encryption docs
Expand Down
50 changes: 50 additions & 0 deletions pkg/apis/v1alpha2/crd_validation_cel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1077,4 +1077,54 @@ var _ = Describe("CEL/Validation", func() {
Expect(env.Client.Create(ctx, nodeClass)).To(Succeed())
})
})

Context("VMSizeProperties", func() {
It("should allow vmSizeProperties with vCPUsPerCore set to 1 (SMT disabled)", func() {
nodeClass := &v1alpha2.AKSNodeClass{
ObjectMeta: metav1.ObjectMeta{Name: strings.ToLower(randomdata.SillyName())},
Spec: v1alpha2.AKSNodeClassSpec{
VMSizeProperties: &v1alpha2.VMSizeProperties{
VCPUsPerCore: lo.ToPtr(int32(1)),
},
},
}
Expect(env.Client.Create(ctx, nodeClass)).To(Succeed())
})

It("should allow vmSizeProperties with vCPUsPerCore set to 2 (SMT enabled)", func() {
nodeClass := &v1alpha2.AKSNodeClass{
ObjectMeta: metav1.ObjectMeta{Name: strings.ToLower(randomdata.SillyName())},
Spec: v1alpha2.AKSNodeClassSpec{
VMSizeProperties: &v1alpha2.VMSizeProperties{
VCPUsPerCore: lo.ToPtr(int32(2)),
},
},
}
Expect(env.Client.Create(ctx, nodeClass)).To(Succeed())
})

It("should reject vmSizeProperties with vCPUsPerCore set to 0", func() {
nodeClass := &v1alpha2.AKSNodeClass{
ObjectMeta: metav1.ObjectMeta{Name: strings.ToLower(randomdata.SillyName())},
Spec: v1alpha2.AKSNodeClassSpec{
VMSizeProperties: &v1alpha2.VMSizeProperties{
VCPUsPerCore: lo.ToPtr(int32(0)),
},
},
}
Expect(env.Client.Create(ctx, nodeClass)).ToNot(Succeed())
})

It("should reject vmSizeProperties with vCPUsPerCore set to 3", func() {
nodeClass := &v1alpha2.AKSNodeClass{
ObjectMeta: metav1.ObjectMeta{Name: strings.ToLower(randomdata.SillyName())},
Spec: v1alpha2.AKSNodeClassSpec{
VMSizeProperties: &v1alpha2.VMSizeProperties{
VCPUsPerCore: lo.ToPtr(int32(3)),
},
},
}
Expect(env.Client.Create(ctx, nodeClass)).ToNot(Succeed())
})
})
})
25 changes: 25 additions & 0 deletions pkg/apis/v1alpha2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions pkg/apis/v1beta1/aksnodeclass.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,24 @@ type AKSNodeClassSpec struct {
// https://learn.microsoft.com/en-us/azure/aks/custom-node-configuration
// +optional
LinuxOSConfig *LinuxOSConfiguration `json:"linuxOSConfig,omitempty"`
// vmSizeProperties configures VM size customization options such as vCPU-to-physical-core ratio.
// This allows disabling hyperthreading (SMT) by setting vCPUsPerCore to 1.
// For more details see https://learn.microsoft.com/en-us/azure/virtual-machines/vm-customization
// +optional
VMSizeProperties *VMSizeProperties `json:"vmSizeProperties,omitempty"`
}

// VMSizeProperties specifies VM size customization options.
// See: https://learn.microsoft.com/en-us/azure/virtual-machines/vm-customization
type VMSizeProperties struct {
// vCPUsPerCore specifies the vCPU to physical core ratio.
// Setting this to 1 disables hyperthreading (SMT).
// Setting this to 2 or omitting enables hyperthreading (default).
// Note: Can only be set at VM creation time, not on running VMs.
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=2
// +optional
VCPUsPerCore *int32 `json:"vCPUsPerCore,omitempty"`
}

// TODO: Add link for the aka.ms/nap/aksnodeclass-enable-host-encryption docs
Expand Down
51 changes: 51 additions & 0 deletions pkg/apis/v1beta1/crd_validation_cel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1097,6 +1097,57 @@ var _ = Describe("CEL/Validation", func() {
Expect(env.Client.Create(ctx, nodeClass)).To(Succeed())
})
})

Context("VMSizeProperties", func() {
It("should allow vmSizeProperties with vCPUsPerCore set to 1 (SMT disabled)", func() {
nodeClass := &v1beta1.AKSNodeClass{
ObjectMeta: metav1.ObjectMeta{Name: strings.ToLower(randomdata.SillyName())},
Spec: v1beta1.AKSNodeClassSpec{
VMSizeProperties: &v1beta1.VMSizeProperties{
VCPUsPerCore: lo.ToPtr(int32(1)),
},
},
}
Expect(env.Client.Create(ctx, nodeClass)).To(Succeed())
})

It("should allow vmSizeProperties with vCPUsPerCore set to 2 (SMT enabled)", func() {
nodeClass := &v1beta1.AKSNodeClass{
ObjectMeta: metav1.ObjectMeta{Name: strings.ToLower(randomdata.SillyName())},
Spec: v1beta1.AKSNodeClassSpec{
VMSizeProperties: &v1beta1.VMSizeProperties{
VCPUsPerCore: lo.ToPtr(int32(2)),
},
},
}
Expect(env.Client.Create(ctx, nodeClass)).To(Succeed())
})

It("should reject vmSizeProperties with vCPUsPerCore set to 0", func() {
nodeClass := &v1beta1.AKSNodeClass{
ObjectMeta: metav1.ObjectMeta{Name: strings.ToLower(randomdata.SillyName())},
Spec: v1beta1.AKSNodeClassSpec{
VMSizeProperties: &v1beta1.VMSizeProperties{
VCPUsPerCore: lo.ToPtr(int32(0)),
},
},
}
Expect(env.Client.Create(ctx, nodeClass)).ToNot(Succeed())
})

It("should reject vmSizeProperties with vCPUsPerCore set to 3", func() {
nodeClass := &v1beta1.AKSNodeClass{
ObjectMeta: metav1.ObjectMeta{Name: strings.ToLower(randomdata.SillyName())},
Spec: v1beta1.AKSNodeClassSpec{
VMSizeProperties: &v1beta1.VMSizeProperties{
VCPUsPerCore: lo.ToPtr(int32(3)),
},
},
}
Expect(env.Client.Create(ctx, nodeClass)).ToNot(Succeed())
})
})

Context("LinuxOSConfig sysctl cross-field validation", func() {
It("should reject rmemDefault > rmemMax", func() {
nodeClass := &v1beta1.AKSNodeClass{
Expand Down
25 changes: 25 additions & 0 deletions pkg/apis/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 17 additions & 1 deletion pkg/providers/instance/vminstance.go
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,8 @@ func newVMObject(opts *createVMOptions) *armcompute.VirtualMachine {
Identity: ConvertToVirtualMachineIdentity(opts.NodeIdentities),
Properties: &armcompute.VirtualMachineProperties{
HardwareProfile: &armcompute.HardwareProfile{
VMSize: lo.ToPtr(armcompute.VirtualMachineSizeTypes(opts.InstanceType.Name)),
VMSize: lo.ToPtr(armcompute.VirtualMachineSizeTypes(opts.InstanceType.Name)),
VMSizeProperties: convertVMSizeProperties(opts.NodeClass.Spec.VMSizeProperties, opts.ProvisionMode),
},

StorageProfile: &armcompute.StorageProfile{
Expand Down Expand Up @@ -678,6 +679,21 @@ func setVMPropertiesSecurityProfile(vmProperties *armcompute.VirtualMachinePrope
}
}

// convertVMSizeProperties converts AKSNodeClass VMSizeProperties to Azure SDK format.
// Returns nil when vmSizeProperties are unspecified or when the provision mode does not use the VM API.
func convertVMSizeProperties(props *v1beta1.VMSizeProperties, provisionMode string) *armcompute.VMSizeProperties {
if props == nil || isAKSMachineAPIMode(provisionMode) {
return nil
}
return &armcompute.VMSizeProperties{
VCPUsPerCore: props.VCPUsPerCore,
}
}

func isAKSMachineAPIMode(provisionMode string) bool {
return provisionMode == consts.ProvisionModeAKSMachineAPI || provisionMode == consts.ProvisionModeAKSMachineAPIHeaderBatch
}

type createResult struct {
Poller *runtime.Poller[armcompute.VirtualMachinesClientCreateOrUpdateResponse]
VM *armcompute.VirtualMachine
Expand Down
Loading