Skip to content

Kubernetes control-plane restart fails after node IP rotation #2156

Description

@mxschmitt

Summary

A single-node Kubernetes cluster created by the Apple container K8s plugin
does not restart after its VM receives a different IPv4 address. Address
rotation is expected; the Kubernetes provider does not preserve the kind
bootstrap contract or configure an address-independent in-VM API endpoint.

Environment

  • macOS on Apple Silicon
  • apple/container 1.3.0 (d6de569)
  • kindest/node:v1.35.5
  • One VM with both control-plane and worker roles
  • No workload or custom DNS configuration

Minimal reproduction

container k8s create --name k8s-repro
container exec k8s-repro cat /kind/old-ipv4
container stop k8s-repro
container k8s start --name k8s-repro

On a clean runtime, the first ordinary restart changed
192.168.64.2 -> 192.168.64.3 and failed before the K8s plugin could perform
its readiness checks:

INFO: detected IPv4 address: 192.168.64.3
INFO: detected old IPv4 address: 192.168.64.2
error: unable to read config from "/kind/kubeadm.conf":
open /kind/kubeadm.conf: no such file or directory

Root cause

There are two independent restart requirements:

  1. The plugin runs kubeadm with /etc/kubernetes/kubeadm-config.yaml, while a
    kind node expects its provider to create /kind/kubeadm.conf for restart
    reconciliation. The kind-owned file was never created; kubeadm did not
    consume or delete it.
  2. Without controlPlaneEndpoint, kubeadm persists the VM address in clients
    such as admin.conf and kube-proxy. In an ablation test, adding only the kind
    file let kind repair API-server state, but kube-proxy continued dialing the
    retired address and CoreDNS remained unready.

Expected behavior

The node should recover after intentional address rotation without requiring a
sticky IP. kind should reconcile address-dependent advertise/certificate
state, while persistent clients use an address-independent endpoint.

Validated fix

PR #2158 writes and uses /kind/kubeadm.conf directly and configures
controlPlaneEndpoint: 127.0.0.1:6443 for clients inside the current one-VM
cluster. After rotation, kind rewrites the node advertise address to the new
VM address while in-VM clients retain loopback. Host kubeconfig export remains
unchanged.

The fix is intentionally limited to newly created single-node clusters. It
does not add sticky addressing, DNS, a proxy, broad start-time rewriting, or
migration for clusters created by older releases. A future multi-node topology
will need a stable shared DNS, VIP, or load-balancer endpoint.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions