Skip to content
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@ spec:
AKSNodeClassSpec is the top level specification for the AKS Karpenter Provider.
This will contain configuration necessary to launch instances in AKS.
properties:
artifactStreamingEnabled:
default: false
description: |-
ArtifactStreamingEnabled controls whether artifact streaming is enabled for container images.
Artifact streaming allows AKS to stream container images from ACR by only pulling the
necessary layers for initial pod startup, reducing image pull times and improving pod start-up performance.
Note: Only supported on Ubuntu2204 and AzureLinux image families. Not supported on ARM64 architecture.
To use artifact streaming, container images must be converted to streaming-compatible artifacts in ACR.
See: https://learn.microsoft.com/en-us/azure/aks/artifact-streaming
type: boolean
fipsMode:
description: FIPSMode controls FIPS compliance for the provisioned
nodes
Expand Down Expand Up @@ -398,6 +408,16 @@ spec:
AKSNodeClassSpec is the top level specification for the AKS Karpenter Provider.
This will contain configuration necessary to launch instances in AKS.
properties:
artifactStreamingEnabled:
default: false
description: |-
ArtifactStreamingEnabled controls whether artifact streaming is enabled for container images.
Artifact streaming allows AKS to stream container images from ACR by only pulling the
necessary layers for initial pod startup, reducing image pull times and improving pod start-up performance.
Note: Only supported on Ubuntu2204 and AzureLinux image families. Not supported on ARM64 architecture.
To use artifact streaming, container images must be converted to streaming-compatible artifacts in ACR.
See: https://learn.microsoft.com/en-us/azure/aks/artifact-streaming
type: boolean
fipsMode:
description: FIPSMode controls FIPS compliance for the provisioned
nodes
Expand Down
20 changes: 20 additions & 0 deletions pkg/apis/crds/karpenter.azure.com_aksnodeclasses.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@ spec:
AKSNodeClassSpec is the top level specification for the AKS Karpenter Provider.
This will contain configuration necessary to launch instances in AKS.
properties:
artifactStreamingEnabled:
default: false
description: |-
ArtifactStreamingEnabled controls whether artifact streaming is enabled for container images.
Artifact streaming allows AKS to stream container images from ACR by only pulling the
necessary layers for initial pod startup, reducing image pull times and improving pod start-up performance.
Note: Only supported on Ubuntu2204 and AzureLinux image families. Not supported on ARM64 architecture.
To use artifact streaming, container images must be converted to streaming-compatible artifacts in ACR.
See: https://learn.microsoft.com/en-us/azure/aks/artifact-streaming
type: boolean
fipsMode:
description: FIPSMode controls FIPS compliance for the provisioned
nodes
Expand Down Expand Up @@ -398,6 +408,16 @@ spec:
AKSNodeClassSpec is the top level specification for the AKS Karpenter Provider.
This will contain configuration necessary to launch instances in AKS.
properties:
artifactStreamingEnabled:
default: false
description: |-
ArtifactStreamingEnabled controls whether artifact streaming is enabled for container images.
Artifact streaming allows AKS to stream container images from ACR by only pulling the
necessary layers for initial pod startup, reducing image pull times and improving pod start-up performance.
Note: Only supported on Ubuntu2204 and AzureLinux image families. Not supported on ARM64 architecture.
To use artifact streaming, container images must be converted to streaming-compatible artifacts in ACR.
See: https://learn.microsoft.com/en-us/azure/aks/artifact-streaming
type: boolean
fipsMode:
description: FIPSMode controls FIPS compliance for the provisioned
nodes
Expand Down
9 changes: 9 additions & 0 deletions pkg/apis/v1alpha2/aksnodeclass.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ type AKSNodeClassSpec struct {
// +kubebuilder:validation:Maximum:=250
// +optional
MaxPods *int32 `json:"maxPods,omitempty"`
// ArtifactStreamingEnabled controls whether artifact streaming is enabled for container images.
// Artifact streaming allows AKS to stream container images from ACR by only pulling the
// necessary layers for initial pod startup, reducing image pull times and improving pod start-up performance.
// Note: Only supported on Ubuntu2204 and AzureLinux image families. Not supported on ARM64 architecture.
// To use artifact streaming, container images must be converted to streaming-compatible artifacts in ACR.
// See: https://learn.microsoft.com/en-us/azure/aks/artifact-streaming
// +kubebuilder:default=false
// +optional
ArtifactStreamingEnabled *bool `json:"artifactStreamingEnabled,omitempty"`
Comment on lines +90 to +92
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this require bumping AKSNodeClass hash version? Otherwise I think the presence of default means hash value will change and cause drift of all nodes ... In any case, aksnodeclass_hash_tests needs to be updated (seems to be missing coverage of some other fields as well)

// Collection of security related karpenter fields
Security *Security `json:"security,omitempty"`
}
Expand Down
5 changes: 5 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.

