Netplan vs. NetworkManager is not an academic question but an operational risk: when two components attempt to control the same network resources, outages, inconsistent IP assignments and issues for services like Kubernetes follow. This guide is aimed at administrators, system engineers and operators and explains in practical steps how to detect conflicts, enforce a clear renderer policy, migrate Kubernetes nodes safely, set up automated validations and prepare fast rollbacks.
Why Renderer‑Policy is so important
Netplan is a declarative frontend: YAML files under /etc/netplan describe the desired network topology. Netplan translates these specifications at runtime into configuration files for a renderer. Renderers are the actual managers — typically systemd-networkd (often abbreviated to networkd) or NetworkManager. NetworkManager is a persistent daemon with its own state and policy. If the organization lacks a clear policy, race conditions occur because netplan writes the renderer configuration during deployment while NetworkManager concurrently manages connections or cloud‑init injects different settings during boot.
Diagnosis: systematic and non-invasive
Start with facts: what is currently configured effectively in the kernel? Then check which managers are active and how Netplan generates the runtime settings.
Basic commands for status and visibility
ip -br link
ip -br addr
ip route showThis view is independent of Netplan or NetworkManager and shows the current state in the kernel.
Manager perspectives
systemctl is-active NetworkManager.service || true
systemctl is-active systemd-networkd.service || true
nmcli -t -f DEVICE,STATE device status
networkctl --no-legend --allnmcli provides NetworkManager’s view, networkctl that of systemd‑networkd. Contradictions here are a clear indicator of competing control.
Failure patterns and their causes
Important symptoms and typical causes — briefly explained:
- IP changes after reboot: either multiple DHCP clients are active or cloud‑init applies different values on first boot.
- Default route disappears: the renderer has different routing policy/metric, or a connection is being disabled.
- Kubernetes Node NotReady: the CNI interface was recreated or NetworkManager altered a bridge/bond. CNI plugins expect static host relationships.
- Logs with „Device is already managed“: NetworkManager discovered a device that netplan intended to assign to networkd.
Concrete checks when something goes wrong
If the causes are not obvious, proceed sequentially:
- Check timings and order: compare
journalctlbefore and after boots or configuration changes. - Observe DHCP traffic to detect parallel clients.
- Inspect Netplan generation to see what is actually written to the renderer.
journalctl -b -u NetworkManager -u systemd-networkd --no-pager | sed -n '1,400p'
# Observe DHCP and ARP (short sample)
tcpdump -n -i ens3 arp or port 67 or port 68 -c 200
# Generate Netplan without applying
netplan generate
ls -l /run/systemd/network /run/NetworkManager 2>/dev/nullConfiguration examples: How the renderer is controlled
Netplan YAML declaratively sets the renderer. Example: forcing networkd as the renderer.
network:
version: 2
renderer: networkd
ethernets:
ens3:
dhcp4: true
optional: true
After you have deployed the file, use netplan generate and netplan apply. netplan generate shows which files would be generated; netplan apply applies them. For critical hosts, netplan try is useful — it automatically rolls the change back if you do not confirm within a timer.
# Interaktives Anwenden mit Fallback
netplan try
# Oder idempotent in Automatisierung
netplan generate && netplan applyNetworkManager: Keyfile example and unmanaged-devices
NetworkManager uses keyfiles for persistent connections. If NetworkManager must remain active but should ignore certain CNI interfaces, create a configuration in /etc/NetworkManager/conf.d/:
# /etc/NetworkManager/conf.d/10-unmanaged.conf
[main]
plugins=keyfile
[keyfile]
unmanaged-devices=interface-name:cni0;interface-name:flannel.1;interface-name:calico0
This entry prevents NetworkManager from managing CNI bridges/interfaces — important for Kubernetes.
systemd-networkd: .network example
If you prefer networkd as the renderer, .network files can be used for finer-grained host settings (usually unnecessary when Netplan generates everything centrally, but useful for special rules).
# /etc/systemd/network/10-ens3.network
[Match]
Name=ens3
[Network]
DHCP=yes
IPv6AcceptRA=yes
[Route]
Gateway=192.0.2.1
A direct .network file is read by networkd; Netplan generates such files automatically when it is set as the networkd renderer.
Migration strategy: safe, incremental, reversible
When changing in production environments, a conservative approach is mandatory. Recommended steps:
- Define policy: specify host groups (e.g. k8s-worker, db-server, workstation) and their renderer.
- Canary rollout: choose 1–3 noncritical nodes as a test case.
- Create backups: back up /etc/netplan, /etc/NetworkManager, cloud-init configurations.
- Change window and out-of-band access: ensure KVM/IPMI/serial console.
- Automated validation: check IP, routes, CNI, kubelet status, and service health.
- Gradual rollout and monitoring: observe metrics, set alerts for defined patterns.
Example validation script (Basic)
#!/usr/bin/env bash
set -euo pipefail
IF=ens3
# IP prüfen
ip addr show "$IF" | grep -q "inet " || { echo "IP fehlt"; exit 2; }
# Default-Route prüfen
ip route show default | grep -q "dev $IF" || { echo "Default-Route fehlt"; exit 3; }
# Kubelet prüfen (nur auf K8s-Nodes)
systemctl is-active --quiet kubelet || { echo "kubelet nicht aktiv"; exit 4; }
# CNI-Interfaces prüfen
ip link show | grep -E "cni|calico|flannel" >/dev/null || echo "Keine CNI-Interfaces gefunden (ist das ok?)"
echo "Validation ok"
This script is intentionally simple; extend it with Prometheus checks, an API query to the kube-apiserver, or test pods if you integrate it into CI/CD.
Kubernetes-specific details and pitfalls
Kubernetes makes network changes immediately visible: pods may lose connectivity, CNI‑plug‑ins can reinitialize and kubelet checks host network conditions. Special notes:
- Drain and uncordon: For major network changes always drain (
kubectl drain) and uncordon after validation. - Account for DaemonSets: CNI daemons run on every node; manage update sequences so that CNI does not RESTart simultaneously.
- IP masquerade and forwarding: Check iptables/nftables rules, as NM occasionally adjusts firewall relationships.
# Sicheres Node-Update Ablauf (Kurzform)
kubectl drain node01 --ignore-daemonsets --delete-local-data
# Änderungen anwenden
# Validieren: CNI Pods, kubelet, Netztests
kubectl uncordon node01
Monitoring: Metriken, Alerts und sinnvolle Thresholds
Configure monitoring so that not every flap triggers a pager. Examples of relevant metrics:
- Interface flaps per host in 10 minutes (>5 → warning).
- DHCP‑renewals per MAC (>3 in 5 minutes → indicator of competing clients).
- Kubernetes Node NotReady events after network changes (critical).
- Service RESTart loops for NetworkManager or systemd‑networkd (alert at host level).
Typische Edge‑Cases und wie Sie sie lösen
Some issues occur only under specific conditions — the most common are:
- Provider images: Cloud images sometimes have preconfigured NetworkManager profiles. Inspect and clean these before rollout.
- Persistent interface naming: udev/hardware changes can rename interfaces. Prefer MAC‑based matching in Netplan or .network if you anticipate risk.
- VLANs, bridging, and bonding: NetworkManager and networkd differ in syntax and behavior; test bonding failover and LACP in a test environment.
VLAN + Bond Beispiel (Netplan)
network:
version: 2
renderer: networkd
ethernets:
ens3: {}
bonds:
bond0:
interfaces: [ens3]
parameters:
mode: 802.3ad
mii-monitor-interval: 100
vlans:
vlan100:
id: 100
link: bond0
dhcp4: true
Rollback‑Praxis: Vorbereitung ist alles
A rollback often takes longer than the change. Prepare the following artifacts:
- Backups:
/root/netcfg-backupswith unique timestamps. - Rollback scripts: Automated steps that RESTore files and RESTart services.
- Out‑of‑band access and test plan: What will be measured to confirm success?
# Backup (bevor Änderungen gemacht werden)
mkdir -p /root/netcfg-backups/$(date +%F_%H%M)
cp -a /etc/netplan /root/netcfg-backups/$(date +%F_%H%M)/
cp -a /etc/NetworkManager /root/netcfg-backups/$(date +%F_%H%M)/ || true
cp -a /etc/cloud /root/netcfg-backups/$(date +%F_%H%M)/ || true
Operational Recommendations — kurz und praktisch
- Define a clear renderer policy for each host group and record it in CM/GitOps.
- Use
netplan tryon critical hosts to automatically roll back if network loss occurs. - Protect CNI interfaces via
unmanaged-devicesbefore allowing NetworkManager. - Test all changes in a staging environment, including node drains for Kubernetes.
- Implement automatic validations and alerts that react to patterns rather than single events.
Fazit
Netplan vs. NetworkManager is in practice a question of discipline: good operations maintain a Single Source of Truth, protect CNI‑Devices, automate validations and keep a tested rollback plan. Technical measures (Netplan‑Renderer, unmanaged‑devices, Node‑Drain) together with organizational rules (host groups, Change‑Windows, out‑of‑band access) minimize risk and keep networks maintainable. Plan your migration in phases, document decisions and measure the impacts automatically — that way your network remains reliable and reproducible.
Netplan vs. NetworkManager: Integration, security and drift strategies
In addition to the renderer policy you should address three operational levels: integration into configuration management/GitOps, audit and hardening against unintended runtime changes, and secure testing and validation procedures. These aspects prevent configuration drift, unauthorized D‑Bus changes or provider agents from undermining your network topology.
Detect and remediate configuration drift proactively
Do not assume that files in /etc automatically match your Git repo. A short, automatable check job detects deviations and can, if required, RESTore an approved configuration or trigger an alert.
#!/usr/bin/env bash
set -euo pipefail
REPO=/srv/git/netcfg.git
TMP=/tmp/netcheck
rm -rf "$TMP" && git clone "file://$REPO" "$TMP"
if ! diff -r "$TMP/etc/netplan" /etc/netplan >/dev/null; then
echo "Drift detected: /etc/netplan differs from Git" >&2
# optional: RESTore or trigger automation
exit 2
fi
echo "Netplan OK"Such jobs run as cron, systemd‑timer or in the CI/CD pipeline. Decide whether to perform automatic correction (git checkout) or only alerting — both have pros and cons with respect to change control.
Security aspects: D‑Bus, PolicyKit and service lockdown
NetworkManager exposes control functions via D‑Bus; that facilitates API‑driven changes but also opens attack surfaces. RESTrict network changes through PolicyKit rules, strict file permissions and, where appropriate, service masking.
# NetworkManager temporär sperren (wird beim Maskieren nicht gestartet)
sudo systemctl mask NetworkManager
# Zurücksetzen
sudo systemctl unmask NetworkManager && sudo systemctl start NetworkManagerFor audit‑capable environments log all changes to /etc/netplan and the D‑Bus calls (auditd or journald with field filters). This provides a traceable change chain for compliance and post‑mortem.
Sandbox testing with network namespaces
Before you apply rules in production, simulate behaviour in isolation with veth pairs and netns. This allows you to test DHCP, VLANs or routing policy without disturbing host interfaces.
# Einfacher Test: veth-Paar und DHCP-Client in Namespace
ip netns add tn
ip link add veth0 type veth peer name veth1
ip link set veth1 netns tn
ip addr add 192.0.2.1/24 dev veth0; ip link set veth0 up
ip netns exec tn ip link set lo up; ip netns exec tn ip link set veth1 up
# Im Namespace kann man jetzt dhclient, ip route etc. testen
ip netns exec tn dhclient -v veth1 & sleep 5; ip netns exec tn ip addr showAutomation: idempotent tasks and preflight checks
Use idempotent modules/tasks in Ansible or your CM and add preflight checks that validate kernel state (ip addr, ip route, CNI bridges). Apply changes only when all preflights succeed; otherwise abort and raise an alert.
# Example (Ansible, simplified form)
- name: Deploy Netplan from repo
hosts: k8s_workers
tasks:
- name: Ensure /etc/netplan matches repo
copy:
src: files/50-netcfg.yaml
dest: /etc/netplan/50-netcfg.yaml
owner: root
mode: '0644'
notify: Apply netplanCombine integration, security and test automation: only in this way will you achieve reproducible network configurations, avoid unexpected changes by third parties (provider agents, user processes) and retain control over Netplan vs. NetworkManager in day-to-day operations.
For this topic, the conflict between Netplan renderers and NetworkManager is also important. The article contextualizes these aspects and shows what matters in day-to-day operations.