Repository: kubernetes/kops (go)

Issue:
Expose imageMinimumGCAge and imageMaximumGCAge kubelet config
/kind feature

**1. Describe IN DETAIL the feature/behavior/change you would like to see.**

I would like to configure `imageMinimumGCAge` and `imageMaximumGCAge` in kubelet config with kops
ref: https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/#kubelet-config-k8s-io-v1beta1-KubeletConfiguration

**2. Feel free to provide a design supporting your feature request.**

adding these to the spec the same way as `imageGCHighThresholdPercent` already is

Pull request description:
feat: added image minimum and maximum gc age
fixes #16317 

i hope i added these correctly. tried to follow these docs: https://github.com/kubernetes/kops/blob/master/docs/contributing/api_updates.md#adding-a-field

Patch:
diff --git a/k8s/crds/kops.k8s.io_clusters.yaml b/k8s/crds/kops.k8s.io_clusters.yaml
index fb80b405e8..a4c2e4b677 100644
--- a/k8s/crds/kops.k8s.io_clusters.yaml
+++ b/k8s/crds/kops.k8s.io_clusters.yaml
@@ -4073,6 +4073,17 @@ spec:
                       disk usage to garbage collect to.
                     format: int32
                     type: integer
+                  imageMaximumGCAge:
+                    description: 'imageMaximumGCAge is the maximum age an image can
+                      be unused before it is garbage collected. The default of this
+                      field is "0s", which disables this field--meaning images won''t
+                      be garbage collected based on being unused for too long. Default:
+                      "0s" (disabled)'
+                    type: string
+                  imageMinimumGCAge:
+                    description: 'imageMinimumGCAge is the minimum age for an unused
+                      image before it is garbage collected. Default: "2m"'
+                    type: string
                   imagePullProgressDeadline:
                     description: ImagePullProgressDeadline is the timeout for image
                       pulls If no pulling progress is made before this deadline, the
@@ -4511,6 +4522,17 @@ spec:
                       disk usage to garbage collect to.
                     format: int32
                     type: integer
+                  imageMaximumGCAge:
+                    description: 'imageMaximumGCAge is the maximum age an image can
+                      be unused before it is garbage collected. The default of this
+                      field is "0s", which disables this field--meaning images won''t
+                      be garbage collected based on being unused for too long. Default:
+                      "0s" (disabled)'
+                    type: string
+                  imageMinimumGCAge:
+                    description: 'imageMinimumGCAge is the minimum age for an unused
+                      image before it is garbage collected. Default: "2m"'
+                    type: string
                   imagePullProgressDeadline:
                     description: ImagePullProgressDeadline is the timeout for image
                       pulls If no pulling progress is made before this deadline, the
diff --git a/k8s/crds/kops.k8s.io_instancegroups.yaml b/k8s/crds/kops.k8s.io_instancegroups.yaml
index ffca491ab2..39d27c5154 100644
--- a/k8s/crds/kops.k8s.io_instancegroups.yaml
+++ b/k8s/crds/kops.k8s.io_instancegroups.yaml
@@ -606,6 +606,17 @@ spec:
                       disk usage to garbage collect to.
                     format: int32
                     type: integer
+                  imageMaximumGCAge:
+                    description: 'imageMaximumGCAge is the maximum age an image can
+                      be unused before it is garbage collected. The default of this
+                      field is "0s", which disables this field--meaning images won''t
+                      be garbage collected based on being unused for too long. Default:
+                      "0s" (disabled)'
+                    type: string
+                  imageMinimumGCAge:
+                    description: 'imageMinimumGCAge is the minimum age for an unused
+                      image before it is garbage collected. Default: "2m"'
+                    type: string
                   imagePullProgressDeadline:
                     description: ImagePullProgressDeadline is the timeout for image
                       pulls If no pulling progress is made before this deadline, the
diff --git a/nodeup/pkg/model/networking/amazon-vpc-routed-eni.go b/nodeup/pkg/model/networking/amazon-vpc-routed-eni.go
deleted file mode 100644
index 3ced7a9eef..0000000000
--- a/nodeup/pkg/model/networking/amazon-vpc-routed-eni.go
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
-Copyright 2024 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.
-*/
-
-package networking
-
-import (
-	"k8s.io/kops/nodeup/pkg/model"
-	"k8s.io/kops/upup/pkg/fi"
-	"k8s.io/kops/upup/pkg/fi/nodeup/nodetasks"
-)
-
-// AmazonVPCRoutedENIBuilder writes the Amazon VPC CNI configuration
-type AmazonVPCRoutedENIBuilder struct {
-	*model.NodeupModelContext
-}
-
-var _ fi.NodeupModelBuilder = &AmazonVPCRoutedENIBuilder{}
-
-// Build is responsible for configuring the network cni
-func (b *AmazonVPCRoutedENIBuilder) Build(c *fi.NodeupModelBuilderContext) error {
-	if b.NodeupConfig.Networking.AmazonVPC == nil {
-		return nil
-	}
-
-	// Running Amazon VPC CNI on Ubuntu 22.04 and later requires setting MACAddressPolicy to `none` (ref: https://github.com/aws/amazon-vpc-cni-k8s/issues/2103 & https://github.com/kubernetes/kops/issues/16255)
-	if b.Distribution.IsUbuntu() && b.Distribution.Version() >= 22.04 {
-		contents := `
-[Match]
-OriginalName=*
-[Link]
-NamePolicy=keep kernel database onboard slot path
-AlternativeNamesPolicy=database onboard slot path
-MACAddressPolicy=none
-`
-
-		// Copy all the relevant entries and replace the one that contains MACAddressPolicy= with MACAddressPolicy=none
-		c.AddTask(&nodetasks.File{
-			Path:            "/etc/systemd/network/99-default.link",
-			Contents:        fi.NewStringResource(contents),
-			Type:            nodetasks.FileType_File,
-			OnChangeExecute: [][]string{{"systemctl", "restart", "systemd-networkd"}},
-		})
-
-	}
-	return nil
-}
diff --git a/pkg/apis/kops/componentconfig.go b/pkg/apis/kops/componentconfig.go
index 8f9bd4d297..ff97458548 100644
--- a/pkg/apis/kops/componentconfig.go
+++ b/pkg/apis/kops/componentconfig.go
@@ -130,6 +130,12 @@ type KubeletConfigSpec struct {
 	// and overrides the default MTU for cases where it cannot be automatically
 	// computed (such as IPSEC).
 	NetworkPluginMTU *int32 `json:"networkPluginMTU,omitempty" flag:"network-plugin-mtu"`
+	// imageMinimumGCAge is the minimum age for an unused image before it is garbage collected. Default: "2m"
+	ImageMinimumGCAge *string `json:"imageMinimumGCAge,omitempty" flag:"image-minimum-gc-age"`
+	// imageMaximumGCAge is the maximum age an image can be unused before it is garbage collected.
+	// The default of this field is "0s", which disables this field--meaning images won't be garbage
+	// collected based on being unused for too long. Default: "0s" (disabled)
+	ImageMaximumGCAge *string `json:"imageMaximumGCAge,omitempty" flag:"image-maximum-gc-age"`
 	// ImageGCHighThresholdPercent is the percent of disk usage after which
 	// image garbage collection is always run.
 	ImageGCHighThresholdPercent *int32 `json:"imageGCHighThresholdPercent,omitempty" flag:"image-gc-high-threshold"`
diff --git a/pkg/apis/kops/v1alpha2/componentconfig.go b/pkg/apis/kops/v1alpha2/componentconfig.go
index d06eda7edd..a45c752620 100644
--- a/pkg/apis/kops/v1alpha2/componentconfig.go
+++ b/pkg/apis/kops/v1alpha2/componentconfig.go
@@ -130,6 +130,12 @@ type KubeletConfigSpec struct {
 	// and overrides the default MTU for cases where it cannot be automatically
 	// computed (such as IPSEC).
 	NetworkPluginMTU *int32 `json:"networkPluginMTU,omitempty" flag:"network-plugin-mtu"`
+	// imageMinimumGCAge is the minimum age for an unused image before it is garbage collected. Default: "2m"
+	ImageMinimumGCAge *string `json:"imageMinimumGCAge,omitempty" flag:"image-minimum-gc-age"`
+	// imageMaximumGCAge is the maximum age an image can be unused before it is garbage collected.
+	// The default of this field is "0s", which disables this field--meaning images won't be garbage
+	// collected based on being unused for too long. Default: "0s" (disabled)
+	ImageMaximumGCAge *string `json:"imageMaximumGCAge,omitempty" flag:"image-maximum-gc-age"`
 	// ImageGCHighThresholdPercent is the percent of disk usage after which
 	// image garbage collection is always run.
 	ImageGCHighThresholdPercent *int32 `json:"imageGCHighThresholdPercent,omitempty" flag:"image-gc-high-threshold"`
diff --git a/pkg/apis/kops/v1alpha2/zz_generated.conversion.go b/pkg/apis/kops/v1alpha2/zz_generated.conversion.go
index 60199892e7..51450a025a 100644
--- a/pkg/apis/kops/v1alpha2/zz_generated.conversion.go
+++ b/pkg/apis/kops/v1alpha2/zz_generated.conversion.go
@@ -5478,6 +5478,8 @@ func autoConvert_v1alpha2_KubeletConfigSpec_To_kops_KubeletConfigSpec(in *Kubele
 	out.NonMasqueradeCIDR = in.NonMasqueradeCIDR
 	out.EnableCustomMetrics = in.EnableCustomMetrics
 	out.NetworkPluginMTU = in.NetworkPluginMTU
+	out.ImageMinimumGCAge = in.ImageMinimumGCAge
+	out.ImageMaximumGCAge = in.ImageMaximumGCAge
 	out.ImageGCHighThresholdPercent = in.ImageGCHighThresholdPercent
 	out.ImageGCLowThresholdPercent = in.ImageGCLowThresholdPercent
 	out.ImagePullProgressDeadline = in.ImagePullProgressDeadline
@@ -5580,6 +5582,8 @@ func autoConvert_kops_KubeletConfigSpec_To_v1alpha2_KubeletConfigSpec(in *kops.K
 	out.NonMasqueradeCIDR = in.NonMasqueradeCIDR
 	out.EnableCustomMetrics = in.EnableCustomMetrics
 	out.NetworkPluginMTU = in.NetworkPluginMTU
+	out.ImageMinimumGCAge = in.ImageMinimumGCAge
+	out.ImageMaximumGCAge = in.ImageMaximumGCAge
 	out.ImageGCHighThresholdPercent = in.ImageGCHighThresholdPercent
 	out.ImageGCLowThresholdPercent = in.ImageGCLowThresholdPercent
 	out.ImagePullProgressDeadline = in.ImagePullProgressDeadline
diff --git a/pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go b/pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go
index bf22be2236..f9a2b2b275 100644
--- a/pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go
+++ b/pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go
@@ -3993,6 +3993,16 @@ func (in *KubeletConfigSpec) DeepCopyInto(out *KubeletConfigSpec) {
 		*out = new(int32)
 		**out = **in
 	}
+	if in.ImageMinimumGCAge != nil {
+		in, out := &in.ImageMinimumGCAge, &out.ImageMinimumGCAge
+		*out = new(string)
+		**out = **in
+	}
+	if in.ImageMaximumGCAge != nil {
+		in, out := &in.ImageMaximumGCAge, &out.ImageMaximumGCAge
+		*out = new(string)
+		**out = **in
+	}
 	if in.ImageGCHighThresholdPercent != nil {
 		in, out := &in.ImageGCHighThresholdPercent, &out.ImageGCHighThresholdPercent
 		*out = new(int32)
diff --git a/pkg/apis/kops/v1alpha3/componentconfig.go b/pkg/apis/kops/v1alpha3/componentconfig.go
index d336b4ead3..a434f2cbda 100644
--- a/pkg/apis/kops/v1alpha3/componentconfig.go
+++ b/pkg/apis/kops/v1alpha3/componentconfig.go
@@ -129,6 +129,12 @@ type KubeletConfigSpec struct {
 	// and overrides the default MTU for cases where it cannot be automatically
 	// computed (such as IPSEC).
 	NetworkPluginMTU *int32 `json:"networkPluginMTU,omitempty" flag:"network-plugin-mtu"`
+	// imageMinimumGCAge is the minimum age for an unused image before it is garbage collected. Default: "2m"
+	ImageMinimumGCAge *string `json:"imageMinimumGCAge,omitempty" flag:"image-minimum-gc-age"`
+	// imageMaximumGCAge is the maximum age an image can be unused before it is garbage collected.
+	// The default of this field is "0s", which disables this field--meaning images won't be garbage
+	// collected based on being unused for too long. Default: "0s" (disabled)
+	ImageMaximumGCAge *string `json:"imageMaximumGCAge,omitempty" flag:"image-maximum-gc-age"`
 	// ImageGCHighThresholdPercent is the percent of disk usage after which
 	// image garbage collection is always run.
 	ImageGCHighThresholdPercent *int32 `json:"imageGCHighThresholdPercent,omitempty" flag:"image-gc-high-threshold"`
diff --git a/pkg/apis/kops/v1alpha3/zz_generated.conversion.go b/pkg/apis/kops/v1alpha3/zz_generated.conversion.go
index 5aba9f361e..81af024cb2 100644
--- a/pkg/apis/kops/v1alpha3/zz_generated.conversion.go
+++ b/pkg/apis/kops/v1alpha3/zz_generated.conversion.go
@@ -5871,6 +5871,8 @@ func autoConvert_v1alpha3_KubeletConfigSpec_To_kops_KubeletConfigSpec(in *Kubele
 	out.NonMasqueradeCIDR = in.NonMasqueradeCIDR
 	out.EnableCustomMetrics = in.EnableCustomMetrics
 	out.NetworkPluginMTU = in.NetworkPluginMTU
+	out.ImageMinimumGCAge = in.ImageMinimumGCAge
+	out.ImageMaximumGCAge = in.ImageMaximumGCAge
 	out.ImageGCHighThresholdPercent = in.ImageGCHighThresholdPercent
 	out.ImageGCLowThresholdPercent = in.ImageGCLowThresholdPercent
 	out.ImagePullProgressDeadline = in.ImagePullProgressDeadline
@@ -5973,6 +5975,8 @@ func autoConvert_kops_KubeletConfigSpec_To_v1alpha3_KubeletConfigSpec(in *kops.K
 	out.NonMasqueradeCIDR = in.NonMasqueradeCIDR
 	out.EnableCustomMetrics = in.EnableCustomMetrics
 	out.NetworkPluginMTU = in.NetworkPluginMTU
+	out.ImageMinimumGCAge = in.ImageMinimumGCAge
+	out.ImageMaximumGCAge = in.ImageMaximumGCAge
 	out.ImageGCHighThresholdPercent = in.ImageGCHighThresholdPercent
 	out.ImageGCLowThresholdPercent = in.ImageGCLowThresholdPercent
 	out.ImagePullProgressDeadline = in.ImagePullProgressDeadline
diff --git a/pkg/apis/kops/v1alpha3/zz_generated.deepcopy.go b/pkg/apis/kops/v1alpha3/zz_generated.deepcopy.go
index 7aa4bf0e07..9d24085e66 100644
--- a/pkg/apis/kops/v1alpha3/zz_generated.deepcopy.go
+++ b/pkg/apis/kops/v1alpha3/zz_generated.deepcopy.go
@@ -3967,6 +3967,16 @@ func (in *KubeletConfigSpec) DeepCopyInto(out *KubeletConfigSpec) {
 		*out = new(int32)
 		**out = **in
 	}
+	if in.ImageMinimumGCAge != nil {
+		in, out := &in.ImageMinimumGCAge, &out.ImageMinimumGCAge
+		*out = new(string)
+		**out = **in
+	}
+	if in.ImageMaximumGCAge != nil {
+		in, out := &in.ImageMaximumGCAge, &out.ImageMaximumGCAge
+		*out = new(string)
+		**out = **in
+	}
 	if in.ImageGCHighThresholdPercent != nil {
 		in, out := &in.ImageGCHighThresholdPercent, &out.ImageGCHighThresholdPercent
 		*out = new(int32)
diff --git a/pkg/apis/kops/zz_generated.deepcopy.go b/pkg/apis/kops/zz_generated.deepcopy.go
index ecadcf9a3e..2f2b658e16 100644
--- a/pkg/apis/kops/zz_generated.deepcopy.go
+++ b/pkg/apis/kops/zz_generated.deepcopy.go
@@ -4070,6 +4070,16 @@ func (in *KubeletConfigSpec) DeepCopyInto(out *KubeletConfigSpec) {
 		*out = new(int32)
 		**out = **in
 	}
+	if in.ImageMinimumGCAge != nil {
+		in, out := &in.ImageMinimumGCAge, &out.ImageMinimumGCAge
+		*out = new(string)
+		**out = **in
+	}
+	if in.ImageMaximumGCAge != nil {
+		in, out := &in.ImageMaximumGCAge, &out.ImageMaximumGCAge
+		*out = new(string)
+		**out = **in
+	}
 	if in.ImageGCHighThresholdPercent != nil {
 		in, out := &in.ImageGCHighThresholdPercent, &out.ImageGCHighThresholdPercent
 		*out = new(int32)
diff --git a/upup/models/cloudup/resources/addons/aws-load-balancer-controller.addons.k8s.io/k8s-1.19.yaml.template b/upup/models/cloudup/resources/addons/aws-load-balancer-controller.addons.k8s.io/k8s-1.19.yaml.template
index 14d25f3b04..d287dfb24e 100644
--- a/upup/models/cloudup/resources/addons/aws-load-balancer-controller.addons.k8s.io/k8s-1.19.yaml.template
+++ b/upup/models/cloudup/resources/addons/aws-load-balancer-controller.addons.k8s.io/k8s-1.19.yaml.template
@@ -1,5 +1,5 @@
 {{- with .CloudProvider.AWS.LoadBalancerController }}
-# sourced from https://github.com/kubernetes-sigs/aws-load-balancer-controller/releases/download/v2.7.0/v2_7_0_full.yaml
+# sourced from https://github.com/kubernetes-sigs/aws-load-balancer-controller/releases/download/v2.6.2/v2_6_2_full.yaml
 apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
@@ -895,7 +895,7 @@ spec:
             fieldRef:
               apiVersion: v1
               fieldPath: spec.nodeName
-        image: public.ecr.aws/eks/aws-load-balancer-controller:{{ or .Version "v2.7.0" }}
+        image: public.ecr.aws/eks/aws-load-balancer-controller:{{ or .Version "v2.6.2" }}
         livenessProbe:
           failureThreshold: 2
           httpGet:
@@ -1149,13 +1149,12 @@ webhooks:
     - ingresses
   sideEffects: None
 ---
-# sourced from https://github.com/kubernetes-sigs/aws-load-balancer-controller/releases/download/v2.7.0/v2_7_0_ingclass.yaml
 apiVersion: elbv2.k8s.aws/v1beta1
 kind: IngressClassParams
 metadata:
   labels:
     app.kubernetes.io/name: aws-load-balancer-controller
-  name: alb
+  name: alb 
 ---
 apiVersion: networking.k8s.io/v1
 kind: IngressClass
@@ -1171,6 +1170,7 @@ spec:
     name: alb
 ---
 apiVersion: policy/v1
+
 kind: PodDisruptionBudget
 metadata:
   name: aws-load-balancer-controller
diff --git a/upup/pkg/fi/nodeup/command.go b/upup/pkg/fi/nodeup/command.go
index f76eaea851..3c04476ba6 100644
--- a/upup/pkg/fi/nodeup/command.go
+++ b/upup/pkg/fi/nodeup/command.go
@@ -318,7 +318,6 @@ func (c *NodeUpCommand) Run(out io.Writer) error {
 	loader.Builders = append(loader.Builders, &networking.CommonBuilder{NodeupModelContext: modelContext})
 	loader.Builders = append(loader.Builders, &networking.CalicoBuilder{NodeupModelContext: modelContext})
 	loader.Builders = append(loader.Builders, &networking.CiliumBuilder{NodeupModelContext: modelContext})
-	loader.Builders = append(loader.Builders, &networking.AmazonVPCRoutedENIBuilder{NodeupModelContext: modelContext})
 	loader.Builders = append(loader.Builders, &networking.KuberouterBuilder{NodeupModelContext: modelContext})
 
 	loader.Builders = append(loader.Builders, &model.BootstrapClientBuilder{NodeupModelContext: modelContext})


Test patch:
diff --git a/tests/integration/update_cluster/aws-lb-controller/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content b/tests/integration/update_cluster/aws-lb-controller/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content
index f4f0dd398f..e34d5de691 100644
--- a/tests/integration/update_cluster/aws-lb-controller/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content
+++ b/tests/integration/update_cluster/aws-lb-controller/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content
@@ -929,7 +929,7 @@ spec:
           value: arn:aws-test:iam::123456789012:role/aws-load-balancer-controller.kube-system.sa.minimal.example.com
         - name: AWS_WEB_IDENTITY_TOKEN_FILE
           value: /var/run/secrets/amazonaws.com/token
-        image: public.ecr.aws/eks/aws-load-balancer-controller:v2.7.0
+        image: public.ecr.aws/eks/aws-load-balancer-controller:v2.6.2
         livenessProbe:
           failureThreshold: 2
           httpGet:
diff --git a/tests/integration/update_cluster/aws-lb-controller/data/aws_s3_object_minimal.example.com-addons-bootstrap_content b/tests/integration/update_cluster/aws-lb-controller/data/aws_s3_object_minimal.example.com-addons-bootstrap_content
index 9ccc6fe85a..2db1004044 100644
--- a/tests/integration/update_cluster/aws-lb-controller/data/aws_s3_object_minimal.example.com-addons-bootstrap_content
+++ b/tests/integration/update_cluster/aws-lb-controller/data/aws_s3_object_minimal.example.com-addons-bootstrap_content
@@ -148,7 +148,7 @@ spec:
     version: 9.99.0
   - id: k8s-1.19
     manifest: aws-load-balancer-controller.addons.k8s.io/k8s-1.19.yaml
-    manifestHash: 866b908b73a7c0083d20b055aefbc9745d3076fd5f5b5ae7e64e6bd2db3e7942
+    manifestHash: 1c7618e2ac4639ab78b8cab895782fc62d521f4fd208b4bff4a0558fa771afc3
     name: aws-load-balancer-controller.addons.k8s.io
     needsPKI: true
     selector:
diff --git a/tests/integration/update_cluster/many-addons-ccm-irsa/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content b/tests/integration/update_cluster/many-addons-ccm-irsa/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content
index f4f0dd398f..e34d5de691 100644
--- a/tests/integration/update_cluster/many-addons-ccm-irsa/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content
+++ b/tests/integration/update_cluster/many-addons-ccm-irsa/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content
@@ -929,7 +929,7 @@ spec:
           value: arn:aws-test:iam::123456789012:role/aws-load-balancer-controller.kube-system.sa.minimal.example.com
         - name: AWS_WEB_IDENTITY_TOKEN_FILE
           value: /var/run/secrets/amazonaws.com/token
-        image: public.ecr.aws/eks/aws-load-balancer-controller:v2.7.0
+        image: public.ecr.aws/eks/aws-load-balancer-controller:v2.6.2
         livenessProbe:
           failureThreshold: 2
           httpGet:
diff --git a/tests/integration/update_cluster/many-addons-ccm-irsa/data/aws_s3_object_minimal.example.com-addons-bootstrap_content b/tests/integration/update_cluster/many-addons-ccm-irsa/data/aws_s3_object_minimal.example.com-addons-bootstrap_content
index 991e5f2315..6c6093f044 100644
--- a/tests/integration/update_cluster/many-addons-ccm-irsa/data/aws_s3_object_minimal.example.com-addons-bootstrap_content
+++ b/tests/integration/update_cluster/many-addons-ccm-irsa/data/aws_s3_object_minimal.example.com-addons-bootstrap_content
@@ -163,7 +163,7 @@ spec:
     version: 9.99.0
   - id: k8s-1.19
     manifest: aws-load-balancer-controller.addons.k8s.io/k8s-1.19.yaml
-    manifestHash: 866b908b73a7c0083d20b055aefbc9745d3076fd5f5b5ae7e64e6bd2db3e7942
+    manifestHash: 1c7618e2ac4639ab78b8cab895782fc62d521f4fd208b4bff4a0558fa771afc3
     name: aws-load-balancer-controller.addons.k8s.io
     needsPKI: true
     selector:
diff --git a/tests/integration/update_cluster/many-addons-ccm-irsa24/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content b/tests/integration/update_cluster/many-addons-ccm-irsa24/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content
index f4f0dd398f..e34d5de691 100644
--- a/tests/integration/update_cluster/many-addons-ccm-irsa24/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content
+++ b/tests/integration/update_cluster/many-addons-ccm-irsa24/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content
@@ -929,7 +929,7 @@ spec:
           value: arn:aws-test:iam::123456789012:role/aws-load-balancer-controller.kube-system.sa.minimal.example.com
         - name: AWS_WEB_IDENTITY_TOKEN_FILE
           value: /var/run/secrets/amazonaws.com/token
-        image: public.ecr.aws/eks/aws-load-balancer-controller:v2.7.0
+        image: public.ecr.aws/eks/aws-load-balancer-controller:v2.6.2
         livenessProbe:
           failureThreshold: 2
           httpGet:
diff --git a/tests/integration/update_cluster/many-addons-ccm-irsa24/data/aws_s3_object_minimal.example.com-addons-bootstrap_content b/tests/integration/update_cluster/many-addons-ccm-irsa24/data/aws_s3_object_minimal.example.com-addons-bootstrap_content
index dfa1dd5de0..7e0ef0977b 100644
--- a/tests/integration/update_cluster/many-addons-ccm-irsa24/data/aws_s3_object_minimal.example.com-addons-bootstrap_content
+++ b/tests/integration/update_cluster/many-addons-ccm-irsa24/data/aws_s3_object_minimal.example.com-addons-bootstrap_content
@@ -170,7 +170,7 @@ spec:
     version: 9.99.0
   - id: k8s-1.19
     manifest: aws-load-balancer-controller.addons.k8s.io/k8s-1.19.yaml
-    manifestHash: 866b908b73a7c0083d20b055aefbc9745d3076fd5f5b5ae7e64e6bd2db3e7942
+    manifestHash: 1c7618e2ac4639ab78b8cab895782fc62d521f4fd208b4bff4a0558fa771afc3
     name: aws-load-balancer-controller.addons.k8s.io
     needsPKI: true
     selector:
diff --git a/tests/integration/update_cluster/many-addons-ccm-irsa25/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content b/tests/integration/update_cluster/many-addons-ccm-irsa25/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content
index f4f0dd398f..e34d5de691 100644
--- a/tests/integration/update_cluster/many-addons-ccm-irsa25/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content
+++ b/tests/integration/update_cluster/many-addons-ccm-irsa25/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content
@@ -929,7 +929,7 @@ spec:
           value: arn:aws-test:iam::123456789012:role/aws-load-balancer-controller.kube-system.sa.minimal.example.com
         - name: AWS_WEB_IDENTITY_TOKEN_FILE
           value: /var/run/secrets/amazonaws.com/token
-        image: public.ecr.aws/eks/aws-load-balancer-controller:v2.7.0
+        image: public.ecr.aws/eks/aws-load-balancer-controller:v2.6.2
         livenessProbe:
           failureThreshold: 2
           httpGet:
diff --git a/tests/integration/update_cluster/many-addons-ccm-irsa25/data/aws_s3_object_minimal.example.com-addons-bootstrap_content b/tests/integration/update_cluster/many-addons-ccm-irsa25/data/aws_s3_object_minimal.example.com-addons-bootstrap_content
index 87a06b7fdd..6189945e6e 100644
--- a/tests/integration/update_cluster/many-addons-ccm-irsa25/data/aws_s3_object_minimal.example.com-addons-bootstrap_content
+++ b/tests/integration/update_cluster/many-addons-ccm-irsa25/data/aws_s3_object_minimal.example.com-addons-bootstrap_content
@@ -170,7 +170,7 @@ spec:
     version: 9.99.0
   - id: k8s-1.19
     manifest: aws-load-balancer-controller.addons.k8s.io/k8s-1.19.yaml
-    manifestHash: 866b908b73a7c0083d20b055aefbc9745d3076fd5f5b5ae7e64e6bd2db3e7942
+    manifestHash: 1c7618e2ac4639ab78b8cab895782fc62d521f4fd208b4bff4a0558fa771afc3
     name: aws-load-balancer-controller.addons.k8s.io
     needsPKI: true
     selector:
diff --git a/tests/integration/update_cluster/many-addons-ccm-irsa26/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content b/tests/integration/update_cluster/many-addons-ccm-irsa26/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content
index f4f0dd398f..e34d5de691 100644
--- a/tests/integration/update_cluster/many-addons-ccm-irsa26/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content
+++ b/tests/integration/update_cluster/many-addons-ccm-irsa26/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content
@@ -929,7 +929,7 @@ spec:
           value: arn:aws-test:iam::123456789012:role/aws-load-balancer-controller.kube-system.sa.minimal.example.com
         - name: AWS_WEB_IDENTITY_TOKEN_FILE
           value: /var/run/secrets/amazonaws.com/token
-        image: public.ecr.aws/eks/aws-load-balancer-controller:v2.7.0
+        image: public.ecr.aws/eks/aws-load-balancer-controller:v2.6.2
         livenessProbe:
           failureThreshold: 2
           httpGet:
diff --git a/tests/integration/update_cluster/many-addons-ccm-irsa26/data/aws_s3_object_minimal.example.com-addons-bootstrap_content b/tests/integration/update_cluster/many-addons-ccm-irsa26/data/aws_s3_object_minimal.example.com-addons-bootstrap_content
index e9af399e00..56c722144a 100644
--- a/tests/integration/update_cluster/many-addons-ccm-irsa26/data/aws_s3_object_minimal.example.com-addons-bootstrap_content
+++ b/tests/integration/update_cluster/many-addons-ccm-irsa26/data/aws_s3_object_minimal.example.com-addons-bootstrap_content
@@ -171,7 +171,7 @@ spec:
     version: 9.99.0
   - id: k8s-1.19
     manifest: aws-load-balancer-controller.addons.k8s.io/k8s-1.19.yaml
-    manifestHash: 866b908b73a7c0083d20b055aefbc9745d3076fd5f5b5ae7e64e6bd2db3e7942
+    manifestHash: 1c7618e2ac4639ab78b8cab895782fc62d521f4fd208b4bff4a0558fa771afc3
     name: aws-load-balancer-controller.addons.k8s.io
     needsPKI: true
     selector:
diff --git a/tests/integration/update_cluster/many-addons-ccm/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content b/tests/integration/update_cluster/many-addons-ccm/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content
index af9e6cad1b..4293a17bb2 100644
--- a/tests/integration/update_cluster/many-addons-ccm/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content
+++ b/tests/integration/update_cluster/many-addons-ccm/data/aws_s3_object_minimal.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content
@@ -939,7 +939,7 @@ spec:
             fieldRef:
               apiVersion: v1
               fieldPath: spec.nodeName
-        image: public.ecr.aws/eks/aws-load-balancer-controller:v2.7.0
+        image: public.ecr.aws/eks/aws-load-balancer-controller:v2.6.2
         livenessProbe:
           failureThreshold: 2
           httpGet:
diff --git a/tests/integration/update_cluster/many-addons-ccm/data/aws_s3_object_minimal.example.com-addons-bootstrap_content b/tests/integration/update_cluster/many-addons-ccm/data/aws_s3_object_minimal.example.com-addons-bootstrap_content
index 0d87dd1b69..ad7ed460fb 100644
--- a/tests/integration/update_cluster/many-addons-ccm/data/aws_s3_object_minimal.example.com-addons-bootstrap_content
+++ b/tests/integration/update_cluster/many-addons-ccm/data/aws_s3_object_minimal.example.com-addons-bootstrap_content
@@ -163,7 +163,7 @@ spec:
     version: 9.99.0
   - id: k8s-1.19
     manifest: aws-load-balancer-controller.addons.k8s.io/k8s-1.19.yaml
-    manifestHash: 7d093be57b67cd3fc018a8e251e2db73e72b6d4592d645a3be5503a6bebe0d52
+    manifestHash: 4b7e10379beabe347fe4d72ddfc00ae77daab278c65251f5a8a56a6e91c2a907
     name: aws-load-balancer-controller.addons.k8s.io
     needsPKI: true
     selector:
diff --git a/tests/integration/update_cluster/many-addons/data/aws_s3_object_many-addons.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content b/tests/integration/update_cluster/many-addons/data/aws_s3_object_many-addons.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content
index a969ae20ff..aef25a991c 100644
--- a/tests/integration/update_cluster/many-addons/data/aws_s3_object_many-addons.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content
+++ b/tests/integration/update_cluster/many-addons/data/aws_s3_object_many-addons.example.com-addons-aws-load-balancer-controller.addons.k8s.io-k8s-1.19_content
@@ -939,7 +939,7 @@ spec:
             fieldRef:
               apiVersion: v1
               fieldPath: spec.nodeName
-        image: public.ecr.aws/eks/aws-load-balancer-controller:v2.7.0
+        image: public.ecr.aws/eks/aws-load-balancer-controller:v2.6.2
         livenessProbe:
           failureThreshold: 2
           httpGet:
diff --git a/tests/integration/update_cluster/many-addons/data/aws_s3_object_many-addons.example.com-addons-bootstrap_content b/tests/integration/update_cluster/many-addons/data/aws_s3_object_many-addons.example.com-addons-bootstrap_content
index d6172e33f3..1f6d861d00 100644
--- a/tests/integration/update_cluster/many-addons/data/aws_s3_object_many-addons.example.com-addons-bootstrap_content
+++ b/tests/integration/update_cluster/many-addons/data/aws_s3_object_many-addons.example.com-addons-bootstrap_content
@@ -163,7 +163,7 @@ spec:
     version: 9.99.0
   - id: k8s-1.19
     manifest: aws-load-balancer-controller.addons.k8s.io/k8s-1.19.yaml
-    manifestHash: b92c8546fc7af32373da80f802287a5c6a5fc491e074c729d4e323f8441c5e7c
+    manifestHash: ea17759bdf2e9ace58d6cd23a0f5f0697736eef8e52a25a30c3bbef8b77aaa48
     name: aws-load-balancer-controller.addons.k8s.io
     needsPKI: true
     selector: