Using static IPs with LXD

Hi Simos, thank you, interesting… I’ll have a play around… I want to ssh into various containers on the same host, so I suspect I’ll need to have different ports for ssh on each container…

You either use different ports for each container.

Or, you can set up a bastion host for SSH. You can google for the bastion host and get some nice tutorials.

1 Like

Great, thank you…

The default expiration time for the “managed” lxdbr0 is actually 1h, check the output of:

lxc network get lxdbr0 ipv4.dhcp.expiry

If you check the parameters with which a dnsmasq instance is started you’ll notice the lease expiration set as part of the “--dhcp-range” parameter. According to dnsmasq man pages the parameter accepts a value of “infinite” so this should work for an infinite lease expiration time:

lxc network set lxdbr0 ipv4.dhcp.expiry=infinite

I presume that @stgraber might come up with some edge cases where using this is not advisable or cases when LXD might reinitialize /var/snap/lxd/common/lxd/networks/lxdbr0/dnsmasq.leases leading to loss of “infinite” leases.

That worked for me perfectly to set the IP address to a fixed value for the container, but since I’ve updated to LXD 5.6 / 5.7 that commands are no longer working:

lxc network attach lxdbr0 wireguard eth0 eth0
Error: Failed add validation for device “eth0”: Instance DNS name “wireguard” already used on network

lxc config set wireguard eth0 ipv4.address=10.0.5.102
Error: Invalid config: Unknown configuration key: eth0

Do you have any ideas?

You should be using lxc config device set ...
This hasn’t changed in LXD 5.7.

Thanks! This was the solution for me as well. :wink:

In case you need to create an instance from scratch (the way I understand it):

# determine the bridge's ip
$ lxc network get lxdbr0 ipv4.address
10.99.10.1/24
# as such the network's address range is apparently 10.99.10.0/24

# create an instance
$ lxc init images:debian/12 d12

# attach lxdbr0 to d12 as a NIC device
$ lxc network attach lxdbr0 d12 eth0 eth0

# set ip for the device
$ lxc config device set d12 eth0 ipv4.address 10.99.10.2

$ lxc start d12
$ lxc list
+------+---------+-------------------+------+-----------+-----------+
| NAME |  STATE  |       IPV4        | IPV6 |   TYPE    | SNAPSHOTS |
+------+---------+-------------------+------+-----------+-----------+
| d12  | RUNNING | 10.99.10.2 (eth0) | ...  | CONTAINER | 0         |
+------+---------+-------------------+------+-----------+-----------+
$ lxc delete --force d12

But lxc network attach is a shortcut for lxc config device add, as such:

$ lxc init images:debian/12 d12
$ lxc config device add d12 eth0 nic network=lxdbr0 ipv4.address=10.99.10.2
$ lxc start d12
$ lxc list
+------+---------+-------------------+------+-----------+-----------+
| NAME |  STATE  |       IPV4        | IPV6 |   TYPE    | SNAPSHOTS |
+------+---------+-------------------+------+-----------+-----------+
| d12  | RUNNING | 10.99.10.2 (eth0) | ...  | CONTAINER | 0         |
+------+---------+-------------------+------+-----------+-----------+
$ lxc delete --force d12

Or even this way:

$ lxc launch -d eth0,ipv4.address=10.99.10.2 images:debian/12 d12
$ lxc list
+------+---------+-------------------+------+-----------+-----------+
| NAME |  STATE  |       IPV4        | IPV6 |   TYPE    | SNAPSHOTS |
+------+---------+-------------------+------+-----------+-----------+
| d12  | RUNNING | 10.99.10.2 (eth0) | ...  | CONTAINER | 0         |
+------+---------+-------------------+------+-----------+-----------+
$ lxc delete --force d12

I didn’t find a way to determine the network’s ip range, but determining it via the bridge’s ip is probably fine. I’m not sure what’s the difference between a device name and a interface name (lxc network attach). And generally I’m not an expert at LXD, so I might be missing something.

Useful links:

UPD Particularly, I don’t understand why exactly I can’t use eth1 in place of eth0. E.g. how do I create an instance without eth0 and with eth1 that has a static ip? Or with eth0 (dynamic ip) and eth1 (static ip)? Not that that is important. Rather out of curiosity. To better understand how it works.

I got static IPs working with routed like this:

# lxc profile show default
config:
  cloud-init.network-config: |
    version: 2
    ethernets:
      eth0:
        nameservers:
          addresses: [8.8.8.8]
description: Default LXD profile
devices:
  eth0:
    nictype: routed
    parent: eno1np0
    type: nic
name: default

For each container:

lxc init images:debian/12/cloud c0
lxc config device override c0 eth0 ipv4.address=1.2.3.4
lxc start c0
lxc exec c0 -- systemctl stop systemd-networkd
lxc exec c0 -- systemctl disable systemd-networkd
lxc exec c0 -- sed -i 's/#DNS=/DNS=8.8.8.8/g' /etc/systemd/resolved.conf
lxc restart c0
1 Like