Skip to main content

Static IP for node1 with Netplan

A DHCP lease that moves node1's address breaks two things at once: the MicroK8s API certificates (SANs are pinned to the node IP) and every NPM proxy host on the VPS pointing at the overlay peer. This pins the address with Netplan.

Starting state​

Ubuntu with systemd-networkd as the renderer (NetworkManager inactive), one config file at /etc/netplan/00-installer-config.yaml.

InterfaceKindStateAddress
enp4s0EthernetNO-CARRIER—
wlp9s0Wi-FiUP, DHCP192.168.1.5/24, gw 192.168.1.1
wt0NetBirdUP100.66.50.60/16
ip -o link show; ip -4 -o addr show; ip route
systemctl is-active systemd-networkd NetworkManager
Keep the address the node already has

MicroK8s puts the node IP in its API-server cert SANs and Calico registers the node by it. Moving to a different IP means regenerating certs (sudo microk8s refresh-certs --cert server.crt) and re-checking Calico. Also make sure the address is outside the router's DHCP pool, or reserved for the NIC's MAC.

Prerequisite for Wi-Fi​

wifis: under the networkd renderer needs wpasupplicant — netplan doesn't speak WPA itself. netplan generate writes /run/netplan/wpa-wlp9s0.conf plus a netplan-wpa-wlp9s0.service that wraps wpa_supplicant.

dpkg -l wpasupplicant >/dev/null 2>&1 && echo present || sudo apt install -y wpasupplicant
sudo apt install -y iw # optional, but the only way to debug association later
Missing wpasupplicant fails silently

netplan apply still exits 0. The generated unit fails, the interface never associates, and no address appears — with no error pointing at the cause. Confirm with systemctl status netplan-wpa-wlp9s0.service rather than trusting the exit code.

Ubuntu Server's minimal profile omits it; desktop installs usually get it via NetworkManager, which is inactive here. Also check linux-firmware is present — a missing chipset blob produces the identical symptom. Skip this section entirely if Wi-Fi already associates on the box, which proves both are installed.

Option 1 — Wi-Fi only​

No cable, no cluster disruption.

/etc/netplan/00-installer-config.yaml
network:
version: 2
renderer: networkd
wifis:
wlp9s0:
dhcp4: false
addresses: [ 192.168.1.5/24 ]
routes:
- { to: default, via: 192.168.1.1 }
nameservers:
addresses: [ 1.1.1.1, 8.8.8.8 ]
access-points:
"YOUR_SSID":
password: "YOUR_PSK"

Option 2 — Ethernet only (best for a k8s node)​

Wi-Fi roaming and power-save cause intermittent API timeouts. Confirm carrier before applying (ip -o link show enp4s0 must not say NO-CARRIER) or the box drops off the network.

/etc/netplan/00-installer-config.yaml
network:
version: 2
renderer: networkd
ethernets:
enp4s0:
dhcp4: false
addresses: [ 192.168.1.5/24 ]
routes:
- { to: default, via: 192.168.1.1 }
nameservers:
addresses: [ 1.1.1.1, 8.8.8.8 ]

Option 3 — Both, Ethernet preferred​

Wired carries the cluster address; Wi-Fi holds a second address behind a higher-metric default route, used only when the cable is out.

/etc/netplan/00-installer-config.yaml
network:
version: 2
renderer: networkd
ethernets:
enp4s0:
dhcp4: false
optional: true # don't block boot waiting for carrier
addresses: [ 192.168.1.5/24 ]
routes:
- { to: default, via: 192.168.1.1, metric: 100 }
nameservers:
addresses: [ 1.1.1.1, 8.8.8.8 ]
wifis:
wlp9s0:
dhcp4: false
optional: true
addresses: [ 192.168.1.4/24 ]
routes:
- { to: default, via: 192.168.1.1, metric: 600 }
nameservers:
addresses: [ 1.1.1.1, 8.8.8.8 ]
access-points:
"YOUR_SSID":
password: "YOUR_PSK"
The node IP moves on failover

The interfaces must not share 192.168.1.5 — duplicate addresses on one L2 segment cause ARP conflicts. So with the cable out, the node's source address becomes 192.168.1.4, which isn't in the cert SANs: SSH and NetBird keep working, but kubelet ↔ API-server may error until the cable is back. This is a rescue path, not HA. Add IP.4 = 192.168.1.4 to /var/snap/microk8s/current/certs/csr.conf.template and run sudo microk8s refresh-certs --cert server.crt to make failover clean.

Applying safely over SSH​

Changing the network through the link you're connected on can lock you out.

Interactive — auto-reverts unless you press Enter:

sudo netplan try --timeout 120

Non-interactive — an armed rollback that survives losing the link:

sudo mkdir -p /root/netplan-backup
sudo cp -a /etc/netplan/00-installer-config.yaml /root/netplan-backup/

# edit the file, then validate WITHOUT applying
sudo chmod 600 /etc/netplan/00-installer-config.yaml
sudo netplan generate

sudo systemd-run --on-active=180 --unit=netplan-rollback \
/bin/bash -c 'cp -a /root/netplan-backup/00-installer-config.yaml /etc/netplan/ && netplan apply'

sudo netplan apply
sudo systemctl stop netplan-rollback.timer # disarm, once you know you're still reachable

If the last line never runs, the old config comes back on its own after 180 s.

Preserve the Wi-Fi PSK

The file is root:root 0600 because it holds the Wi-Fi password. Copy the whole access-points: block out of the backup rather than retyping it, and keep mode 600.

Verify​

ip -4 -o addr show enp4s0 wlp9s0 # static, no "dynamic" flag
ip route # default via 192.168.1.1 dev enp4s0 metric 100
ping -c2 1.1.1.1
netbird status # Management/Signal: Connected
microk8s kubectl get nodes -o wide # INTERNAL-IP still 192.168.1.5

Troubleshooting​

SymptomCause / fix
Locked out after netplan applyThe armed netplan-rollback unit restores the backup after 180 s. Otherwise restore from /root/netplan-backup/ at the console.
Wi-Fi never associates, no errorwpasupplicant not installed — netplan apply exits 0 regardless. Check systemctl status netplan-wpa-wlp9s0.service.
Wi-Fi never associatesThe access-points: block was lost or mis-indented. Restore from the backup.
Both up but traffic uses Wi-FiMetrics inverted — the lower metric wins.
x509 errors mentioning an IPNode IP moved away from the cert SAN. Move it back, or add it to csr.conf.template + refresh-certs --cert server.crt.
NetBird peer unreachablesudo netbird down && sudo netbird up to rebind wt0 to the new source address.
Random disconnects / conflictsThe static IP sits inside the router's DHCP pool.