Kubernetes control-plane restart fails after node IP rotation
- Dominant language
- Swift
- Stars
- 49.9k
- Forks
- 1.8k
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 22
Description
## 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
```sh
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:
```text
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.
Contributor guide
Research direction
Reproduce with `container k8s create`, the `/kind/old-ipv4` check, and a stop/start cycle, then inspect how the Kubernetes provider handles `/etc/kubernetes/kubeadm-config.yaml` and `/kind/kubeadm.conf`. Compare the behavior with PR #2158; done means a newly created single-node cluster recovers after its VM address changes and its in-VM clients remain ready.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- kubernetes, swift
- Domain
- devops, infrastructure
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 15/100