Repository: kubernetes/minikube
Pull request #19715 (2024-09-27 20:34:07)

testing: Add defer to disable addon to start of each addon test
https://github.com/kubernetes/minikube/issues/19714

Add defer to disable addon to start of each addon test. In relation to https://github.com/kubernetes/minikube/issues/19714, this will prevent GCP-Auth addon mock issue from affecting the registry test.

This PR should fix the registry test for all environments.


Patch:
diff --git a/.github/workflows/functional_verified.yml b/.github/workflows/functional_verified.yml
index 5c2ae6f6e..d56666649 100644
--- a/.github/workflows/functional_verified.yml
+++ b/.github/workflows/functional_verified.yml
@@ -97,7 +97,7 @@ jobs:
       - name: Install gopogh
         shell: bash
         run: |
-          go install github.com/medyagh/gopogh/cmd/gopogh@v0.28.0
+          go install github.com/medyagh/gopogh/cmd/gopogh@v0.29.0
 
       - name: Docker Info
         shell: bash
diff --git a/.github/workflows/hide-minikube-bot-comments.yml b/.github/workflows/hide-minikube-bot-comments.yml
index e8b491339..c3d16a030 100644
--- a/.github/workflows/hide-minikube-bot-comments.yml
+++ b/.github/workflows/hide-minikube-bot-comments.yml
@@ -8,6 +8,6 @@ jobs:
     if: ${{ github.event.issue.pull_request }}
     runs-on: ubuntu-22.04
     steps:
-      - uses: spowelljr/hide-minikube-bot-comments@7d9688dd9b7fce605c24be174110c344728160de
+      - uses: spowelljr/hide-minikube-bot-comments@6ef419ab40a17cf0bdc1f98f2442bf19b72d911d
         with:
           token: ${{ secrets.MINIKUBE_BOT_PAT }}
diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml
index 206e3fa5f..dbcf9fe98 100644
--- a/.github/workflows/master.yml
+++ b/.github/workflows/master.yml
@@ -135,7 +135,7 @@ jobs:
       - name: Install gopogh
         shell: bash
         run: |
-          go install github.com/medyagh/gopogh/cmd/gopogh@v0.28.0
+          go install github.com/medyagh/gopogh/cmd/gopogh@v0.29.0
       - name: Download Binaries
         uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16
         with:
@@ -235,7 +235,7 @@ jobs:
       - name: Install gopogh
         shell: bash
         run: |
-          go install github.com/medyagh/gopogh/cmd/gopogh@v0.28.0
+          go install github.com/medyagh/gopogh/cmd/gopogh@v0.29.0
       - name: Download Binaries
         uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16
         with:
@@ -353,7 +353,7 @@ jobs:
       - name: Install gopogh
         shell: bash
         run: |
-          go install github.com/medyagh/gopogh/cmd/gopogh@v0.28.0
+          go install github.com/medyagh/gopogh/cmd/gopogh@v0.29.0
       - name: Download Binaries
         uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16
         with:
@@ -458,7 +458,7 @@ jobs:
       - name: Install gopogh
         shell: bash
         run: |
-          go install github.com/medyagh/gopogh/cmd/gopogh@v0.28.0
+          go install github.com/medyagh/gopogh/cmd/gopogh@v0.29.0
       - name: Download Binaries
         uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16
         with:
@@ -578,7 +578,7 @@ jobs:
       - name: Install gopogh
         shell: bash
         run: |
-          go install github.com/medyagh/gopogh/cmd/gopogh@v0.28.0
+          go install github.com/medyagh/gopogh/cmd/gopogh@v0.29.0
       - name: Set fs.protected_regular
         shell: bash
         run: |
diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
index a41f6349f..d16c47950 100644
--- a/.github/workflows/pr.yml
+++ b/.github/workflows/pr.yml
@@ -133,7 +133,7 @@ jobs:
       - name: Install gopogh
         shell: bash
         run: |
-          go install github.com/medyagh/gopogh/cmd/gopogh@v0.28.0
+          go install github.com/medyagh/gopogh/cmd/gopogh@v0.29.0
       - name: Download Binaries
         uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16
         with:
@@ -233,7 +233,7 @@ jobs:
       - name: Install gopogh
         shell: bash
         run: |
-          go install github.com/medyagh/gopogh/cmd/gopogh@v0.28.0
+          go install github.com/medyagh/gopogh/cmd/gopogh@v0.29.0
       - name: Download Binaries
         uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16
         with:
@@ -351,7 +351,7 @@ jobs:
       - name: Install gopogh
         shell: bash
         run: |
-          go install github.com/medyagh/gopogh/cmd/gopogh@v0.28.0
+          go install github.com/medyagh/gopogh/cmd/gopogh@v0.29.0
       - name: Download Binaries
         uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16
         with:
@@ -456,7 +456,7 @@ jobs:
       - name: Install gopogh
         shell: bash
         run: |
-          go install github.com/medyagh/gopogh/cmd/gopogh@v0.28.0
+          go install github.com/medyagh/gopogh/cmd/gopogh@v0.29.0
       - name: Download Binaries
         uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16
         with:
@@ -476,7 +476,7 @@ jobs:
           sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld
           MINIKUBE_HOME=$(pwd)/testhome ./minikube-linux-amd64 delete --all --purge
           START_TIME=$(date -u +%s)
-          KUBECONFIG=$(pwd)/testhome/kubeconfig MINIKUBE_HOME=$(pwd)/testhome ./e2e-linux-amd64 -minikube-start-args=--vm-driver=podman -v=6 --alsologtostderr -test.run TestFunctional -test.timeout=15m -test.v -timeout-multiplier=1.5 -binary=./minikube-linux-amd64 2>&1 | tee ./report/testout.txt
+          KUBECONFIG=$(pwd)/testhome/kubeconfig MINIKUBE_HOME=$(pwd)/testhome ./e2e-linux-amd64 -minikube-start-args="--vm-driver=podman -v=6 --alsologtostderr" -test.run TestFunctional -test.timeout=15m -test.v -timeout-multiplier=1.5 -binary=./minikube-linux-amd64 2>&1 | tee ./report/testout.txt
           END_TIME=$(date -u +%s)
           TIME_ELAPSED=$(($END_TIME-$START_TIME))
           min=$((${TIME_ELAPSED}/60))
@@ -576,7 +576,7 @@ jobs:
       - name: Install gopogh
         shell: bash
         run: |
-          go install github.com/medyagh/gopogh/cmd/gopogh@v0.28.0
+          go install github.com/medyagh/gopogh/cmd/gopogh@v0.29.0
       - name: Set fs.protected_regular
         shell: bash
         run: |
