The containers don't get IPv4 addresses and networking doesn't work from within the containers. The problem is the same on Debian, Ubuntu and Alpine.
❯ lxc list
+------------+---------+------+----------------------------------------------+------------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+------------+---------+------+----------------------------------------------+------------+-----------+
| buster | RUNNING | | fd42:3cb:5f02:b33b:216:3eff:fe5a:710e (eth0) | PERSISTENT | 0 |
+------------+---------+------+----------------------------------------------+------------+-----------+
| first | RUNNING | | fd42:3cb:5f02:b33b:216:3eff:fe34:c776 (eth0) | PERSISTENT | 0 |
+------------+---------+------+----------------------------------------------+------------+-----------+
| ubuntu1904 | RUNNING | | fd42:3cb:5f02:b33b:216:3eff:fe67:ccf1 (eth0) | PERSISTENT | 0 |
+------------+---------+------+----------------------------------------------+------------+-----------+
❯ lxc exec buster bash
root@buster:~# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::216:3eff:fe5a:710e prefixlen 64 scopeid 0x20<link>
inet6 fd42:3cb:5f02:b33b:216:3eff:fe5a:710e prefixlen 64 scopeid 0x0<global>
ether 00:16:3e:5a:71:0e txqueuelen 1000 (Ethernet)
RX packets 24 bytes 4026 (3.9 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 19 bytes 2934 (2.8 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
root@buster:~# apt update
Err:1 http://deb.debian.org/debian buster InRelease
Temporary failure resolving 'deb.debian.org'
The reason for this, was that my firewall blocked the requests from
the DHCP server lxd
was running to assign IPs to the
containers. snap
who's running lxd
on my Debian system used the
wrong command to interact with my firewall. To solve this, I did:
# update-alternatives --set iptables /usr/sbin/iptables-legacy
# update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
# snap restart lxd
Now, my containers got IPv4 addresses and container networking worked like a charm:
❯ lxc list
+------------+---------+----------------------+----------------------------------------------+------------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+------------+---------+----------------------+----------------------------------------------+------------+-----------+
| buster | RUNNING | 10.186.38.200 (eth0) | fd42:3cb:5f02:b33b:216:3eff:fe5a:710e (eth0) | PERSISTENT | 0 |
+------------+---------+----------------------+----------------------------------------------+------------+-----------+
| first | RUNNING | 10.186.38.197 (eth0) | fd42:3cb:5f02:b33b:216:3eff:fe34:c776 (eth0) | PERSISTENT | 0 |
+------------+---------+----------------------+----------------------------------------------+------------+-----------+
| ubuntu1904 | RUNNING | 10.186.38.153 (eth0) | fd42:3cb:5f02:b33b:216:3eff:fe67:ccf1 (eth0) | PERSISTENT | 0 |
+------------+---------+----------------------+----------------------------------------------+------------+-----------+
Still no IPv4
On a different Debian system, I still couldn't get an IP, even after
updating iptables
alternatives outlined in the above section.
After investigating this, I discovered that I had a DNS server running:
root@geronimo ~ # netstat -nlp --tcp | grep -w 53
tcp 0 0 0.0.0.0:53 0.0.0.0:* LISTEN 794/dnsmasq
tcp6 0 0 :::53 :::* LISTEN 794/dnsmasq
This causes conflicts with lxd
, which also wants to fire up its own
DNS server. Since I had to need for the DNS server (I'd forgotten why
I installed it in the first place), I removed it and restarted lxd
:
# apt-get remove dnsmasq
# snap restart lxd
And lo and behold, my containers were started again, this time with a shiny IPv4 address!
If the lxd containers still doesn't get an IP
Could be your kernel isn't new enough. LXD will default to
iptables-legacy
if you're running a kernel older than 5.x
. lxd
will then add rules to iptables-legacy
, even though the rest of your
system is using iptables-nft
and you have set
/etc/alternatives/iptables
to point to iptables-nft
.
You can see this if you do:
# iptables-nft -L
..all your regular rules...
But LXD has still used the old iptables
:
# iptables-legacy -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:domain /* generated for LXD network lxdbr0 */
ACCEPT udp -- anywhere anywhere udp dpt:domain /* generated for LXD network lxdbr0 */
ACCEPT udp -- anywhere anywhere udp dpt:bootps /* generated for LXD network lxdbr0 */
Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere /* generated for LXD network lxdbr0 */
ACCEPT all -- anywhere anywhere /* generated for LXD network lxdbr0 */
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp spt:domain /* generated for LXD network lxdbr0 */
ACCEPT udp -- anywhere anywhere udp spt:domain /* generated for LXD network lxdbr0 */
ACCEPT udp -- anywhere anywhere udp spt:bootps /* generated for LXD network lxdbr0 */
To remedy this, clear all the rules of both tables:
for ipt in iptables iptables-legacy ip6tables ip6tables-legacy; do
$ipt --flush; $ipt --flush -t nat;
$ipt --flush -t mangle;
$ipt --delete-chain;
$ipt --delete-chain -t nat;
$ipt -P FORWARD ACCEPT;
$ipt -P INPUT ACCEPT;
$ipt -P OUTPUT ACCEPT;
done
And then reload LXD:
# systemctl reload snap.lxd.daemon
Your containers should now have IPs again 😃