Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package kind for openSUSE:Factory checked in at 2026-08-28 19:52:30 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/kind (Old) and /work/SRC/openSUSE:Factory/.kind.new.1265 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kind" Fri Aug 28 19:52:30 2026 rev:10 rq:1374272 version:0.33.0 Changes: -------- --- /work/SRC/openSUSE:Factory/kind/kind.changes 2026-06-03 20:28:13.635658208 +0200 +++ /work/SRC/openSUSE:Factory/.kind.new.1265/kind.changes 2026-08-28 19:54:57.979881863 +0200 @@ -1,0 +2,31 @@ +Fri Aug 28 07:54:52 UTC 2026 - Johannes Kastl <[email protected]> + +- Update to version 0.33.0: + This release contains critical dependency updates, bug fixes, and + defaults to Kubernetes 1.36.1. + * Breaking Changes + - The default node image is now + kindest/node:v1.37.0@sha256:a1ed56cfb0e7b93589bdf97c8cd566405a265939e3620fc4f5de89adff580ae5. + * New Features + - Assorted dependency updates. + * Images pre-built for this release: + - v1.37.0: + kindest/node:v1.37.0@sha256:a1ed56cfb0e7b93589bdf97c8cd566405a265939e3620fc4f5de89adff580ae5 + - v1.36.4: + kindest/node:v1.36.4@sha256:099e049362a1526b2db71494e1947aae99bd16290d7c895f2b7ea312e3cbfaed + - v1.35.8: + kindest/node:v1.35.8@sha256:07b2536e30b803ed61d1677a79df6115f798ce64c80f9e22f6ed45afd09323c0 + - v1.34.11: + kindest/node:v1.34.11@sha256:44e222ee2132dab25ff87301682f89eb82c7880ea3a1bf543bfe9708fd08d67d + NOTE: You must use the @sha256 digest to guarantee an image + built for this release, until such a time as we switch to a + different tagging scheme. Even then we will highly encourage + digest pinning for security and reproducibility reasons. + * Fixes + - Respect Docker client proxy config for docker nodes. (#4192) + - Preserve external load balancer CDS/LDS configuration across + container restarts. (#4195) + - Improve local-path-provisioner helperPod tolerations. (#4210) + - Assorted documentation fixes and improvements. + +------------------------------------------------------------------- Old: ---- kind-0.32.0.obscpio New: ---- kind-0.33.0.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ kind.spec ++++++ --- /var/tmp/diff_new_pack.LFOELQ/_old 2026-08-28 19:54:59.428932513 +0200 +++ /var/tmp/diff_new_pack.LFOELQ/_new 2026-08-28 19:54:59.434932723 +0200 @@ -17,7 +17,7 @@ Name: kind -Version: 0.32.0 +Version: 0.33.0 Release: 0 Summary: Kubernetes IN Docker - local clusters for testing Kubernetes License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.LFOELQ/_old 2026-08-28 19:54:59.504935170 +0200 +++ /var/tmp/diff_new_pack.LFOELQ/_new 2026-08-28 19:54:59.512935449 +0200 @@ -1,9 +1,9 @@ <services> <service name="obs_scm" mode="manual"> - <param name="url">https://github.com/kubernetes-sigs/kind/</param> + <param name="url">https://github.com/kubernetes-sigs/kind.git</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">v0.32.0</param> + <param name="revision">refs/tags/v0.33.0</param> <param name="versionformat">@PARENT_TAG@</param> <param name="changesgenerate">enable</param> <param name="versionrewrite-pattern">v(.*)</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.LFOELQ/_old 2026-08-28 19:54:59.564937267 +0200 +++ /var/tmp/diff_new_pack.LFOELQ/_new 2026-08-28 19:54:59.569937442 +0200 @@ -1,6 +1,8 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/kubernetes-sigs/kind/</param> - <param name="changesrevision">cda67ef8588f6bfdac5358233f2471cb2149ecaf</param></service></servicedata> + <param name="changesrevision">cda67ef8588f6bfdac5358233f2471cb2149ecaf</param></service><service name="tar_scm"> + <param name="url">https://github.com/kubernetes-sigs/kind.git</param> + <param name="changesrevision">407a9675e6d9af1200b5f57f9ca52ec6cdacce74</param></service></servicedata> (No newline at EOF) ++++++ kind-0.32.0.obscpio -> kind-0.33.0.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/.go-version new/kind-0.33.0/.go-version --- old/kind-0.32.0/.go-version 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/.go-version 2026-08-26 23:27:15.000000000 +0200 @@ -1 +1 @@ -1.26.3 +1.26.7 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/README.md new/kind-0.33.0/README.md --- old/kind-0.32.0/README.md 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/README.md 2026-08-26 23:27:15.000000000 +0200 @@ -5,7 +5,7 @@ kind is a tool for running local Kubernetes clusters using Docker container "nodes". kind was primarily designed for testing Kubernetes itself, but may be used for local development or CI. -If you have [go] 1.16+ and [docker], [podman] or [nerdctl] installed `go install sigs.k8s.io/[email protected] && kind create cluster` is all you need! +If you have [go] and [docker], [podman] or [nerdctl] installed `go install sigs.k8s.io/[email protected] && kind create cluster` is all you need!  @@ -23,7 +23,7 @@ For a complete [install guide] see [the documentation here][install guide]. -You can install kind with `go install sigs.k8s.io/[email protected]`. +You can install kind with `go install sigs.k8s.io/[email protected]`. **NOTE**: please use the latest go to do this. KIND is developed with the latest stable go, see [`.go-version`](./.go-version) for the exact version we're using. @@ -43,9 +43,9 @@ ```console # For AMD64 / x86_64 -[ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.31.0/kind-$(uname)-amd64 +[ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.32.0/kind-$(uname)-amd64 # For ARM64 -[ $(uname -m) = aarch64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.31.0/kind-$(uname)-arm64 +[ $(uname -m) = aarch64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.32.0/kind-$(uname)-arm64 chmod +x ./kind sudo mv ./kind /usr/local/bin/kind ``` @@ -66,9 +66,9 @@ ```console # For Intel Macs -[ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.31.0/kind-darwin-amd64 +[ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.32.0/kind-darwin-amd64 # For M1 / ARM Macs -[ $(uname -m) = arm64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.31.0/kind-darwin-arm64 +[ $(uname -m) = arm64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.32.0/kind-darwin-arm64 chmod +x ./kind mv ./kind /some-dir-in-your-PATH/kind ``` @@ -76,7 +76,7 @@ On Windows: ```powershell -curl.exe -Lo kind-windows-amd64.exe https://kind.sigs.k8s.io/dl/v0.31.0/kind-windows-amd64 +curl.exe -Lo kind-windows-amd64.exe https://kind.sigs.k8s.io/dl/v0.32.0/kind-windows-amd64 Move-Item .\kind-windows-amd64.exe c:\some-dir-in-your-PATH\kind.exe # OR via Chocolatey (https://chocolatey.org/packages/kind) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/images/base/Dockerfile new/kind-0.33.0/images/base/Dockerfile --- old/kind-0.32.0/images/base/Dockerfile 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/images/base/Dockerfile 2026-08-26 23:27:15.000000000 +0200 @@ -124,7 +124,7 @@ # stage for building containerd FROM go-build AS build-containerd ARG TARGETARCH GO_VERSION -ARG CONTAINERD_VERSION="v2.3.1" +ARG CONTAINERD_VERSION="v2.3.4" ARG CONTAINERD_CLONE_URL="https://github.com/containerd/containerd" # we don't build with optional snapshotters, we never select any of these # they're not ideal inside kind anyhow, and we save some disk space @@ -142,7 +142,7 @@ # stage for building runc FROM go-build AS build-runc ARG TARGETARCH GO_VERSION -ARG RUNC_VERSION="v1.4.2" +ARG RUNC_VERSION="v1.4.3" ARG RUNC_CLONE_URL="https://github.com/opencontainers/runc" RUN git clone --filter=tree:0 "${RUNC_CLONE_URL}" /runc \ && cd /runc \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/pkg/apis/config/defaults/image.go new/kind-0.33.0/pkg/apis/config/defaults/image.go --- old/kind-0.32.0/pkg/apis/config/defaults/image.go 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/pkg/apis/config/defaults/image.go 2026-08-26 23:27:15.000000000 +0200 @@ -18,4 +18,4 @@ package defaults // Image is the default for the Config.Image field, aka the default node image. -const Image = "kindest/node:v1.36.1@sha256:3489c7674813ba5d8b1a9977baea8a6e553784dab7b84759d1014dbd78f7ebd5" +const Image = "kindest/node:v1.37.0@sha256:a1ed56cfb0e7b93589bdf97c8cd566405a265939e3620fc4f5de89adff580ae5" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/pkg/build/nodeimage/const_cni.go new/kind-0.33.0/pkg/build/nodeimage/const_cni.go --- old/kind-0.32.0/pkg/build/nodeimage/const_cni.go 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/pkg/build/nodeimage/const_cni.go 2026-08-26 23:27:15.000000000 +0200 @@ -20,7 +20,7 @@ The default CNI manifest and images are our own tiny kindnet */ -const kindnetdImage = "docker.io/kindest/kindnetd:v20260528-9350166c" +const kindnetdImage = "docker.io/kindest/kindnetd:v20260820-69b56db7" var defaultCNIImages = []string{kindnetdImage} @@ -135,9 +135,6 @@ requests: cpu: "100m" memory: "50Mi" - limits: - cpu: "100m" - memory: "50Mi" securityContext: privileged: false capabilities: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/pkg/build/nodeimage/const_storage.go new/kind-0.33.0/pkg/build/nodeimage/const_storage.go --- old/kind-0.32.0/pkg/build/nodeimage/const_storage.go 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/pkg/build/nodeimage/const_storage.go 2026-08-26 23:27:15.000000000 +0200 @@ -26,7 +26,7 @@ - tolerate control plane scheduling taints */ -const storageProvisionerImage = "docker.io/kindest/local-path-provisioner:v20260521-9fb22683" +const storageProvisionerImage = "docker.io/kindest/local-path-provisioner:v20260820-69b56db7" const storageHelperImage = "docker.io/kindest/local-path-helper:v20260131-7181c60a" // image we need to preload @@ -204,9 +204,10 @@ spec: priorityClassName: system-node-critical tolerations: - - key: node.kubernetes.io/disk-pressure - operator: Exists + - operator: Exists effect: NoSchedule + - operator: Exists + effect: NoExecute containers: - name: helper-pod image: ` + storageHelperImage + ` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/pkg/build/nodeimage/defaults.go new/kind-0.33.0/pkg/build/nodeimage/defaults.go --- old/kind-0.32.0/pkg/build/nodeimage/defaults.go 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/pkg/build/nodeimage/defaults.go 2026-08-26 23:27:15.000000000 +0200 @@ -22,4 +22,4 @@ // DefaultBaseImage is the default base image used // TODO: come up with a reasonable solution to digest pinning // https://github.com/moby/moby/issues/43188 -const DefaultBaseImage = "docker.io/kindest/base:v20260601-995e8fa5" +const DefaultBaseImage = "docker.io/kindest/base:v20260820-69b56db7" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/pkg/cluster/internal/kubeconfig/internal/kubeconfig/paths.go new/kind-0.33.0/pkg/cluster/internal/kubeconfig/internal/kubeconfig/paths.go --- old/kind-0.32.0/pkg/cluster/internal/kubeconfig/internal/kubeconfig/paths.go 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/pkg/cluster/internal/kubeconfig/internal/kubeconfig/paths.go 2026-08-26 23:27:15.000000000 +0200 @@ -74,7 +74,7 @@ func fileExists(filename string) bool { info, err := os.Stat(filename) - if os.IsNotExist(err) { + if err != nil { return false } return !info.IsDir() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/pkg/cluster/internal/kubeconfig/internal/kubeconfig/paths_test.go new/kind-0.33.0/pkg/cluster/internal/kubeconfig/internal/kubeconfig/paths_test.go --- old/kind-0.32.0/pkg/cluster/internal/kubeconfig/internal/kubeconfig/paths_test.go 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/pkg/cluster/internal/kubeconfig/internal/kubeconfig/paths_test.go 2026-08-26 23:27:15.000000000 +0200 @@ -124,6 +124,29 @@ expected := "/bogus/path/two" assert.StringEqual(t, expected, result) }) + t.Run("KUBECONFIG skips inaccessible entry", func(t *testing.T) { + inaccessibleDir := filepath.Join(dir, "inaccessible") + if err := os.Mkdir(inaccessibleDir, 0o700); err != nil { + t.Fatalf("failed to create inaccessible dir: %v", err) + } + defer func() { + if err := os.Chmod(inaccessibleDir, 0o700); err != nil { + t.Fatalf("failed to restore dir permissions: %v", err) + } + }() + if err := os.Chmod(inaccessibleDir, 0); err != nil { + t.Fatalf("failed to chmod inaccessible dir: %v", err) + } + + inaccessibleFile := filepath.Join(inaccessibleDir, "config") + kubeconfigEnvValue := strings.Join([]string{inaccessibleFile, fakeKubeconfigs[1]}, string(filepath.ListSeparator)) + result := pathForMerge("", func(s string) string { + return map[string]string{ + "KUBECONFIG": kubeconfigEnvValue, + }[s] + }) + assert.StringEqual(t, fakeKubeconfigs[1], result) + }) } func TestHomeDir(t *testing.T) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/pkg/cluster/internal/loadbalancer/config.go new/kind-0.33.0/pkg/cluster/internal/loadbalancer/config.go --- old/kind-0.32.0/pkg/cluster/internal/loadbalancer/config.go 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/pkg/cluster/internal/loadbalancer/config.go 2026-08-26 23:27:15.000000000 +0200 @@ -171,18 +171,13 @@ ProxyConfigPathLDS, ) - // Create dynamic Envoy config files and start Envoy with retry, - // since it has an initialization phase before forwarding traffic. - // cmd := []string{"bash", "-c", - // fmt.Sprintf(`mkdir -p %s && echo -en '%s' > %s && touch %s && touch %s && while true; do envoy -c %s && break; sleep 1; done`, constants.ProxyConfigDir, - // envoyConfig, constants.ProxyConfigPath, constants.ProxyConfigPathCDS, constants.ProxyConfigPathLDS, constants.ProxyConfigPath)} // Create dynamic Envoy config files with valid empty resources emptyConfig := "resources: []" return []string{"bash", "-c", - fmt.Sprintf(`mkdir -p %s && echo -en '%s' > %s && echo -en '%s' > %s && echo -en '%s' > %s && while true; do envoy -c %s && break; sleep 1; done`, + fmt.Sprintf(`mkdir -p %s && echo -en '%s' > %s && { [ ! -f %s ] && echo -en '%s' > %s || true; } && { [ ! -f %s ] && echo -en '%s' > %s || true; } && while true; do envoy -c %s && break; sleep 1; done`, ProxyConfigDir, envoyConfig, ProxyConfigPath, - emptyConfig, ProxyConfigPathCDS, // Initialize CDS - emptyConfig, ProxyConfigPathLDS, // Initialize LDS + ProxyConfigPathCDS, emptyConfig, ProxyConfigPathCDS, // Initialize CDS only if not exists + ProxyConfigPathLDS, emptyConfig, ProxyConfigPathLDS, // Initialize LDS only if not exists ProxyConfigPath)} } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/pkg/cluster/internal/providers/docker/images.go new/kind-0.33.0/pkg/cluster/internal/providers/docker/images.go --- old/kind-0.32.0/pkg/cluster/internal/providers/docker/images.go 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/pkg/cluster/internal/providers/docker/images.go 2026-08-26 23:27:15.000000000 +0200 @@ -37,7 +37,7 @@ for _, image := range common.RequiredNodeImages(cfg).List() { // prints user friendly message friendlyImageName, image := sanitizeImage(image) - status.Start(fmt.Sprintf("Ensuring node image (%s) 🖼", friendlyImageName)) + status.Start(fmt.Sprintf("Ensuring node image (%s) 🖼️", friendlyImageName)) if _, err := pullIfNotPresent(logger, image, 4); err != nil { status.End(false) return err diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/pkg/cluster/internal/providers/docker/provision.go new/kind-0.33.0/pkg/cluster/internal/providers/docker/provision.go --- old/kind-0.32.0/pkg/cluster/internal/providers/docker/provision.go 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/pkg/cluster/internal/providers/docker/provision.go 2026-08-26 23:27:15.000000000 +0200 @@ -20,6 +20,7 @@ "context" "fmt" "net" + "os" "path/filepath" "strings" "time" @@ -291,6 +292,9 @@ func getProxyEnv(cfg *config.Cluster, networkName string, nodeNames []string) (map[string]string, error) { envs := common.GetProxyEnvs(cfg) + if !kindProxyEnvOverridesDockerConfig(os.Getenv) { + envs = mergeProxyEnvWithDockerConfig(cfg, envs, dockerConfigProxyEnvs(os.Getenv, os.ReadFile, inspectDockerContextHost)) + } // Specifically add the docker network subnets to NO_PROXY if we are using a proxy if len(envs) > 0 { subnets, err := getSubnets(networkName) @@ -313,6 +317,28 @@ return envs, nil } +func mergeProxyEnvWithDockerConfig(cfg *config.Cluster, envs, dockerEnv map[string]string) map[string]string { + if len(envs) == 0 && len(dockerEnv) > 0 { + envs = dockerEnv + noProxy := envs[common.NOProxy] + if noProxy != "" { + noProxy += "," + } + noProxy += cfg.Networking.ServiceSubnet + "," + cfg.Networking.PodSubnet + envs[common.NOProxy] = noProxy + envs[strings.ToLower(common.NOProxy)] = noProxy + return envs + } + + for _, name := range []string{common.HTTPProxy, common.HTTPSProxy, common.NOProxy} { + if envs[name] == "" && dockerEnv[name] != "" { + envs[name] = dockerEnv[name] + envs[strings.ToLower(name)] = dockerEnv[name] + } + } + return envs +} + func getSubnets(networkName string) ([]string, error) { format := `{{range (index (index . "IPAM") "Config")}}{{index . "Subnet"}} {{end}}` cmd := exec.Command("docker", "network", "inspect", "-f", format, networkName) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/pkg/cluster/internal/providers/docker/proxyconfig.go new/kind-0.33.0/pkg/cluster/internal/providers/docker/proxyconfig.go --- old/kind-0.32.0/pkg/cluster/internal/providers/docker/proxyconfig.go 1970-01-01 01:00:00.000000000 +0100 +++ new/kind-0.33.0/pkg/cluster/internal/providers/docker/proxyconfig.go 2026-08-26 23:27:15.000000000 +0200 @@ -0,0 +1,155 @@ +/* +Copyright 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 docker + +import ( + "encoding/json" + "path/filepath" + "strings" + + "sigs.k8s.io/kind/pkg/cluster/internal/providers/common" + "sigs.k8s.io/kind/pkg/exec" +) + +const ( + dockerConfigEnv = "DOCKER_CONFIG" + dockerContextEnv = "DOCKER_CONTEXT" + dockerHostEnv = "DOCKER_HOST" +) + +type dockerConfigFile struct { + CurrentContext string `json:"currentContext"` + Proxies map[string]dockerProxyConfig `json:"proxies"` +} + +type dockerProxyConfig struct { + HTTPProxy string `json:"httpProxy"` + HTTPSProxy string `json:"httpsProxy"` + NOProxy string `json:"noProxy"` +} + +func dockerConfigProxyEnvs( + getEnv func(string) string, + readFile func(string) ([]byte, error), + inspectContextHost func(string) (string, error), +) map[string]string { + configPath := dockerConfigPath(getEnv) + if configPath == "" { + return map[string]string{} + } + + rawConfig, err := readFile(configPath) + if err != nil { + return map[string]string{} + } + + cfg := dockerConfigFile{} + if err := json.Unmarshal(rawConfig, &cfg); err != nil { + return map[string]string{} + } + + proxyCfg, ok := dockerProxySettings(cfg.Proxies, dockerHostForProxyLookup(getEnv, cfg, inspectContextHost)) + if !ok { + return map[string]string{} + } + + envs := map[string]string{} + setProxyEnv(envs, common.HTTPProxy, proxyCfg.HTTPProxy) + setProxyEnv(envs, common.HTTPSProxy, proxyCfg.HTTPSProxy) + setProxyEnv(envs, common.NOProxy, proxyCfg.NOProxy) + return envs +} + +func dockerConfigPath(getEnv func(string) string) string { + // Docker CLI config defaults to ~/.docker/config.json and can be overridden + // with DOCKER_CONFIG. The same config file also stores the current context. + // See https://docs.docker.com/reference/cli/docker/ + if dockerConfigDir := getEnv(dockerConfigEnv); dockerConfigDir != "" { + return filepath.Join(dockerConfigDir, "config.json") + } + if homeDir := getEnv("HOME"); homeDir != "" { + return filepath.Join(homeDir, ".docker", "config.json") + } + return "" +} + +func dockerHostForProxyLookup( + getEnv func(string) string, + cfg dockerConfigFile, + inspectContextHost func(string) (string, error), +) string { + if dockerHost := getEnv(dockerHostEnv); dockerHost != "" { + return dockerHost + } + + contextName := getEnv(dockerContextEnv) + if contextName == "" { + contextName = cfg.CurrentContext + } + if contextName == "" { + contextName = "default" + } + + host, err := inspectContextHost(contextName) + if err != nil { + return "" + } + return strings.TrimSpace(host) +} + +func dockerProxySettings(proxies map[string]dockerProxyConfig, dockerHost string) (dockerProxyConfig, bool) { + if len(proxies) == 0 { + return dockerProxyConfig{}, false + } + // Docker's proxies config supports a "default" entry plus per-daemon entries + // keyed by the daemon host string, for example + // "https://manager1.mycorp.example.com:2377". + // See https://docs.docker.com/reference/cli/docker/ + if dockerHost != "" { + if proxyCfg, ok := proxies[dockerHost]; ok { + return proxyCfg, true + } + } + proxyCfg, ok := proxies["default"] + return proxyCfg, ok +} + +func setProxyEnv(envs map[string]string, name, value string) { + if value == "" { + return + } + envs[name] = value + envs[strings.ToLower(name)] = value +} + +func kindProxyEnvOverridesDockerConfig(getEnv func(string) string) bool { + for _, name := range []string{common.HTTPProxy, common.HTTPSProxy} { + if getEnv(name) != "" || getEnv(strings.ToLower(name)) != "" { + return true + } + } + return false +} + +func inspectDockerContextHost(contextName string) (string, error) { + format := `{{ (index .Endpoints "docker").Host }}` + lines, err := exec.OutputLines(exec.Command("docker", "context", "inspect", "--format", format, contextName)) + if err != nil || len(lines) == 0 { + return "", err + } + return lines[0], nil +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/pkg/cluster/internal/providers/docker/proxyconfig_test.go new/kind-0.33.0/pkg/cluster/internal/providers/docker/proxyconfig_test.go --- old/kind-0.32.0/pkg/cluster/internal/providers/docker/proxyconfig_test.go 1970-01-01 01:00:00.000000000 +0100 +++ new/kind-0.33.0/pkg/cluster/internal/providers/docker/proxyconfig_test.go 2026-08-26 23:27:15.000000000 +0200 @@ -0,0 +1,331 @@ +/* +Copyright 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 docker + +import ( + "path/filepath" + "testing" + + "sigs.k8s.io/kind/pkg/cluster/internal/providers/common" + "sigs.k8s.io/kind/pkg/internal/apis/config" + "sigs.k8s.io/kind/pkg/internal/assert" +) + +func TestDockerConfigProxyEnvs(t *testing.T) { + t.Parallel() + + const configJSON = `{ + "proxies": { + "default": { + "httpProxy": "http://proxy.default:3128", + "httpsProxy": "https://proxy.default:3129", + "noProxy": "default.internal" + }, + "tcp://remote.example.com:2376": { + "httpProxy": "http://proxy.remote:4128", + "httpsProxy": "https://proxy.remote:4129", + "noProxy": "remote.internal" + } + } + }` + + cases := []struct { + name string + env map[string]string + want map[string]string + }{ + { + name: "uses default docker config", + env: map[string]string{ + "DOCKER_CONFIG": "/tmp/docker-config", + }, + want: map[string]string{ + common.HTTPProxy: "http://proxy.default:3128", + "http_proxy": "http://proxy.default:3128", + common.HTTPSProxy: "https://proxy.default:3129", + "https_proxy": "https://proxy.default:3129", + common.NOProxy: "default.internal", + "no_proxy": "default.internal", + }, + }, + { + name: "uses host specific docker config when DOCKER_HOST matches", + env: map[string]string{ + "DOCKER_CONFIG": "/tmp/docker-config", + "DOCKER_HOST": "tcp://remote.example.com:2376", + }, + want: map[string]string{ + common.HTTPProxy: "http://proxy.remote:4128", + "http_proxy": "http://proxy.remote:4128", + common.HTTPSProxy: "https://proxy.remote:4129", + "https_proxy": "https://proxy.remote:4129", + common.NOProxy: "remote.internal", + "no_proxy": "remote.internal", + }, + }, + { + name: "uses host specific docker config when DOCKER_CONTEXT matches a remote host", + env: map[string]string{ + "DOCKER_CONFIG": "/tmp/docker-config", + "DOCKER_CONTEXT": "remote-context", + }, + want: map[string]string{ + common.HTTPProxy: "http://proxy.remote:4128", + "http_proxy": "http://proxy.remote:4128", + common.HTTPSProxy: "https://proxy.remote:4129", + "https_proxy": "https://proxy.remote:4129", + common.NOProxy: "remote.internal", + "no_proxy": "remote.internal", + }, + }, + { + name: "uses host specific docker config when currentContext matches a remote host", + env: map[string]string{ + "DOCKER_CONFIG": "/tmp/docker-config", + }, + want: map[string]string{ + common.HTTPProxy: "http://proxy.remote:4128", + "http_proxy": "http://proxy.remote:4128", + common.HTTPSProxy: "https://proxy.remote:4129", + "https_proxy": "https://proxy.remote:4129", + common.NOProxy: "remote.internal", + "no_proxy": "remote.internal", + }, + }, + { + name: "falls back to HOME docker config path", + env: map[string]string{ + "HOME": "/home/tester", + }, + want: map[string]string{ + common.HTTPProxy: "http://proxy.default:3128", + "http_proxy": "http://proxy.default:3128", + common.HTTPSProxy: "https://proxy.default:3129", + "https_proxy": "https://proxy.default:3129", + common.NOProxy: "default.internal", + "no_proxy": "default.internal", + }, + }, + } + + for _, tc := range cases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + + cfgJSON := configJSON + if tc.name == "uses host specific docker config when currentContext matches a remote host" { + cfgJSON = `{ + "currentContext": "remote-context", + "proxies": { + "default": { + "httpProxy": "http://proxy.default:3128", + "httpsProxy": "https://proxy.default:3129", + "noProxy": "default.internal" + }, + "tcp://remote.example.com:2376": { + "httpProxy": "http://proxy.remote:4128", + "httpsProxy": "https://proxy.remote:4129", + "noProxy": "remote.internal" + } + } + }` + } + + result := dockerConfigProxyEnvs(func(key string) string { + return tc.env[key] + }, func(name string) ([]byte, error) { + switch name { + case filepath.Join("/tmp/docker-config", "config.json"), filepath.Join("/home/tester", ".docker", "config.json"): + return []byte(cfgJSON), nil + default: + t.Fatalf("unexpected config path %q", name) + return nil, nil + } + }, func(contextName string) (string, error) { + switch contextName { + case "default": + return "unix:///var/run/docker.sock", nil + case "remote-context": + return "tcp://remote.example.com:2376", nil + default: + t.Fatalf("unexpected context %q", contextName) + return "", nil + } + }) + + assert.DeepEqual(t, tc.want, result) + }) + } +} + +func TestDockerConfigProxyEnvsIgnoresInvalidConfig(t *testing.T) { + t.Parallel() + + result := dockerConfigProxyEnvs(func(key string) string { + if key == "DOCKER_CONFIG" { + return "/tmp/docker-config" + } + return "" + }, func(name string) ([]byte, error) { + return []byte("{not-json"), nil + }, func(string) (string, error) { + t.Fatal("context inspection should not be called for invalid config") + return "", nil + }) + + assert.DeepEqual(t, map[string]string{}, result) +} + +func TestKindProxyEnvOverridesDockerConfig(t *testing.T) { + t.Parallel() + + cases := []struct { + name string + env map[string]string + want bool + }{ + { + name: "http proxy set", + env: map[string]string{ + common.HTTPProxy: "http://proxy.example.com:3128", + }, + want: true, + }, + { + name: "https proxy set in lower case", + env: map[string]string{ + "https_proxy": "https://proxy.example.com:3129", + }, + want: true, + }, + { + name: "only no proxy set", + env: map[string]string{ + common.NOProxy: "example.internal", + }, + want: false, + }, + { + name: "no proxy env set", + env: map[string]string{}, + want: false, + }, + } + + for _, tc := range cases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + result := kindProxyEnvOverridesDockerConfig(func(key string) string { + return tc.env[key] + }) + assert.BoolEqual(t, tc.want, result) + }) + } +} + +func TestMergeProxyEnvWithDockerConfig(t *testing.T) { + t.Parallel() + + cluster := &config.Cluster{} + cluster.Networking.ServiceSubnet = "10.96.0.0/16" + cluster.Networking.PodSubnet = "10.244.0.0/16" + + const configJSON = `{ + "proxies": { + "default": { + "httpProxy": "http://proxy.default:3128", + "httpsProxy": "https://proxy.default:3129", + "noProxy": "default.internal" + } + } + }` + + cases := []struct { + name string + env map[string]string + want map[string]string + }{ + { + name: "uses docker config when shell proxy env is unset", + env: map[string]string{ + "DOCKER_CONFIG": "/tmp/docker-config", + }, + want: map[string]string{ + common.HTTPProxy: "http://proxy.default:3128", + "http_proxy": "http://proxy.default:3128", + common.HTTPSProxy: "https://proxy.default:3129", + "https_proxy": "https://proxy.default:3129", + common.NOProxy: "default.internal,10.96.0.0/16,10.244.0.0/16", + "no_proxy": "default.internal,10.96.0.0/16,10.244.0.0/16", + }, + }, + { + name: "shell no proxy is preserved while docker fills http vars", + env: map[string]string{ + "DOCKER_CONFIG": "/tmp/docker-config", + common.NOProxy: "shell.internal", + }, + want: map[string]string{ + common.HTTPProxy: "http://proxy.default:3128", + "http_proxy": "http://proxy.default:3128", + common.HTTPSProxy: "https://proxy.default:3129", + "https_proxy": "https://proxy.default:3129", + common.NOProxy: "shell.internal,10.96.0.0/16,10.244.0.0/16", + "no_proxy": "shell.internal,10.96.0.0/16,10.244.0.0/16", + }, + }, + } + + for _, tc := range cases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + baseEnv := map[string]string{} + for _, name := range []string{common.HTTPProxy, common.HTTPSProxy, common.NOProxy, "http_proxy", "https_proxy", "no_proxy"} { + if value := tc.env[name]; value != "" { + baseEnv[name] = value + } + } + if len(baseEnv) > 0 { + noProxy := baseEnv[common.NOProxy] + if noProxy == "" { + noProxy = baseEnv["no_proxy"] + } + if noProxy != "" { + noProxy += "," + } + noProxy += cluster.Networking.ServiceSubnet + "," + cluster.Networking.PodSubnet + baseEnv[common.NOProxy] = noProxy + baseEnv["no_proxy"] = noProxy + } + + result := mergeProxyEnvWithDockerConfig(cluster, baseEnv, dockerConfigProxyEnvs(func(key string) string { + return tc.env[key] + }, func(name string) ([]byte, error) { + if name != filepath.Join("/tmp/docker-config", "config.json") { + t.Fatalf("unexpected config path %q", name) + } + return []byte(configJSON), nil + }, func(string) (string, error) { + return "", nil + })) + assert.DeepEqual(t, tc.want, result) + }) + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/pkg/cluster/internal/providers/nerdctl/images.go new/kind-0.33.0/pkg/cluster/internal/providers/nerdctl/images.go --- old/kind-0.32.0/pkg/cluster/internal/providers/nerdctl/images.go 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/pkg/cluster/internal/providers/nerdctl/images.go 2026-08-26 23:27:15.000000000 +0200 @@ -37,7 +37,7 @@ for _, image := range common.RequiredNodeImages(cfg).List() { // prints user friendly message friendlyImageName, image := sanitizeImage(image) - status.Start(fmt.Sprintf("Ensuring node image (%s) 🖼", friendlyImageName)) + status.Start(fmt.Sprintf("Ensuring node image (%s) 🖼️", friendlyImageName)) if _, err := pullIfNotPresent(logger, image, 4, binaryName); err != nil { status.End(false) return err diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/pkg/cluster/internal/providers/podman/images.go new/kind-0.33.0/pkg/cluster/internal/providers/podman/images.go --- old/kind-0.32.0/pkg/cluster/internal/providers/podman/images.go 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/pkg/cluster/internal/providers/podman/images.go 2026-08-26 23:27:15.000000000 +0200 @@ -37,7 +37,7 @@ for _, image := range common.RequiredNodeImages(cfg).List() { // prints user friendly message friendlyImageName, image := sanitizeImage(image) - status.Start(fmt.Sprintf("Ensuring node image (%s) 🖼", friendlyImageName)) + status.Start(fmt.Sprintf("Ensuring node image (%s) 🖼️", friendlyImageName)) if _, err := pullIfNotPresent(logger, image, 4); err != nil { status.End(false) return err diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/pkg/cluster/internal/providers/podman/provider.go new/kind-0.33.0/pkg/cluster/internal/providers/podman/provider.go --- old/kind-0.32.0/pkg/cluster/internal/providers/podman/provider.go 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/pkg/cluster/internal/providers/podman/provider.go 2026-08-26 23:27:15.000000000 +0200 @@ -101,13 +101,30 @@ // ListClusters is part of the providers.Provider interface func (p *provider) ListClusters() ([]string, error) { + // Select the format specifier for extracting the cluster label. + // podman 6.0.0 changed `.Labels` from a map to a slice, breaking the + // `index .Labels "key"` form; the `.Label "key"` specifier works on + // podman 5.0.0+ and across that change, but does not exist on older + // versions. See https://github.com/kubernetes-sigs/kind/issues/4201 + v, err := getPodmanVersion() + if err != nil { + return nil, errors.Wrap(err, "failed to check podman version") + } + + var format string + if v.AtLeast(version.MustParseSemantic(labelFormatVersion)) { + format = fmt.Sprintf(`{{.Label "%s"}}`, clusterLabelKey) + } else { + format = fmt.Sprintf(`{{index .Labels "%s"}}`, clusterLabelKey) + } + cmd := exec.Command("podman", "ps", "-a", // show stopped nodes // filter for nodes with the cluster label "--filter", "label="+clusterLabelKey, // format to include the cluster name - "--format", fmt.Sprintf(`{{index .Labels "%s"}}`, clusterLabelKey), + "--format", format, ) lines, err := exec.OutputLines(cmd) if err != nil { @@ -201,7 +218,7 @@ // https://github.com/containers/podman/issues/8444 if v.AtLeast(version.MustParseSemantic("2.2.0")) && v.LessThan(version.MustParseSemantic("3.0.0")) { - p.logger.Warnf("WARNING: podman version %s not fully supported, please use versions 3.0.0+") + p.logger.Warnf("WARNING: podman version %s not fully supported, please use versions 3.0.0+", v) cmd := exec.Command( "podman", "inspect", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/pkg/cluster/internal/providers/podman/util.go new/kind-0.33.0/pkg/cluster/internal/providers/podman/util.go --- old/kind-0.32.0/pkg/cluster/internal/providers/podman/util.go 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/pkg/cluster/internal/providers/podman/util.go 2026-08-26 23:27:15.000000000 +0200 @@ -57,6 +57,13 @@ const ( minSupportedVersion = "1.8.0" + + // labelFormatVersion is the first podman version that supports the `.Label` + // format specifier for `podman ps --format`. From podman 6.0.0 onward the + // `.Labels` field is a slice rather than a map, which breaks the previous + // `index .Labels` form, so `.Label` must be used on newer podman. + // See https://github.com/kubernetes-sigs/kind/issues/4201 + labelFormatVersion = "5.0.0" ) func ensureMinVersion() error { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/pkg/cmd/kind/create/cluster/createcluster.go new/kind-0.33.0/pkg/cmd/kind/create/cluster/createcluster.go --- old/kind-0.32.0/pkg/cmd/kind/create/cluster/createcluster.go 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/pkg/cmd/kind/create/cluster/createcluster.go 2026-08-26 23:27:15.000000000 +0200 @@ -83,7 +83,7 @@ &flags.Wait, "wait", time.Duration(0), - "wait for control plane node to be ready (default 0s)", + "The length of time to wait for control plane node to be ready (default 0s). Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h).", ) cmd.Flags().StringVar( &flags.Kubeconfig, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/pkg/cmd/kind/version/version.go new/kind-0.33.0/pkg/cmd/kind/version/version.go --- old/kind-0.32.0/pkg/cmd/kind/version/version.go 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/pkg/cmd/kind/version/version.go 2026-08-26 23:27:15.000000000 +0200 @@ -58,7 +58,7 @@ } // versionCore is the core portion of the kind CLI version per Semantic Versioning 2.0.0 -const versionCore = "0.32.0" +const versionCore = "0.33.0" // versionPreRelease is the base pre-release portion of the kind CLI version per // Semantic Versioning 2.0.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/site/config.toml new/kind-0.33.0/site/config.toml --- old/kind-0.32.0/site/config.toml 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/site/config.toml 2026-08-26 23:27:15.000000000 +0200 @@ -67,7 +67,7 @@ home = ["HTML", "REDIRECTS"] [params] -stable = "v0.31.0" +stable = "v0.32.0" # privacy settings [privacy] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/site/content/_index.md new/kind-0.33.0/site/content/_index.md --- old/kind-0.32.0/site/content/_index.md 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/site/content/_index.md 2026-08-26 23:27:15.000000000 +0200 @@ -83,7 +83,7 @@ - kind supports building Kubernetes release builds from source - support for make / bash or docker, in addition to pre-published builds - kind supports Linux, macOS and Windows -- kind is a [CNCF certified conformant Kubernetes installer](https://landscape.cncf.io/?selected=kind) +- kind is a [CNCF certified conformant Kubernetes installer](https://landscape.cncf.io/?group=projects-and-products&item=platform--certified-kubernetes-installer--kind) ### Code of conduct diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/site/content/docs/user/local-registry.md new/kind-0.33.0/site/content/docs/user/local-registry.md --- old/kind-0.32.0/site/content/docs/user/local-registry.md 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/site/content/docs/user/local-registry.md 2026-08-26 23:27:15.000000000 +0200 @@ -27,8 +27,13 @@ 3. Then we'll push it to the registry `docker push localhost:5001/hello-app:1.0` 4. And now we can use the image `kubectl create deployment hello-server --image=localhost:5001/hello-app:1.0` +> **NOTE**: The example commands above use Docker. If you are using Podman +> and see `http: server gave HTTP response to HTTPS client` when pushing to +> `localhost:5001`, configure Podman to treat the local registry as insecure, +> or push with `podman push --tls-verify=false localhost:5001/hello-app:1.0`. + If you build your own image and tag it like `localhost:5001/image:foo` and then use -it in kubernetes as `localhost:5001/image:foo`. +it in kubernetes as `localhost:5001/image:foo`. If for some reason you have code running *inside* of a pod within the cluster that needs to use this registry directly (e.g. to build and push an image) then that diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/site/content/docs/user/private-registries.md new/kind-0.33.0/site/content/docs/user/private-registries.md --- old/kind-0.32.0/site/content/docs/user/private-registries.md 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/site/content/docs/user/private-registries.md 2026-08-26 23:27:15.000000000 +0200 @@ -53,6 +53,81 @@ hostPath: /path/to/my/secret.json {{< /codeFromInline >}} +**Important**: The mounted file must contain the actual base64-encoded +credentials in the `auths` field. It cannot reference an external credential +store or helper. + +Many systems store docker credentials outside of `config.json` using a +credential helper (e.g. `"credsStore": "desktop"` on Docker Desktop, +`"credsStore": "osxkeychain"` on macOS, or `"credsStore": "secretservice"` on +Linux). If your `~/.docker/config.json` contains a `credsStore` or `credHelpers` +key, the credentials themselves are **not** in the file and mounting it into a +kind node will not work because the credential helper binary is not present +inside the node. + +To check whether your config contains plain credentials or a credential store +reference: + +```sh +cat ~/.docker/config.json +``` + +A config with plain credentials looks like: + +```json +{ + "auths": { + "myregistry.example.com": { + "auth": "dXNlcjpwYXNzd29yZA==" + } + } +} +``` + +A config that uses an external credential store (which will **not** work when +mounted) looks like: + +```json +{ + "auths": {}, + "credsStore": "desktop" +} +``` + +To generate a config file with plain credentials, create a temporary config that +bypasses the credential store and log in with it: + +```sh +# Create a temp dir to hold the plain-credential config +DOCKER_CONFIG=$(mktemp -d) +export DOCKER_CONFIG + +# Seed an empty auths entry to disable the credential store +cat <<EOF >"${DOCKER_CONFIG}/config.json" +{ + "auths": { "myregistry.example.com": {} } +} +EOF + +# Log in — credentials will be written as plain base64 auth in the file +docker login myregistry.example.com + +# Use ${DOCKER_CONFIG}/config.json as your hostPath +``` + +For registries that use short-lived or token-based authentication (such as Azure +Container Registry with OAuth tokens), the static mount approach may not be +reliable once the token expires. For ACR, prefer logging in with a +[service principal][acrServicePrincipal] whose credentials are long-lived: + +```sh +docker login myregistry.azurecr.io \ + --username <service-principal-id> \ + --password <service-principal-password> +``` + +[acrServicePrincipal]: https://learn.microsoft.com/en-us/azure/container-registry/container-registry-auth-service-principal + #### Use an Access Token A credential can be programmatically added to the nodes at runtime. @@ -110,4 +185,4 @@ - |- [plugins."io.containerd.grpc.v1.cri".registry] config_path = "/etc/containerd/certs.d" -{{< /codeFromInline >}} \ No newline at end of file +{{< /codeFromInline >}} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kind-0.32.0/site/content/docs/user/quick-start.md new/kind-0.33.0/site/content/docs/user/quick-start.md --- old/kind-0.32.0/site/content/docs/user/quick-start.md 2026-06-02 18:28:54.000000000 +0200 +++ new/kind-0.33.0/site/content/docs/user/quick-start.md 2026-08-26 23:27:15.000000000 +0200 @@ -84,7 +84,7 @@ #### Installing with `go install` -When installing with [Go](https://golang.org/) please use the latest stable Go release. At least go1.16 or greater is required. +When installing with [Go](https://golang.org/) please use the latest stable Go release. To install use: `go install sigs.k8s.io/kind@{{< stableVersion >}}`. @@ -131,6 +131,11 @@ winget install Kubernetes.kind {{< /codeFromInline >}} +On Arch Linux via pacman (https://archlinux.org/packages/extra/x86_64/kind/) +{{< codeFromInline lang="bash" >}} +sudo pacman -Syu kind +{{< /codeFromInline >}} + ## Discovering Additional Command Options kind provides built-in help for all commands and subcommands. ++++++ kind.obsinfo ++++++ --- /var/tmp/diff_new_pack.LFOELQ/_old 2026-08-28 19:55:00.170958450 +0200 +++ /var/tmp/diff_new_pack.LFOELQ/_new 2026-08-28 19:55:00.178958729 +0200 @@ -1,5 +1,5 @@ name: kind -version: 0.32.0 -mtime: 1780417734 -commit: cda67ef8588f6bfdac5358233f2471cb2149ecaf +version: 0.33.0 +mtime: 1787779635 +commit: 407a9675e6d9af1200b5f57f9ca52ec6cdacce74 ++++++ vendor.tar.gz ++++++