diff --git a/.github/workflows/update-kube-vip-version.yml b/.github/workflows/update-kube-vip-version.yml
new file mode 100644
index 000000000..bf917f8fb
--- /dev/null
+++ b/.github/workflows/update-kube-vip-version.yml
@@ -0,0 +1,48 @@
+name: "update-kube-vip-version"
+on:
+  workflow_dispatch:
+  schedule:
+    # every Monday at around 3 am pacific/10 am UTC
+    - cron: "0 10 * * 1"
+env:
+  GOPROXY: https://proxy.golang.org
+  GO_VERSION: '1.23.0'
+permissions:
+  contents: read
+
+jobs:
+  bump-kube-vip-version:
+    runs-on: ubuntu-22.04
+    steps:
+      - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
+      - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32
+        with:
+          go-version: ${{env.GO_VERSION}}
+      - name: Bump kube-vip version
+        id: bumpKubeVip
+        run: |
+          echo "OLD_VERSION=$(DEP=kube-vip make get-dependency-version)" >> "$GITHUB_OUTPUT"
+          make update-kube-vip-version
+          echo "NEW_VERSION=$(DEP=kube-vip make get-dependency-version)" >> "$GITHUB_OUTPUT"
+          # The following is to support multiline with GITHUB_OUTPUT, see https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings
+          echo "changes<<EOF" >> "$GITHUB_OUTPUT"
+          echo "$(git status --porcelain)" >> "$GITHUB_OUTPUT"
+          echo "EOF" >> "$GITHUB_OUTPUT"
+      - name: Create PR
+        if: ${{ steps.bumpKubeVip.outputs.changes != '' }}
+        uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f
+        with:
+          token: ${{ secrets.MINIKUBE_BOT_PAT }}
+          commit-message: 'HA (multi-control plane): Update kube-vip from ${{ steps.bumpKubeVip.outputs.OLD_VERSION }} to ${{ steps.bumpKubeVip.outputs.NEW_VERSION }}'
+          committer: minikube-bot <minikube-bot@google.com>
+          author: minikube-bot <minikube-bot@google.com>
+          branch: auto_bump_kube_vip_version
+          push-to-fork: minikube-bot/minikube
+          base: master
+          delete-branch: true
+          title: 'HA (multi-control plane): Update kube-vip from ${{ steps.bumpKubeVip.outputs.OLD_VERSION }} to ${{ steps.bumpKubeVip.outputs.NEW_VERSION }}'
+          labels: ok-to-test
+          body: |
+            The kube-vip project released a [new version](https://github.com/kube-vip/kube-vip)
+
+            This PR was auto-generated by `make update-kube-vip-version` using [update-kube-vip-version.yml](https://github.com/kubernetes/minikube/tree/master/.github/workflows/update-kube-vip-version.yml) CI Workflow.
diff --git a/Makefile b/Makefile
index 9ef1cb211..15d916f70 100644
--- a/Makefile
+++ b/Makefile
@@ -1255,3 +1255,8 @@ get-dependency-version:
 .PHONY: generate-licenses
 generate-licenses:
 	./hack/generate_licenses.sh
+
+.PHONY: update-kube-vip-version
+update-kube-vip-version:
+	(cd hack/update/kube_vip_version && \
+	 go run update_kube_vip_version.go)
diff --git a/cmd/minikube/cmd/docker-env.go b/cmd/minikube/cmd/docker-env.go
index 60aca90b1..8a376ea80 100644
--- a/cmd/minikube/cmd/docker-env.go
+++ b/cmd/minikube/cmd/docker-env.go
@@ -25,7 +25,6 @@ import (
 	"net/url"
 	"os"
 	"os/exec"
-	"runtime"
 	"strconv"
 	"strings"
 	"time"
@@ -309,7 +308,6 @@ docker-cli install instructions: https://minikube.sigs.k8s.io/docs/tutorials/doc
 			exit.Message(reason.EnvMultiConflict, `The docker-env command is incompatible with multi-node clusters. Use the 'registry' add-on: https://minikube.sigs.k8s.io/docs/handbook/registry/`)
 		}
 		cr := co.Config.KubernetesConfig.ContainerRuntime
-		// nerdctld supports amd64 and arm64
 		if err := dockerEnvSupported(cr, driverName); err != nil {
 			exit.Message(reason.Usage, err.Error())
 		}
@@ -674,9 +672,6 @@ func tryDockerConnectivity(bin string, ec DockerEnvConfig) ([]byte, error) {
 }
 
 func dockerEnvSupported(containerRuntime, driverName string) error {
-	if runtime.GOARCH != "amd64" && runtime.GOARCH != "arm64" {
-		return fmt.Errorf("the docker-env command only supports amd64 & arm64 architectures")
-	}
 	if containerRuntime != constants.Docker && containerRuntime != constants.Containerd {
 		return fmt.Errorf("the docker-env command only supports the docker and containerd runtimes")
 	}
diff --git a/deploy/addons/inspektor-gadget/ig-configmap.yaml b/deploy/addons/inspektor-gadget/ig-configmap.yaml
new file mode 100644
index 000000000..444bf5b98
--- /dev/null
+++ b/deploy/addons/inspektor-gadget/ig-configmap.yaml
@@ -0,0 +1,26 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: gadget
+  namespace: gadget
+data:
+  config.yaml: |-
+    hook-mode: auto
+    fallback-pod-informer: true
+    events-buffer-length: 16384
+    containerd-socketpath: /run/containerd/containerd.sock
+    crio-socketpath: /run/crio/crio.sock
+    docker-socketpath: /run/docker.sock
+    podman-socketpath: /run/podman/podman.sock
+    operator:
+      oci:
+        verify-image: true
+        public-keys:
+          - |
+            -----BEGIN PUBLIC KEY-----
+            MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoDOC0gYSxZTopenGmX3ZFvQ1DSfh
+            Ir4EKRt5jC+mXaJ7c7J+oREskYMn/SfZdRHNSOjLTZUMDm60zpXGhkFecg==
+            -----END PUBLIC KEY-----
+        allowed-gadgets:
+          []
+        disallow-pulling: false
diff --git a/deploy/addons/inspektor-gadget/ig-daemonset.yaml.tmpl b/deploy/addons/inspektor-gadget/ig-daemonset.yaml.tmpl
index 77141e7fc..4f41c6f95 100644
--- a/deploy/addons/inspektor-gadget/ig-daemonset.yaml.tmpl
+++ b/deploy/addons/inspektor-gadget/ig-daemonset.yaml.tmpl
@@ -173,7 +173,15 @@ spec:
           mountPath: /sys/fs/cgroup
         - name: bpffs
           mountPath: /sys/fs/bpf
-      tolerations:
+        # We need to add a dedicated volume to store OCI image otherwise it
+        # will fail as the container root filesystem is read only.
+        # For this, we use an emptyDir without size limit.
+        - mountPath: /var/lib/ig
+          name: oci
+        - mountPath: /etc/ig
+          name: config
+          readOnly: true
+      tolerations: 
       - effect: NoSchedule
         operator: Exists
       - effect: NoExecute
@@ -196,4 +204,10 @@ spec:
           path: /sys/fs/bpf
       - name: debugfs
         hostPath:
-          path: /sys/kernel/debug 
\ No newline at end of file
+          path: /sys/kernel/debug
+      - name: oci
+        emptyDir:
+      - name: config
+        configMap:
+          name: gadget
+          defaultMode: 0o400
diff --git a/hack/jenkins/common.ps1 b/hack/jenkins/common.ps1
index 63265394c..98620335d 100644
--- a/hack/jenkins/common.ps1
+++ b/hack/jenkins/common.ps1
@@ -68,7 +68,7 @@ gsutil.cmd -m cp -r gs://minikube-builds/$env:MINIKUBE_LOCATION/installers/check
 ./out/check_install_golang.ps1
 
 # Download gopogh and gotestsum
-go install github.com/medyagh/gopogh/cmd/gopogh@v0.28.0
+go install github.com/medyagh/gopogh/cmd/gopogh@v0.29.0
 go install gotest.tools/gotestsum@v1.12.0
 # temporary: remove the old install of gopogh & gotestsum as it's taking priority over our current install, preventing updating
 if (Test-Path "C:\Go") {
diff --git a/hack/jenkins/installers/check_install_gopogh.sh b/hack/jenkins/installers/check_install_gopogh.sh
index 987e6a3fb..dcbc688cc 100755
--- a/hack/jenkins/installers/check_install_gopogh.sh
+++ b/hack/jenkins/installers/check_install_gopogh.sh
@@ -22,4 +22,4 @@ set -eux -o pipefail
 # temporary: remove the old install of gopogh as it's taking priority over our current install, preventing updating
 sudo rm -f /usr/local/bin/gopogh
 
-go install github.com/medyagh/gopogh/cmd/gopogh@v0.28.0
+go install github.com/medyagh/gopogh/cmd/gopogh@v0.29.0
diff --git a/hack/kicbase_version/os-package-list.txt b/hack/kicbase_version/os-package-list.txt
index 61913f5c0..b528c69e6 100644
--- a/hack/kicbase_version/os-package-list.txt
+++ b/hack/kicbase_version/os-package-list.txt
@@ -12,7 +12,7 @@ ii  bind9-dnsutils                  1:9.18.28-0ubuntu0.22.04.1              amd6
 ii  bind9-host                      1:9.18.28-0ubuntu0.22.04.1              amd64        DNS Lookup Utility
 ii  bind9-libs:amd64                1:9.18.28-0ubuntu0.22.04.1              amd64        Shared Libraries used by BIND 9
 ii  bsdutils                        1:2.37.2-4ubuntu3.4                     amd64        basic utilities from 4.4BSD-Lite
-ii  ca-certificates                 20230311ubuntu0.22.04.1                 all          Common CA certificates
+ii  ca-certificates                 20240203~22.04.1                        all          Common CA certificates
 ii  catatonit                       0.1.7-1                                 amd64        init process for containers
 ii  conmon                          100:2.1.2~0                             amd64        OCI container runtime monitor
 ii  conntrack                       1:1.4.6-2build2                         amd64        Program to modify the conntrack tables
@@ -137,8 +137,8 @@ ii  libnghttp2-14:amd64             1.43.0-1ubuntu0.2                       amd6
 ii  libnl-3-200:amd64               3.5.0-0.1                               amd64        library for dealing with netlink sockets
 ii  libnpth0:amd64                  1.6-3build2                             amd64        replacement for GNU Pth using system threads
 ii  libnsl2:amd64                   1.3.0-2build2                           amd64        Public client interface for NIS(YP) and NIS+
-ii  libnvidia-container-tools       1.16.1-1                                amd64        NVIDIA container runtime library (command-line tools)
-ii  libnvidia-container1:amd64      1.16.1-1                                amd64        NVIDIA container runtime library
+ii  libnvidia-container-tools       1.16.2-1                                amd64        NVIDIA container runtime library (command-line tools)
+ii  libnvidia-container1:amd64      1.16.2-1                                amd64        NVIDIA container runtime library
 ii  libp11-kit0:amd64               0.24.0-6build1                          amd64        library for loading and coordinating access to PKCS#11 modules - runtime
 ii  libpam-modules:amd64            1.4.0-11ubuntu2.4                       amd64        Pluggable Authentication Modules for PAM
 ii  libpam-modules-bin              1.4.0-11ubuntu2.4                       amd64        Pluggable Authentication Modules for PAM - helper binaries
@@ -196,8 +196,8 @@ ii  ncurses-bin                     6.3-2ubuntu0.1                          amd6
 ii  netbase                         6.3                                     all          Basic TCP/IP networking system
 ii  netcat-openbsd                  1.218-4ubuntu1                          amd64        TCP/IP swiss army knife
 ii  nfs-common                      1:2.6.1-1ubuntu1.2                      amd64        NFS support files common to client and server
-ii  nvidia-container-toolkit        1.16.1-1                                amd64        NVIDIA Container toolkit
-ii  nvidia-container-toolkit-base   1.16.1-1                                amd64        NVIDIA Container Toolkit Base
+ii  nvidia-container-toolkit        1.16.2-1                                amd64        NVIDIA Container toolkit
+ii  nvidia-container-toolkit-base   1.16.2-1                                amd64        NVIDIA Container Toolkit Base
 ii  openssh-client                  1:8.9p1-3ubuntu0.10                     amd64        secure shell (SSH) client, for secure access to remote machines
 ii  openssh-server                  1:8.9p1-3ubuntu0.10                     amd64        secure shell (SSH) server, for secure access from remote machines
 ii  openssh-sftp-server             1:8.9p1-3ubuntu0.10                     amd64        secure shell (SSH) sftp server module, for SFTP access from remote machines
diff --git a/hack/update/get_version/get_version.go b/hack/update/get_version/get_version.go
index c09783161..7d52a7731 100644
--- a/hack/update/get_version/get_version.go
+++ b/hack/update/get_version/get_version.go
@@ -60,6 +60,7 @@ var dependencies = map[string]dependency{
 	"istio-operator":          {addonsFile, `istio/operator:(.*)@`},
 	"kindnetd":                {"pkg/minikube/bootstrapper/images/images.go", `kindnetd:(.*)"`},
 	"kong":                    {addonsFile, `kong:(.*)@`},
+	"kube-vip":                {"pkg/minikube/cluster/ha/kube-vip/kube-vip.go", `image: ghcr.io/kube-vip/kube-vip:(.*)`},
 	"volcano":                 {addonsFile, `volcanosh/vc-webhook-manager:(.*)@`},
 	"kong-ingress-controller": {addonsFile, `kong/kubernetes-ingress-controller:(.*)@`},
 	"kubectl":                 {addonsFile, `bitnami/kubectl:(.*)@`},
diff --git a/hack/update/kube_vip_version/update_kube_vip_version.go b/hack/update/kube_vip_version/update_kube_vip_version.go
new file mode 100644
index 000000000..ab921e9f4
--- /dev/null
+++ b/hack/update/kube_vip_version/update_kube_vip_version.go
@@ -0,0 +1,62 @@
+/*
+Copyright 2024 The Kubernetes Authors All rights reserved.
+
+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 main
+
+import (
+	"context"
+	"time"
+
+	"k8s.io/klog/v2"
+
+	"k8s.io/minikube/hack/update"
+)
+
+const (
+	// default context timeout
+	cxTimeout = 5 * time.Minute
+)
+
+var (
+	schema = map[string]update.Item{
+		"pkg/minikube/cluster/ha/kube-vip/kube-vip.go": {
+			Replace: map[string]string{
+				`image: ghcr.io/kube-vip/kube-vip:.*`: `image: ghcr.io/kube-vip/kube-vip:{{.StableVersion}}`,
+			},
+		},
+	}
+)
+
+// Data holds stable kube-vip version in semver format.
+type Data struct {
+	StableVersion string
+}
+
+func main() {
+	// set a context with defined timeout
+	ctx, cancel := context.WithTimeout(context.Background(), cxTimeout)
+	defer cancel()
+
+	// get kube-vip stable version
+	stable, err := update.StableVersion(ctx, "kube-vip", "kube-vip")
+	if err != nil {
+		klog.Fatalf("Unable to get kube-vip stable version: %v", err)
+	}
+	data := Data{StableVersion: stable}
+	klog.Infof("kube-vip stable version: %s", stable)
+
+	update.Apply(schema, data)
+}
diff --git a/netlify.toml b/netlify.toml
index c0b9fc776..651214e8c 100644
--- a/netlify.toml
+++ b/netlify.toml
@@ -5,7 +5,7 @@ command = "pwd && cd themes/docsy && npm install && git submodule update -f --in
 
 [build.environment]
 NODE_VERSION = "20.17.0"
-HUGO_VERSION = "v0.134.3"
+HUGO_VERSION = "v0.135.0"
 
 [context.production.environment]
 HUGO_ENV = "production"
diff --git a/pkg/drivers/kic/types.go b/pkg/drivers/kic/types.go
index 9eed5c625..7da6968d4 100644
--- a/pkg/drivers/kic/types.go
+++ b/pkg/drivers/kic/types.go
@@ -24,10 +24,10 @@ import (
 
 const (
 	// Version is the current version of kic
-	Version = "v0.0.45-1727108449-19696"
+	Version = "v0.0.45-1727731891-master"
 
 	// SHA of the kic base image
-	baseImageSHA = "c662152d8855bc4c62a3b5786a68adf99e04794e7f8f374a3859703004ef1d21"
+	baseImageSHA = "d66dfd4a976cf0b4581cac255174cef4031588c4570fa4a795e0b3d42edc9122"
 	// The name of the GCR kicbase repository
 	gcrRepo = "gcr.io/k8s-minikube/kicbase-builds"
 	// The name of the Dockerhub kicbase repository
diff --git a/pkg/minikube/assets/addons.go b/pkg/minikube/assets/addons.go
index 19607f7ae..60cca7262 100644
--- a/pkg/minikube/assets/addons.go
+++ b/pkg/minikube/assets/addons.go
@@ -312,6 +312,7 @@ var Addons = map[string]*Addon{
 		MustBinAsset(addons.InspektorGadgetAssets, "inspektor-gadget/ig-rolebinding.yaml", vmpath.GuestAddonsDir, "ig-rolebinding.yaml", "0640"),
 		MustBinAsset(addons.InspektorGadgetAssets, "inspektor-gadget/ig-clusterrole.yaml", vmpath.GuestAddonsDir, "ig-clusterrole.yaml", "0640"),
 		MustBinAsset(addons.InspektorGadgetAssets, "inspektor-gadget/ig-clusterrolebinding.yaml", vmpath.GuestAddonsDir, "ig-clusterrolebinding.yaml", "0640"),
+		MustBinAsset(addons.InspektorGadgetAssets, "inspektor-gadget/ig-configmap.yaml", vmpath.GuestAddonsDir, "ig-configmap.yaml", "0640"),
 		MustBinAsset(addons.InspektorGadgetAssets, "inspektor-gadget/ig-crd.yaml", vmpath.GuestAddonsDir, "ig-crd.yaml", "0640"),
 		MustBinAsset(addons.InspektorGadgetAssets, "inspektor-gadget/ig-daemonset.yaml.tmpl", vmpath.GuestAddonsDir, "ig-daemonset.yaml", "0640"),
 	}, false, "inspektor-gadget", "3rd party (inspektor-gadget.io)", "https://github.com/orgs/inspektor-gadget/people", "https://minikube.sigs.k8s.io/docs/handbook/addons/inspektor-gadget/",
diff --git a/pkg/minikube/cluster/ha/kube-vip/kube-vip.go b/pkg/minikube/cluster/ha/kube-vip/kube-vip.go
index d94597831..ed7d19a9d 100644
--- a/pkg/minikube/cluster/ha/kube-vip/kube-vip.go
+++ b/pkg/minikube/cluster/ha/kube-vip/kube-vip.go
@@ -32,8 +32,8 @@ import (
 const Manifest = "kube-vip.yaml"
 
 // KubeVipTemplate is kube-vip static pod config template
-// ref: https://kube-vip.io/docs/installation/static/
-// update: regenerate with:
+// ref: https://kube-vip.io/docs/installation/static/#generating-a-manifest
+// note: to check if the latest kube-vip version introduces any significant changes, compare the current one with a latest default manifest generated with:
 //
 //	export KVVERSION=$(curl -sL https://api.github.com/repos/kube-vip/kube-vip/releases | jq -r ".[0].name")
 //	docker run --rm ghcr.io/kube-vip/kube-vip:$KVVERSION manifest pod --interface eth0 --address 192.168.42.17 --controlplane --arp --leaderElection
diff --git a/pkg/minikube/cluster/status.go b/pkg/minikube/cluster/status.go
index 0cc58da19..3963cbde4 100644
--- a/pkg/minikube/cluster/status.go
+++ b/pkg/minikube/cluster/status.go
@@ -68,7 +68,7 @@ const (
 	// 2xx signifies that the API Server is able to service requests
 
 	OK       = 200
-	OKHAppy  = 201
+	HAppy    = 201
 	Warning  = 203
 	Degraded = 204
 
@@ -99,7 +99,7 @@ var (
 		103: "Deleting",
 
 		200: "OK",
-		201: "OKHAppy",
+		201: "HAppy",
 		203: "Warning",
 		204: "Degraded",
 
@@ -292,6 +292,7 @@ func GetState(sts []*Status, profile string, cc *config.ClusterConfig) State {
 			finalStep = data
 			klog.Infof("transient code %d (%q) for step: %+v", transientCode, codeNames[transientCode], data)
 		}
+
 		if ev.Type() == "io.k8s.sigs.minikube.error" {
 			var data map[string]string
 			err := ev.DataAs(&data)
@@ -299,15 +300,21 @@ func GetState(sts []*Status, profile string, cc *config.ClusterConfig) State {
 				klog.Errorf("unable to parse data: %v\nraw data: %s", err, ev.Data())
 				continue
 			}
-			exitCode, err := strconv.Atoi(data["exitcode"])
-			if err != nil {
-				klog.Errorf("exit code not found: %v", err)
-				continue
+			// process exit code, if present
+			if ec, ok := data["exitcode"]; ok && ec != "" {
+				exitCode, err := strconv.Atoi(ec)
+				if err != nil {
+					klog.Errorf("exit code not found: %v", err)
+					continue
+				}
+
+				if val, ok := exitCodeToHTTPCode[exitCode]; ok {
+					exitCode = val
+				}
+
+				transientCode = exitCode
 			}
-			if val, ok := exitCodeToHTTPCode[exitCode]; ok {
-				exitCode = val
-			}
-			transientCode = exitCode
+
 			for _, n := range cs.Nodes {
 				n.StatusCode = transientCode
 				n.StatusName = codeNames[n.StatusCode]
@@ -336,7 +343,7 @@ func GetState(sts []*Status, profile string, cc *config.ClusterConfig) State {
 		case healthyCPs == 2:
 			cs.StatusCode = Degraded
 		default:
-			cs.StatusCode = OKHAppy
+			cs.StatusCode = HAppy
 		}
 	}
 
diff --git a/pkg/minikube/cni/cilium.yaml b/pkg/minikube/cni/cilium.yaml
index c5dbb82aa..f7ba9d140 100644
--- a/pkg/minikube/cni/cilium.yaml
+++ b/pkg/minikube/cni/cilium.yaml
@@ -981,6 +981,31 @@ subjects:
     name: "cilium"
     namespace: kube-system
 ---
+# Source: cilium/templates/cilium-envoy/service.yaml
+apiVersion: v1
+kind: Service
+metadata:
+  name: cilium-envoy
+  namespace: kube-system
+  annotations:
+    prometheus.io/scrape: "true"
+    prometheus.io/port: "9964"
+  labels:
+    k8s-app: cilium-envoy
+    app.kubernetes.io/name: cilium-envoy
+    app.kubernetes.io/part-of: cilium
+    io.cilium/app: proxy
+spec:
+  clusterIP: None
+  type: ClusterIP
+  selector:
+    k8s-app: cilium-envoy
+  ports:
+  - name: envoy-metrics
+    port: 9964
+    protocol: TCP
+    targetPort: envoy-metrics
+---
 # Source: cilium/templates/hubble/peer-service.yaml
 apiVersion: v1
 kind: Service
@@ -1032,7 +1057,7 @@ spec:
           type: Unconfined
       containers:
       - name: cilium-agent
-        image: "quay.io/cilium/cilium:v1.16.1@sha256:0b4a3ab41a4760d86b7fc945b8783747ba27f29dac30dd434d94f2c9e3679f39"
+        image: "quay.io/cilium/cilium:v1.16.2@sha256:4386a8580d8d86934908eea022b0523f812e6a542f30a86a47edd8bed90d51ea"
         imagePullPolicy: IfNotPresent
         command:
         - cilium-agent
@@ -1186,7 +1211,7 @@ spec:
           mountPath: /tmp
       initContainers:
       - name: config
-        image: "quay.io/cilium/cilium:v1.16.1@sha256:0b4a3ab41a4760d86b7fc945b8783747ba27f29dac30dd434d94f2c9e3679f39"
+        image: "quay.io/cilium/cilium:v1.16.2@sha256:4386a8580d8d86934908eea022b0523f812e6a542f30a86a47edd8bed90d51ea"
         imagePullPolicy: IfNotPresent
         command:
         - cilium-dbg
@@ -1209,7 +1234,7 @@ spec:
       # Required to mount cgroup2 filesystem on the underlying Kubernetes node.
       # We use nsenter command with host's cgroup and mount namespaces enabled.
       - name: mount-cgroup
-        image: "quay.io/cilium/cilium:v1.16.1@sha256:0b4a3ab41a4760d86b7fc945b8783747ba27f29dac30dd434d94f2c9e3679f39"
+        image: "quay.io/cilium/cilium:v1.16.2@sha256:4386a8580d8d86934908eea022b0523f812e6a542f30a86a47edd8bed90d51ea"
         imagePullPolicy: IfNotPresent
         env:
         - name: CGROUP_ROOT
@@ -1246,7 +1271,7 @@ spec:
             drop:
               - ALL
       - name: apply-sysctl-overwrites
-        image: "quay.io/cilium/cilium:v1.16.1@sha256:0b4a3ab41a4760d86b7fc945b8783747ba27f29dac30dd434d94f2c9e3679f39"
+        image: "quay.io/cilium/cilium:v1.16.2@sha256:4386a8580d8d86934908eea022b0523f812e6a542f30a86a47edd8bed90d51ea"
         imagePullPolicy: IfNotPresent
         env:
         - name: BIN_PATH
@@ -1284,7 +1309,7 @@ spec:
       # from a privileged container because the mount propagation bidirectional
       # only works from privileged containers.
       - name: mount-bpf-fs
-        image: "quay.io/cilium/cilium:v1.16.1@sha256:0b4a3ab41a4760d86b7fc945b8783747ba27f29dac30dd434d94f2c9e3679f39"
+        image: "quay.io/cilium/cilium:v1.16.2@sha256:4386a8580d8d86934908eea022b0523f812e6a542f30a86a47edd8bed90d51ea"
         imagePullPolicy: IfNotPresent
         args:
         - 'mount | grep "/sys/fs/bpf type bpf" || mount -t bpf bpf /sys/fs/bpf'
@@ -1300,7 +1325,7 @@ spec:
           mountPath: /sys/fs/bpf
           mountPropagation: Bidirectional
       - name: clean-cilium-state
-        image: "quay.io/cilium/cilium:v1.16.1@sha256:0b4a3ab41a4760d86b7fc945b8783747ba27f29dac30dd434d94f2c9e3679f39"
+        image: "quay.io/cilium/cilium:v1.16.2@sha256:4386a8580d8d86934908eea022b0523f812e6a542f30a86a47edd8bed90d51ea"
         imagePullPolicy: IfNotPresent
         command:
         - /init-container.sh
@@ -1347,7 +1372,7 @@ spec:
           mountPath: /var/run/cilium # wait-for-kube-proxy
       # Install the CNI binaries in an InitContainer so we don't have a writable host mount in the agent
       - name: install-cni-binaries
-        image: "quay.io/cilium/cilium:v1.16.1@sha256:0b4a3ab41a4760d86b7fc945b8783747ba27f29dac30dd434d94f2c9e3679f39"
+        image: "quay.io/cilium/cilium:v1.16.2@sha256:4386a8580d8d86934908eea022b0523f812e6a542f30a86a47edd8bed90d51ea"
         imagePullPolicy: IfNotPresent
         command:
           - "/install-plugin.sh"
@@ -1514,8 +1539,6 @@ spec:
   template:
     metadata:
       annotations:
-        prometheus.io/port: "9964"
-        prometheus.io/scrape: "true"
       labels:
         k8s-app: cilium-envoy
         name: cilium-envoy
@@ -1527,7 +1550,7 @@ spec:
           type: Unconfined
       containers:
       - name: cilium-envoy
-        image: "quay.io/cilium/cilium-envoy:v1.29.7-39a2a56bbd5b3a591f69dbca51d3e30ef97e0e51@sha256:bd5ff8c66716080028f414ec1cb4f7dc66f40d2fb5a009fff187f4a9b90b566b"
+        image: "quay.io/cilium/cilium-envoy:v1.29.9-1726784081-a90146d13b4cd7d168d573396ccf2b3db5a3b047@sha256:9762041c3760de226a8b00cc12f27dacc28b7691ea926748f9b5c18862db503f"
         imagePullPolicy: IfNotPresent
         command:
         - /usr/bin/cilium-envoy-starter
@@ -1703,7 +1726,7 @@ spec:
     spec:
       containers:
       - name: cilium-operator
-        image: "quay.io/cilium/operator-generic:v1.16.1@sha256:3bc7e7a43bc4a4d8989cb7936c5d96675dd2d02c306adf925ce0a7c35aa27dc4"
+        image: "quay.io/cilium/operator-generic:v1.16.2@sha256:cccfd3b886d52cb132c06acca8ca559f0fce91a6bd99016219b1a81fdbc4813a"
         imagePullPolicy: IfNotPresent
         command:
         - cilium-operator-generic
diff --git a/site/content/en/docs/commands/start.md b/site/content/en/docs/commands/start.md
index af5a58980..533f49917 100644
--- a/site/content/en/docs/commands/start.md
+++ b/site/content/en/docs/commands/start.md
@@ -27,7 +27,7 @@ minikube start [flags]
       --apiserver-port int                The apiserver listening port (default 8443)
       --auto-pause-interval duration      Duration of inactivity before the minikube VM is paused (default 1m0s) (default 1m0s)
       --auto-update-drivers               If set, automatically updates drivers to the latest version. Defaults to true. (default true)
-      --base-image string                 The base image to use for docker/podman drivers. Intended for local development. (default "gcr.io/k8s-minikube/kicbase-builds:v0.0.45-1727108449-19696@sha256:c662152d8855bc4c62a3b5786a68adf99e04794e7f8f374a3859703004ef1d21")
+      --base-image string                 The base image to use for docker/podman drivers. Intended for local development. (default "gcr.io/k8s-minikube/kicbase-builds:v0.0.45-1727731891-master@sha256:d66dfd4a976cf0b4581cac255174cef4031588c4570fa4a795e0b3d42edc9122")
       --binary-mirror string              Location to fetch kubectl, kubelet, & kubeadm binaries from.
       --cache-images                      If true, cache docker images for the current bootstrapper and load them into the machine. Always false with --driver=none. (default true)
       --cert-expiration duration          Duration until minikube certificate expiration, defaults to three years (26280h). (default 26280h0m0s)
diff --git a/site/content/en/docs/tutorials/multi_control_plane_ha_clusters.md b/site/content/en/docs/tutorials/multi_control_plane_ha_clusters.md
index 986151856..977dba6c2 100644
--- a/site/content/en/docs/tutorials/multi_control_plane_ha_clusters.md
+++ b/site/content/en/docs/tutorials/multi_control_plane_ha_clusters.md
@@ -185,7 +185,7 @@ users:
 - Overview of the current leader and follower API servers
 
 ```shell
-minikube ssh -p ha-demo -- 'sudo /var/lib/minikube/binaries/v1.28.4/kubectl --kubeconfig=/var/lib/minikube/kubeconfig logs -n kube-system pod/kube-vip-ha-demo'
+minikube ssh -p ha-demo -- 'find /var/lib/minikube/binaries -iname kubectl -exec sudo {} --kubeconfig=/var/lib/minikube/kubeconfig logs -n kube-system pod/kube-vip-ha-demo \; -quit'
 ```
 ```
 time="2024-03-14T21:38:34Z" level=info msg="Starting kube-vip.io [v0.7.1]"
@@ -205,7 +205,7 @@ time="2024-03-14T21:38:48Z" level=info msg="Added backend for [192.168.49.254:84
 ```
 
 ```shell
-minikube ssh -p ha-demo -- 'sudo /var/lib/minikube/binaries/v1.28.4/kubectl --kubeconfig=/var/lib/minikube/kubeconfig logs -n kube-system pod/kube-vip-ha-demo-m02'
+minikube ssh -p ha-demo -- 'find /var/lib/minikube/binaries -iname kubectl -exec sudo {} --kubeconfig=/var/lib/minikube/kubeconfig logs -n kube-system pod/kube-vip-ha-demo-m02 \; -quit'
 ```
 ```
 time="2024-03-14T21:38:25Z" level=info msg="Starting kube-vip.io [v0.7.1]"
@@ -218,7 +218,7 @@ time="2024-03-14T21:38:34Z" level=info msg="Node [ha-demo] is assuming leadershi
 ```
 
 ```shell
-minikube ssh -p ha-demo -- 'sudo /var/lib/minikube/binaries/v1.28.4/kubectl --kubeconfig=/var/lib/minikube/kubeconfig logs -n kube-system pod/kube-vip-ha-demo-m03'
+minikube ssh -p ha-demo -- 'find /var/lib/minikube/binaries -iname kubectl -exec sudo {} --kubeconfig=/var/lib/minikube/kubeconfig logs -n kube-system pod/kube-vip-ha-demo-m03 \; -quit'
 ```
 ```
 time="2024-03-14T21:38:48Z" level=info msg="Starting kube-vip.io [v0.7.1]"
@@ -233,7 +233,7 @@ time="2024-03-14T21:38:48Z" level=info msg="Node [ha-demo] is assuming leadershi
 - Overview of multi-etcd instances
 
 ```shell
-minikube ssh -p ha-demo -- 'sudo /var/lib/minikube/binaries/v1.28.4/kubectl --kubeconfig=/var/lib/minikube/kubeconfig exec -ti pod/etcd-ha-demo -n kube-system -- /bin/sh -c "ETCDCTL_API=3 etcdctl member list --write-out=table --cacert=/var/lib/minikube/certs/etcd/ca.crt --cert=/var/lib/minikube/certs/etcd/server.crt --key=/var/lib/minikube/certs/etcd/server.key"'
+minikube ssh -p ha-demo -- 'find /var/lib/minikube/binaries -iname kubectl -exec sudo {} --kubeconfig=/var/lib/minikube/kubeconfig exec -ti pod/etcd-ha-demo -n kube-system -- /bin/sh -c "ETCDCTL_API=3 etcdctl member list --write-out=table --cacert=/var/lib/minikube/certs/etcd/ca.crt --cert=/var/lib/minikube/certs/etcd/server.crt --key=/var/lib/minikube/certs/etcd/server.key" \; -quit'
 ```
 ```
 +------------------+---------+-------------+---------------------------+---------------------------+------------+
diff --git a/translations/zh-CN.json b/translations/zh-CN.json
index 9be2c43e6..a0f8aac06 100644
--- a/translations/zh-CN.json
+++ b/translations/zh-CN.json
@@ -170,8 +170,8 @@
 	"Creating {{.driver_name}} VM (CPUs={{.number_of_cpus}}, Memory={{.memory_size}}MB, Disk={{.disk_size}}MB) ...": "正在创建 {{.driver_name}} 虚拟机（CPUs={{.number_of_cpus}}，Memory={{.memory_size}}MB, Disk={{.disk_size}}MB）...",
 	"Creating {{.driver_name}} {{.machine_type}} (CPUs={{.number_of_cpus}}, Memory={{.memory_size}}MB) ...": "正在创建 {{.driver_name}} {{.machine_type}}（CPUs={{.number_of_cpus}}，内存={{.memory_size}}MB）...",
 	"Creating {{.driver_name}} {{.machine_type}} (CPUs={{.number_of_cpus}}, Memory={{.memory_size}}MB, Disk={{.disk_size}}MB) ...": "正在创建 {{.driver_name}} {{.machine_type}}（CPUs={{.number_of_cpus}}，内存={{.memory_size}}MB，磁盘={{.disk_size}}MB）...",
-	"Creating {{.driver_name}} {{.machine_type}} (CPUs={{if not .number_of_cpus}}no-limit{{else}}{{.number_of_cpus}}{{end}}, Memory={{if not .memory_size}}no-limit{{else}}{{.memory_size}}MB{{end}}) ...": "",
-	"Current context is \"{{.context}}\"": "当前的上下文为 \"{{.context}}\"创建 {{.driver_name}} {{.machine_type}}（CPU={{if not .number_of_cpus}}无限制{{else}}{{.number_of_cpus}}{{end}}，内存={{if not .memory_size}}无限制{{else}}{{.memory_size}}MB{{end}}）...",
+	"Creating {{.driver_name}} {{.machine_type}} (CPUs={{if not .number_of_cpus}}no-limit{{else}}{{.number_of_cpus}}{{end}}, Memory={{if not .memory_size}}no-limit{{else}}{{.memory_size}}MB{{end}}) ...": "创建 {{.driver_name}} {{.machine_type}}（CPU={{if not .number_of_cpus}}无限制{{else}}{{.number_of_cpus}}{{end}}，内存={{if not .memory_size}}无限制{{else}}{{.memory_size}}MB{{end}}）...",
+	"Current context is \"{{.context}}\"": "当前的上下文为 \"{{.context}}\"",
 	"DEPRECATED, use `driver` instead.": "已弃用，请改用 `driver`。",
 	"DEPRECATED: Replaced by --cni": "已弃用，改用 --cni 来代替",
 	"DEPRECATED: Replaced by --cni=bridge": "已弃用，改用 --cni=bridge",


Test patch:
diff --git a/pkg/minikube/driver/driver_test.go b/pkg/minikube/driver/driver_test.go
index 03528bb12..ff5b45193 100644
--- a/pkg/minikube/driver/driver_test.go
+++ b/pkg/minikube/driver/driver_test.go
@@ -68,6 +68,7 @@ func TestMachineType(t *testing.T) {
 		KVM2:       "VM",
 		QEMU2:      "VM",
 		QEMU:       "VM",
+		VFKit:      "VM",
 		VirtualBox: "VM",
 		HyperKit:   "VM",
 		VMware:     "VM",
diff --git a/test/integration/addons_test.go b/test/integration/addons_test.go
index 26d798200..1828422c6 100644
--- a/test/integration/addons_test.go
+++ b/test/integration/addons_test.go
@@ -100,9 +100,9 @@ func TestAddons(t *testing.T) {
 		// so we override that here to let minikube auto-detect appropriate cgroup driver
 		os.Setenv(constants.MinikubeForceSystemdEnv, "")
 
-		args := append([]string{"start", "-p", profile, "--wait=true", "--memory=4000", "--alsologtostderr", "--addons=registry", "--addons=metrics-server", "--addons=volumesnapshots", "--addons=csi-hostpath-driver", "--addons=gcp-auth", "--addons=cloud-spanner", "--addons=inspektor-gadget", "--addons=storage-provisioner-rancher", "--addons=nvidia-device-plugin", "--addons=yakd", "--addons=volcano"}, StartArgs()...)
-		if !NoneDriver() { // none driver does not support ingress
-			args = append(args, "--addons=ingress", "--addons=ingress-dns")
+		args := append([]string{"start", "-p", profile, "--wait=true", "--memory=4000", "--alsologtostderr", "--addons=registry", "--addons=metrics-server", "--addons=volumesnapshots", "--addons=csi-hostpath-driver", "--addons=gcp-auth", "--addons=cloud-spanner", "--addons=inspektor-gadget", "--addons=nvidia-device-plugin", "--addons=yakd", "--addons=volcano"}, StartArgs()...)
+		if !NoneDriver() {
+			args = append(args, "--addons=ingress", "--addons=ingress-dns", "--addons=storage-provisioner-rancher")
 		}
 		rr, err := Run(t, exec.CommandContext(ctx, Target(), args...))
 		if err != nil {
@@ -189,10 +189,12 @@ func TestAddons(t *testing.T) {
 
 // validateIngressAddon tests the ingress addon by deploying a default nginx pod
 func validateIngressAddon(ctx context.Context, t *testing.T, profile string) {
-	defer PostMortemLogs(t, profile)
 	if NoneDriver() {
 		t.Skipf("skipping: ingress not supported")
 	}
+	defer disableAddon(t, "ingress", profile)
+	defer disableAddon(t, "ingress-dns", profile)
+	defer PostMortemLogs(t, profile)
 
 	client, err := kapi.Client(profile)
 	if err != nil {
@@ -300,20 +302,11 @@ func validateIngressAddon(ctx context.Context, t *testing.T, profile string) {
 	if !strings.Contains(rr.Stdout.String(), ip) {
 		t.Errorf("unexpected output from nslookup. stdout: %v\nstderr: %v", rr.Stdout.String(), rr.Stderr.String())
 	}
-
-	rr, err = Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "addons", "disable", "ingress-dns", "--alsologtostderr", "-v=1"))
-	if err != nil {
-		t.Errorf("failed to disable ingress-dns addon. args %q : %v", rr.Command(), err)
-	}
-
-	rr, err = Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "addons", "disable", "ingress", "--alsologtostderr", "-v=1"))
-	if err != nil {
-		t.Errorf("failed to disable ingress addon. args %q : %v", rr.Command(), err)
-	}
 }
 
 // validateRegistryAddon tests the registry addon
 func validateRegistryAddon(ctx context.Context, t *testing.T, profile string) {
+	defer disableAddon(t, "registry", profile)
 	defer PostMortemLogs(t, profile)
 
 	client, err := kapi.Client(profile)
@@ -382,15 +375,11 @@ func validateRegistryAddon(ctx context.Context, t *testing.T, profile string) {
 	if err := retry.Expo(checkExternalAccess, 500*time.Millisecond, Seconds(150)); err != nil {
 		t.Errorf("failed to check external access to %s: %v", u.String(), err.Error())
 	}
-
-	rr, err = Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "addons", "disable", "registry", "--alsologtostderr", "-v=1"))
-	if err != nil {
-		t.Errorf("failed to disable registry addon. args %q: %v", rr.Command(), err)
-	}
 }
 
 // validateMetricsServerAddon tests the metrics server addon by making sure "kubectl top pods" returns a sensible result
 func validateMetricsServerAddon(ctx context.Context, t *testing.T, profile string) {
+	defer disableAddon(t, "metrics-server", profile)
 	defer PostMortemLogs(t, profile)
 
 	client, err := kapi.Client(profile)
@@ -426,16 +415,12 @@ func validateMetricsServerAddon(ctx context.Context, t *testing.T, profile strin
 	if err := retry.Expo(checkMetricsServer, time.Second*3, Minutes(6)); err != nil {
 		t.Errorf("failed checking metric server: %v", err.Error())
 	}
-
-	rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "addons", "disable", "metrics-server", "--alsologtostderr", "-v=1"))
-	if err != nil {
-		t.Errorf("failed to disable metrics-server addon: args %q: %v", rr.Command(), err)
-	}
 }
 
 // validateOlmAddon tests the OLM addon
 func validateOlmAddon(ctx context.Context, t *testing.T, profile string) {
 	t.Skip("Skipping OLM addon test until https://github.com/operator-framework/operator-lifecycle-manager/issues/2534 is resolved")
+	defer disableAddon(t, "olm", profile)
 	defer PostMortemLogs(t, profile)
 	start := time.Now()
 
@@ -483,14 +468,12 @@ func validateOlmAddon(ctx context.Context, t *testing.T, profile string) {
 	if err := retry.Expo(checkOperatorInstalled, time.Second*3, Minutes(10)); err != nil {
 		t.Errorf("failed checking operator installed: %v", err.Error())
 	}
-
-	if rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "addons", "disable", "olm", "--alsologtostderr", "-v=1")); err != nil {
-		t.Errorf("failed to disable olm addon: args %q: %v", rr.Command(), err)
-	}
 }
 
 // validateCSIDriverAndSnapshots tests the csi hostpath driver by creating a persistent volume, snapshotting it and restoring it.
 func validateCSIDriverAndSnapshots(ctx context.Context, t *testing.T, profile string) {
+	defer disableAddon(t, "csi-hostpath-driver", profile)
+	defer disableAddon(t, "volumesnapshots", profile)
 	defer PostMortemLogs(t, profile)
 
 	client, err := kapi.Client(profile)
@@ -579,14 +562,6 @@ func validateCSIDriverAndSnapshots(ctx context.Context, t *testing.T, profile st
 	if err != nil {
 		t.Logf("cleanup with %s failed: %v", rr.Command(), err)
 	}
-	rr, err = Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "addons", "disable", "csi-hostpath-driver", "--alsologtostderr", "-v=1"))
-	if err != nil {
-		t.Errorf("failed to disable csi-hostpath-driver addon: args %q: %v", rr.Command(), err)
-	}
-	rr, err = Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "addons", "disable", "volumesnapshots", "--alsologtostderr", "-v=1"))
-	if err != nil {
-		t.Errorf("failed to disable volumesnapshots addon: args %q: %v", rr.Command(), err)
-	}
 }
 
 // validateGCPAuthNamespaces validates that newly created namespaces contain the gcp-auth secret.
@@ -619,6 +594,15 @@ func validateGCPAuthNamespaces(ctx context.Context, t *testing.T, profile string
 
 // validateGCPAuthAddon tests the GCP Auth addon with either phony or real credentials and makes sure the files are mounted into pods correctly
 func validateGCPAuthAddon(ctx context.Context, t *testing.T, profile string) {
+	defer func() {
+		disableGCPAuth := func() error {
+			disableAddon(t, "gcp-auth", profile)
+			return nil
+		}
+		if err := retry.Expo(disableGCPAuth, Minutes(2), Minutes(10), 5); err != nil {
+			t.Errorf("failed to disable GCP auth addon: %v", err)
+		}
+	}()
 	defer PostMortemLogs(t, profile)
 
 	t.Run("Namespaces", func(t *testing.T) {
@@ -707,18 +691,6 @@ func validateGCPAuthAddon(ctx context.Context, t *testing.T, profile string) {
 		t.Errorf("'printenv GOOGLE_CLOUD_PROJECT' returned %s, expected %s", got, expected)
 	}
 
-	disableGCPAuth := func() error {
-		_, err = Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "addons", "disable", "gcp-auth", "--alsologtostderr", "-v=1"))
-		if err != nil {
-			return err
-		}
-		return nil
-	}
-
-	if err := retry.Expo(disableGCPAuth, Minutes(2), Minutes(10), 5); err != nil {
-		t.Errorf("failed to disable GCP auth addon: %v", err)
-	}
-
 	// If we're on GCE, we have proper credentials and can test the registry secrets with an artifact registry image
 	if detect.IsOnGCE() && !detect.IsCloudShell() && !VMDriver() {
 		t.Skip("skipping GCPAuth addon test until 'Permission \"artifactregistry.repositories.downloadArtifacts\" denied on resource \"projects/k8s-minikube/locations/us/repositories/test-artifacts\" (or it may not exist)' issue is resolved")
@@ -763,6 +735,7 @@ func validateGCPAuthAddon(ctx context.Context, t *testing.T, profile string) {
 }
 
 func validateHeadlampAddon(ctx context.Context, t *testing.T, profile string) {
+	defer disableAddon(t, "headlamp", profile)
 	defer PostMortemLogs(t, profile)
 
 	rr, err := Run(t, exec.CommandContext(ctx, Target(), "addons", "enable", "headlamp", "-p", profile, "--alsologtostderr", "-v=1"))
@@ -773,26 +746,21 @@ func validateHeadlampAddon(ctx context.Context, t *testing.T, profile string) {
 	if _, err := PodWait(ctx, t, profile, "headlamp", "app.kubernetes.io/name=headlamp", Minutes(8)); err != nil {
 		t.Fatalf("failed waiting for headlamp pod: %v", err)
 	}
-
-	if rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "addons", "disable", "headlamp", "--alsologtostderr", "-v=1")); err != nil {
-		t.Errorf("failed to disable headlamp addon: args %q: %v", rr.Command(), err)
-	}
 }
 
 // validateInspektorGadgetAddon tests the inspektor-gadget addon by ensuring the pod has come up and addon disables
 func validateInspektorGadgetAddon(ctx context.Context, t *testing.T, profile string) {
+	defer disableAddon(t, "inspektor-gadget", profile)
 	defer PostMortemLogs(t, profile)
 
 	if _, err := PodWait(ctx, t, profile, "gadget", "k8s-app=gadget", Minutes(8)); err != nil {
 		t.Fatalf("failed waiting for inspektor-gadget pod: %v", err)
 	}
-	if rr, err := Run(t, exec.CommandContext(ctx, Target(), "addons", "disable", "inspektor-gadget", "-p", profile)); err != nil {
-		t.Errorf("failed to disable inspektor-gadget addon: args %q : %v", rr.Command(), err)
-	}
 }
 
 // validateCloudSpannerAddon tests the cloud-spanner addon by ensuring the deployment and pod come up and addon disables
 func validateCloudSpannerAddon(ctx context.Context, t *testing.T, profile string) {
+	defer disableAddon(t, "cloud-spanner", profile)
 	defer PostMortemLogs(t, profile)
 
 	client, err := kapi.Client(profile)
@@ -805,13 +773,11 @@ func validateCloudSpannerAddon(ctx context.Context, t *testing.T, profile string
 	if _, err := PodWait(ctx, t, profile, "default", "app=cloud-spanner-emulator", Minutes(6)); err != nil {
 		t.Errorf("failed waiting for app=cloud-spanner-emulator pod: %v", err)
 	}
-	if rr, err := Run(t, exec.CommandContext(ctx, Target(), "addons", "disable", "cloud-spanner", "-p", profile)); err != nil {
-		t.Errorf("failed to disable cloud-spanner addon: args %q : %v", rr.Command(), err)
-	}
 }
 
 // validateVolcanoAddon tests the Volcano addon, makes sure the Volcano is installed into cluster.
 func validateVolcanoAddon(ctx context.Context, t *testing.T, profile string) {
+	defer disableAddon(t, "volcano", profile)
 	defer PostMortemLogs(t, profile)
 	if ContainerRuntime() == "crio" {
 		t.Skipf("skipping: crio not supported")
@@ -902,19 +868,14 @@ func validateVolcanoAddon(ctx context.Context, t *testing.T, profile string) {
 	if _, err := PodWait(ctx, t, profile, "my-volcano", "volcano.sh/job-name=test-job", Minutes(3)); err != nil {
 		t.Fatalf("failed waiting for test-local-path pod: %v", err)
 	}
-
-	rr, err = Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "addons", "disable", "volcano", "--alsologtostderr", "-v=1"))
-	if err != nil {
-		t.Errorf("failed to disable volcano addon: args %q: %v", rr.Command(), err)
-	}
 }
 
 // validateLocalPathAddon tests the functionality of the storage-provisioner-rancher addon
 func validateLocalPathAddon(ctx context.Context, t *testing.T, profile string) {
-
 	if NoneDriver() {
 		t.Skipf("skip local-path test on none driver")
 	}
+	defer disableAddon(t, "storage-provisioner-rancher", profile)
 
 	// Create a test PVC
 	rr, err := Run(t, exec.CommandContext(ctx, "kubectl", "--context", profile, "apply", "-f", filepath.Join(*testdataDir, "storage-provisioner-rancher", "pvc.yaml")))
@@ -964,10 +925,6 @@ func validateLocalPathAddon(ctx context.Context, t *testing.T, profile string) {
 	if err != nil {
 		t.Logf("cleanup with %s failed: %v", rr.Command(), err)
 	}
-	rr, err = Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "addons", "disable", "storage-provisioner-rancher", "--alsologtostderr", "-v=1"))
-	if err != nil {
-		t.Errorf("failed to disable storage-provisioner-rancher addon: args %q: %v", rr.Command(), err)
-	}
 }
 
 // validateEnablingAddonOnNonExistingCluster tests enabling an addon on a non-existing cluster
@@ -1015,3 +972,10 @@ func validateYakdAddon(ctx context.Context, t *testing.T, profile string) {
 		t.Errorf("failed to disable yakd addon: args %q: %v", rr.Command(), err)
 	}
 }
+
+func disableAddon(t *testing.T, addon, profile string) {
+	rr, err := Run(t, exec.Command(Target(), "-p", profile, "addons", "disable", addon, "--alsologtostderr", "-v=1"))
+	if err != nil {
+		t.Errorf("failed to disable %s addon: args %q: %v", addon, rr.Command(), err)
+	}
+}
diff --git a/test/integration/ha_test.go b/test/integration/ha_test.go
index 5cb4f5a3d..3d7f7adc9 100644
--- a/test/integration/ha_test.go
+++ b/test/integration/ha_test.go
@@ -300,8 +300,10 @@ func validateHAStatusHAppy(ctx context.Context, t *testing.T, profile string) {
 
 	if profileObject == nil {
 		t.Errorf("expected the json of 'profile list' to include %q but got *%q*. args: %q", profile, rr.Stdout.String(), rr.Command())
-	} else if expected, numNodes := 4, len(profileObject.Config.Nodes); numNodes != expected {
-		t.Errorf("expected profile %q in json of 'profile list' to include %d nodes but have %d nodes. got *%q*. args: %q", profile, expected, numNodes, rr.Stdout.String(), rr.Command())
+	} else {
+		if expected, numNodes := 4, len(profileObject.Config.Nodes); numNodes != expected {
+			t.Errorf("expected profile %q in json of 'profile list' to include %d nodes but have %d nodes. got *%q*. args: %q", profile, expected, numNodes, rr.Stdout.String(), rr.Command())
+		}
 
 		if expected, status := "HAppy", profileObject.Status; status != expected {
 			t.Errorf("expected profile %q in json of 'profile list' to have %q status but have %q status. got *%q*. args: %q", profile, expected, status, rr.Stdout.String(), rr.Command())