9 changes: 9 additions & 0 deletions pkg/apis/v1beta1/aksnodeclass.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ type AKSNodeClassSpec struct {
// +kubebuilder:validation:Maximum:=250
// +optional
MaxPods *int32 `json:"maxPods,omitempty"`
// ArtifactStreamingEnabled controls whether artifact streaming is enabled for container images.
// Artifact streaming allows AKS to stream container images from ACR by only pulling the
// necessary layers for initial pod startup, reducing image pull times and improving pod start-up performance.
// Note: Only supported on Ubuntu2204 and AzureLinux image families. Not supported on ARM64 architecture.
// To use artifact streaming, container images must be converted to streaming-compatible artifacts in ACR.
// See: https://learn.microsoft.com/en-us/azure/aks/artifact-streaming
// +kubebuilder:default=false
// +optional
ArtifactStreamingEnabled *bool `json:"artifactStreamingEnabled,omitempty"`

// Collection of security related karpenter fields
Security *Security `json:"security,omitempty"`
Expand Down
44 changes: 44 additions & 0 deletions pkg/apis/v1beta1/crd_validation_cel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
"sigs.k8s.io/controller-runtime/pkg/client"

karpv1 "sigs.k8s.io/karpenter/pkg/apis/v1"
"sigs.k8s.io/karpenter/pkg/test"
Expand Down Expand Up @@ -363,4 +364,47 @@ var _ = Describe("CEL/Validation", func() {
Expect(env.Client.Create(ctx, nodeClass)).To(Succeed())
})
})

Context("ArtifactStreamingEnabled", func() {
It("should default to false when not specified", func() {
nodeClass := &v1beta1.AKSNodeClass{
ObjectMeta: metav1.ObjectMeta{Name: strings.ToLower(randomdata.SillyName())},
Spec: v1beta1.AKSNodeClassSpec{},
}
Expect(env.Client.Create(ctx, nodeClass)).To(Succeed())
// Fetch the created nodeClass to check the defaulted value
createdNodeClass := &v1beta1.AKSNodeClass{}
Expect(env.Client.Get(ctx, client.ObjectKeyFromObject(nodeClass), createdNodeClass)).To(Succeed())
Expect(createdNodeClass.Spec.ArtifactStreamingEnabled).ToNot(BeNil())
Expect(lo.FromPtr(createdNodeClass.Spec.ArtifactStreamingEnabled)).To(BeFalse())
})

It("should allow explicitly setting to false", func() {
nodeClass := &v1beta1.AKSNodeClass{
ObjectMeta: metav1.ObjectMeta{Name: strings.ToLower(randomdata.SillyName())},
Spec: v1beta1.AKSNodeClassSpec{
ArtifactStreamingEnabled: lo.ToPtr(false),
},
}
Expect(env.Client.Create(ctx, nodeClass)).To(Succeed())
createdNodeClass := &v1beta1.AKSNodeClass{}
Expect(env.Client.Get(ctx, client.ObjectKeyFromObject(nodeClass), createdNodeClass)).To(Succeed())
Expect(createdNodeClass.Spec.ArtifactStreamingEnabled).ToNot(BeNil())
Expect(lo.FromPtr(createdNodeClass.Spec.ArtifactStreamingEnabled)).To(BeFalse())
})

It("should allow explicitly setting to true", func() {
nodeClass := &v1beta1.AKSNodeClass{
ObjectMeta: metav1.ObjectMeta{Name: strings.ToLower(randomdata.SillyName())},
Spec: v1beta1.AKSNodeClassSpec{
ArtifactStreamingEnabled: lo.ToPtr(true),
},
}
Expect(env.Client.Create(ctx, nodeClass)).To(Succeed())
createdNodeClass := &v1beta1.AKSNodeClass{}
Expect(env.Client.Get(ctx, client.ObjectKeyFromObject(nodeClass), createdNodeClass)).To(Succeed())
Expect(createdNodeClass.Spec.ArtifactStreamingEnabled).ToNot(BeNil())
Expect(lo.FromPtr(createdNodeClass.Spec.ArtifactStreamingEnabled)).To(BeTrue())
})
})
})
5 changes: 5 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.

4 changes: 4 additions & 0 deletions pkg/providers/imagefamily/azlinux.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ func (u AzureLinux) ScriptlessCustomData(
labels map[string]string,
caBundle *string,
_ *cloudprovider.InstanceType,
artifactStreamingEnabled *bool,
) bootstrap.Bootstrapper {
return bootstrap.AKS{
Options: bootstrap.Options{
Expand Down Expand Up @@ -151,6 +152,7 @@ func (u AzureLinux) ScriptlessCustomData(
NetworkPlugin: u.Options.NetworkPlugin,
NetworkPolicy: u.Options.NetworkPolicy,
KubernetesVersion: u.Options.KubernetesVersion,
ArtifactStreamingEnabled: artifactStreamingEnabled,
}
}

Expand All @@ -165,6 +167,7 @@ func (u AzureLinux) CustomScriptsNodeBootstrapping(
storageProfile string,
nodeBootstrappingClient types.NodeBootstrappingAPI,
fipsMode *v1beta1.FIPSMode,
artifactStreamingEnabled *bool,
) customscriptsbootstrap.Bootstrapper {
return customscriptsbootstrap.ProvisionClientBootstrap{
ClusterName: u.Options.ClusterName,
Expand All @@ -185,5 +188,6 @@ func (u AzureLinux) CustomScriptsNodeBootstrapping(
NodeBootstrappingProvider: nodeBootstrappingClient,
OSSKU: customscriptsbootstrap.ImageFamilyOSSKUAzureLinux2,
FIPSMode: fipsMode,
ArtifactStreamingEnabled: artifactStreamingEnabled,
}
}
4 changes: 4 additions & 0 deletions pkg/providers/imagefamily/azlinux3.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ func (u AzureLinux3) ScriptlessCustomData(
labels map[string]string,
caBundle *string,
_ *cloudprovider.InstanceType,
artifactStreamingEnabled *bool,
) bootstrap.Bootstrapper {
return bootstrap.AKS{
Options: bootstrap.Options{
Expand Down Expand Up @@ -169,6 +170,7 @@ func (u AzureLinux3) ScriptlessCustomData(
NetworkPlugin: u.Options.NetworkPlugin,
NetworkPolicy: u.Options.NetworkPolicy,
KubernetesVersion: u.Options.KubernetesVersion,
ArtifactStreamingEnabled: artifactStreamingEnabled,
}
}

Expand All @@ -183,6 +185,7 @@ func (u AzureLinux3) CustomScriptsNodeBootstrapping(
storageProfile string,
nodeBootstrappingClient types.NodeBootstrappingAPI,
fipsMode *v1beta1.FIPSMode,
artifactStreamingEnabled *bool,
) customscriptsbootstrap.Bootstrapper {
return customscriptsbootstrap.ProvisionClientBootstrap{
ClusterName: u.Options.ClusterName,
Expand All @@ -203,5 +206,6 @@ func (u AzureLinux3) CustomScriptsNodeBootstrapping(
NodeBootstrappingProvider: nodeBootstrappingClient,
OSSKU: customscriptsbootstrap.ImageFamilyOSSKUAzureLinux3,
FIPSMode: fipsMode,
ArtifactStreamingEnabled: artifactStreamingEnabled,
}
}
1 change: 1 addition & 0 deletions pkg/providers/imagefamily/azlinux3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ func TestAzureLinux3_CustomScriptsNodeBootstrapping(t *testing.T) {
storageProfile,
nodeBootstrappingClient,
fipsMode,
nil, // artifactStreamingEnabled
)

// Verify the returned bootstrapper is of the correct type
Expand Down
1 change: 1 addition & 0 deletions pkg/providers/imagefamily/azlinux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ func TestAzureLinux_CustomScriptsNodeBootstrapping(t *testing.T) {
storageProfile,
nodeBootstrappingClient,
fipsMode,
nil, // artifactStreamingEnabled
)

// Verify the returned bootstrapper is of the correct type
Expand Down
5 changes: 5 additions & 0 deletions pkg/providers/imagefamily/bootstrap/aksbootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type AKS struct {
NetworkPlugin string
NetworkPolicy string
KubernetesVersion string
ArtifactStreamingEnabled *bool
}

var _ Bootstrapper = (*AKS)(nil) // assert AKS implements Bootstrapper
Expand Down Expand Up @@ -220,6 +221,7 @@ type NodeBootstrapVariables struct {
KubeCACrt string // x unique per cluster
ContainerdConfigContent string // k determined by GPU VM size, WASM support, Kata support
IsKata bool // n user-specified
EnableArtifactStreaming bool // t user-specified via AKSNodeClass
}

func (a AKS) aksBootstrapScript() (string, error) {
Expand Down Expand Up @@ -354,6 +356,9 @@ func (a AKS) applyOptions(nbv *NodeBootstrapVariables) {
nbv.KubeletFlags = strings.Join(lo.MapToSlice(kubeletFlags, func(k, v string) string {
return fmt.Sprintf("%s=%s", k, v)
}), " ")

// Set artifact streaming enabled flag
nbv.EnableArtifactStreaming = lo.FromPtr(a.ArtifactStreamingEnabled)
}

func containerdConfigFromNodeBootstrapVars(nbv *NodeBootstrapVariables) (string, error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ type ProvisionClientBootstrap struct {
OSSKU string
NodeBootstrappingProvider types.NodeBootstrappingAPI
FIPSMode *v1beta1.FIPSMode
ArtifactStreamingEnabled *bool
}

var _ Bootstrapper = (*ProvisionClientBootstrap)(nil) // assert ProvisionClientBootstrap implements customscriptsbootstrapper
Expand Down Expand Up @@ -107,8 +108,13 @@ func (p *ProvisionClientBootstrap) ConstructProvisionValues(ctx context.Context)
labels.AddAgentBakerGeneratedLabels(p.ResourceGroup, options.FromContext(ctx).KubeletIdentityClientID, nodeLabels)

// artifact streaming is not yet supported for Arm64, for Ubuntu 20.04, Ubuntu 24.04, and for Azure Linux v3
enableArtifactStreaming := p.Arch == karpv1.ArchitectureAmd64 &&
(p.OSSKU == ImageFamilyOSSKUUbuntu2204 || p.OSSKU == ImageFamilyOSSKUAzureLinux2)
// Only enable if explicitly requested in the nodeclass AND the configuration is supported
enableArtifactStreaming := false
if lo.FromPtr(p.ArtifactStreamingEnabled) {
// User wants it enabled, verify the arch and OS SKU are supported
enableArtifactStreaming = p.Arch == karpv1.ArchitectureAmd64 &&
(p.OSSKU == ImageFamilyOSSKUUbuntu2204 || p.OSSKU == ImageFamilyOSSKUAzureLinux2)
}

// unspecified FIPSMode is effectively no FIPS for now
enableFIPS := lo.FromPtr(p.FIPSMode) == v1beta1.FIPSModeFIPS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ func TestConstructProvisionValues(t *testing.T) {
OSSKU: customscriptsbootstrap.ImageFamilyOSSKUAzureLinux2,
Labels: map[string]string{"kubernetes.azure.com/mode": "system"}, // Test system mode
NodeBootstrappingProvider: &fake.NodeBootstrappingAPI{},
ArtifactStreamingEnabled: lo.ToPtr(true), // Explicitly enable to test artifact streaming works when enabled
InstanceType: &cloudprovider.InstanceType{
Name: "Standard_D2s_v3",
Capacity: v1.ResourceList{
Expand Down Expand Up @@ -695,13 +696,13 @@ func TestArtifactStreamingEnablement(t *testing.T) {
description: "Artifact streaming should be disabled for AMD64 with Ubuntu2004 FIPS",
},
{
name: "AMD64 Ubuntu2204 - Artifact streaming enabled",
name: "AMD64 Ubuntu2204 - Artifact streaming disabled by default",
arch: karpv1.ArchitectureAmd64,
ossku: customscriptsbootstrap.ImageFamilyOSSKUUbuntu2204,
kubernetesVersion: "1.31.0",
imageDistro: "aks-ubuntu-containerd-22.04-gen2",
expectedArtifactStreamingEnabled: true,
description: "Artifact streaming should be enabled for AMD64 with Ubuntu2204",
expectedArtifactStreamingEnabled: false,
description: "Artifact streaming should be disabled by default for AMD64 with Ubuntu2204",
},
{
name: "AMD64 Ubuntu2404 - Artifact streaming disabled",
Expand All @@ -713,13 +714,13 @@ func TestArtifactStreamingEnablement(t *testing.T) {
description: "Artifact streaming should be disabled for AMD64 with Ubuntu2404",
},
{
name: "AMD64 AzureLinux2 - Artifact streaming enabled",
name: "AMD64 AzureLinux2 - Artifact streaming disabled by default",
arch: karpv1.ArchitectureAmd64,
ossku: customscriptsbootstrap.ImageFamilyOSSKUAzureLinux2,
kubernetesVersion: "1.31.0",
imageDistro: "aks-azurelinux-v2-gen2",
expectedArtifactStreamingEnabled: true,
description: "Artifact streaming should be enabled for AMD64 with AzureLinux2",
expectedArtifactStreamingEnabled: false,
description: "Artifact streaming should be disabled by default for AMD64 with AzureLinux2",
},
{
name: "AMD64 AzureLinux3 - Artifact streaming disabled",
Expand Down
4 changes: 4 additions & 0 deletions pkg/providers/imagefamily/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ type ImageFamily interface {
labels map[string]string,
caBundle *string,
instanceType *cloudprovider.InstanceType,
artifactStreamingEnabled *bool,
) bootstrap.Bootstrapper
CustomScriptsNodeBootstrapping(
kubeletConfig *bootstrap.KubeletConfiguration,
Expand All @@ -80,6 +81,7 @@ type ImageFamily interface {
storageProfile string,
nodeBootstrappingClient types.NodeBootstrappingAPI,
fipsMode *v1beta1.FIPSMode,
artifactStreamingEnabled *bool,
) customscriptsbootstrap.Bootstrapper
Name() string
// DefaultImages returns a list of default CommunityImage definitions for this ImageFamily.
Expand Down Expand Up @@ -162,6 +164,7 @@ func (r *defaultResolver) Resolve(
staticParameters.Labels,
staticParameters.CABundle,
instanceType,
nodeClass.Spec.ArtifactStreamingEnabled,
),
CustomScriptsNodeBootstrapping: imageFamily.CustomScriptsNodeBootstrapping(
prepareKubeletConfiguration(ctx, instanceType, nodeClass),
Expand All @@ -173,6 +176,7 @@ func (r *defaultResolver) Resolve(
diskType,
r.nodeBootstrappingProvider,
nodeClass.Spec.FIPSMode,
nodeClass.Spec.ArtifactStreamingEnabled,
),
StorageProfileDiskType: diskType,
StorageProfileIsEphemeral: diskType == consts.StorageProfileEphemeral,
Expand Down
Loading
Loading