Turn off DHCP for OVN network in LXD

I am using LXD and OVN to prototype a bastion host and a set of hosts behind it prior to implementing with real hardware. One of the functions the bastion host will implement in the physical world is DHCP (and DNS). However, OVN implements DHCP itself which conflicts with the explicit DHCP daemon. How do I turn off DHCP for the OVN network?

What I did. Create a network in OVS to be used for OVN:

$ sudo ovs-vsctl set open_vswitch . \
      external_ids:ovn-remote=unix:/var/run/ovn/ovnsb_db.sock \
      external_ids:ovn-encap-type=geneve \
      external_ids:ovn-encap-ip=127.0.0.1

And then use it when creating a network in LXD that uses it:

$ lxc network create ovnbr0 \
        ipv4.address=10.10.10.1/24 ipv4.nat=true \
        ipv4.dhcp.ranges=10.10.10.2-10.10.10.199 \
        ipv4.ovn.ranges=10.10.10.200-10.10.10.254 \
        ipv6.address=fd42:4242:4242:1010::1/64 ipv6.nat=true \
        ipv6.ovn.ranges=fd42:4242:4242:1010::200-fd42:4242:4242:1010::254
$ lxc network create ovn0 --type=ovn network=ovnbr0

And use it when creating some hosts inside the bastion area:

$ lxc init ubuntu:22.04 c1
$ lxc config device override c1 eth0 network=ovn0
$ lxc start c1
$ lxc info c1
...
      IP addresses:
        inet:  10.19.156.2/24 (global)
...
I don't want c1 to be able to get an address via DHCP from OVN. I want to provide an explicit DHCP server to give c1 an address. How do I do this? What am I missing?

It looks like LXD and OVN may not be the correct approach. Instead, I created an unmanaged bridge (outside the control of LXD) and configured it:

$ sudo ip link add internalbr0 type bridge
$ sudo ip addr add 172.16.0.1/12 dev internalbr0
$ sudo ip set internalbr0 up
$ ip link show zeekbr0
21: internalbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether e2:ab:00:c9:bb:db brd ff:ff:ff:ff:ff:ff

For convenience, I created a profile for the internal network:

$ cat <<EOF | lxc profile edit internal
description: Bridged internal network for prototype
devices:
  eth0:
    name: eth0
    nictype: bridged
    parent: internalbr0
   type: nic
EOF
$ lxc profile show internal  # looks like supplied config

Create the containers and observe they do not have addresses:

$ lxc launch -p default -p internal ubuntu:22.04 c1
$ lxc exec c2 -- ip addr show
24: eth0@if25: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 00:16:3e:63:26:21 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::216:3eff:fe63:2621/64 scope link
       valid_lft forever preferred_lft forever
$ lxc launch -p default -p internal ubuntu:22.04 c2
$ lxc exec c2 -- ip addr show
26: eth0@if27: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 00:16:3e:ef:78:5e brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::216:3eff:feef:785e/64 scope link
       valid_lft forever preferred_lft forever

Manually give the containers’ interfaces addresses and make sure they can ping each other (and the bridge):

$ lxc exec c1 -- ip address add 172.16.0.2/12 dev eth0
$ lxc exec c2 -- ip address add 172.16.0.3/12 dev eth0
$ lxc exec c1 -- ping -c 1 172.16.0.1  # bridge: OK
$ lxc exec c1 -- ping -c 1 172.16.0.2  # self: OK
$ lxc exec c1 -- ping -c 1 172.16.0.3  # other: OK
$ lxc exec c2 -- ping -c 1 172.16.0.1  # bridge OK
$ lxc exec c2 -- ping -c 1 172.16.0.2  # other: OK
$ lxc exec c2 -- ping -c 1 172.16.0.3  # self: OK

This is sufficient for what I need.

Note: it would be very convenient if LXD would allow one to create a bridge without automatically starting DHCP/DNS. I would not make that the default but having the option would support use cases like this for prototyping what will be a physical deployment.

You can use:

lxc network create foo ipv4.dhcp=false ipv6.dhcp=false

Thank you Thomas. I should have noticed those in the documentation. Somehow I missed them.

1 Like