canonical / canonical/cloud-init
DataSourceEc2: cloud-init breaks static IPs when used with dhcpcd and multiple NICs
- Dominant language
- Python
- Stars
- 3.8k
- Forks
- 1.1k
- Avg merge
- 2d 23h
- Merged PRs (30d)
- 18
Description
# Bug report
When an EC2 instance has multiple NICs, cloud-init sets up policy routing for them. That runs after networkd, and if it uses dhcpcd, it breaks static IPs added by networkd.
Here's the sequence:
1. cloud-init-local finishes
2. networkd starts, configures static (and any other dhcp) IPs
3. cloud-init-network runs:
1. dhcpcd is started to find the gateway, adding the assigned IP with a finite lifetime
2. dhcpcd exits, leaving the lifetime in place
4. when the lifetime is up, the kernel removes the address
The interface is now down. networkd marks it degraded, and needs a down/up or restart to fix it.
## Steps to reproduce the problem
Create a VM with multiple NICs, assign one a static IP. I used opentofu to create an ENI, and generate the user-data for the static config. But it will also work if you change the VM's network config by hand.
## Environment details
Affected environments:
- cloud-init 25.1.4 from Debian 13, using dhcpcd
Unaffected:
- cloud-init 22.4.2 from Debian 12, using dhclient
(isc dhclient was deprecated in Debian 13 - so isn't available)
## cloud-init logs
```
$ sudo cloud-init query userdata
#cloud-config
write_files:
- path: /etc/netplan/50-cloud-init.yaml
content: |
network:
version: 2
ethernets:
ens5:
match:
name: ens5
dhcp4: true
ens6:
match:
macaddress: 0e:50:89:67:df:57
addresses:
- 172.31.76.52/20
dhcp4: false
dhcp6: false
set-name: "ens6"
runcmd:
- netplan apply
power_state:
mode: reboot
$ sudo netplan get
network:
version: 2
ethernets:
ens5:
match:
name: "ens5"
dhcp4: true
ens6:
match:
macaddress: "0e:50:89:67:df:57"
addresses:
- "172.31.76.52/20"
dhcp4: false
dhcp6: false
set-name: "ens6"
$ ip addr list dev ens6
...
3: ens6: mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 0e:50:89:67:df:57 brd ff:ff:ff:ff:ff:ff
altname enp0s6
altname enx0e508967df57
inet 172.31.76.52/20 brd 172.31.79.255 scope global dynamic ens6
valid_lft 3566sec preferred_lft 3116sec
inet6 fe80::c50:89ff:fe67:df57/64 scope link proto kernel_ll
valid_lft forever preferred_lft forever
$ journalctl -b --grep "dhcp|networkd" | cat
Aug 01 02:56:59 ip-172-31-59-213 systemd[1]: Listening on systemd-networkd.socket - Network Service Netlink Socket.
Aug 01 02:57:01 ip-172-31-59-213 dhcpcd[577]: dhcpcd-10.1.0 starting
Aug 01 02:57:02 ip-172-31-59-213 dhcpcd[584]: control command: dhcpcd --dumplease --ipv4only ens5
Aug 01 02:57:08 ip-172-31-59-213 dhcpcd[608]: dhcpcd-10.1.0 starting
Aug 01 02:57:08 ip-172-31-59-213 dhcpcd[611]: control command: dhcpcd --dumplease --ipv4only ens6
Aug 01 02:57:08 ip-172-31-59-213 systemd[1]: Starting systemd-networkd.service - Network Configuration...
Aug 01 02:57:08 ip-172-31-59-213 systemd[1]: Started systemd-networkd.service - Network Configuration.
Aug 01 02:57:09 ip-172-31-59-213 systemd[1]: Starting systemd-networkd-persistent-storage.service - Enable Persistent Storage
in systemd-networkd...
Aug 01 02:57:09 ip-172-31-59-213 systemd[1]: Starting systemd-networkd-wait-online.service - Wait for Network to be
Configured...
Aug 01 02:57:09 ip-172-31-59-213 systemd[1]: Finished systemd-networkd-persistent-storage.service - Enable Persistent Storage
in systemd-networkd.
Aug 01 02:57:09 ip-172-31-59-213 systemd-networkd[627]: ens5: DHCPv4 address 172.31.59.213/20, gateway 172.31.48.1 acquired
from 172.31.48.1
Aug 01 02:57:11 ip-172-31-59-213 systemd[1]: Finished systemd-networkd-wait-online.service - Wait for Network to be Configured.
Aug 01 02:57:11 ip-172-31-59-213 dhcpcd[647]: dhcpcd-10.1.0 starting
Aug 01 02:57:12 ip-172-31-59-213 dhcpcd[650]: control command: dhcpcd --dumplease --ipv4only ens6
Aug 01 02:57:13 ip-172-31-59-213 dbus-daemon[693]: [system] Activating systemd to hand-off: service
name='org.freedesktop.hostname1' unit='dbus-org.freedesktop.hostname1.service' requested by ':1.0' (uid=998 pid=627
comm="/usr/lib/systemd/systemd-networkd")
Aug 01 03:03:49 ip-172-31-59-213 dhcpcd[1214]: dhcpcd-10.1.0 starting
Aug 01 03:03:50 ip-172-31-59-213 dhcpcd[1217]: control command: dhcpcd --dumplease --ipv4only ens5
```
Contributor guide
Research direction
Start by tracing the cloud-init-network path that invokes dhcpcd for multiple NICs, then reproduce the reported sequence with networkd and a static address. Done means the static address remains configured after the dhcpcd lease lifetime expires and networkd does not mark the interface degraded.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, python
- Domain
- cloud, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100