24/7/365 Support

Networking with LXD in Ubuntu

In this recipe, we will look at LXD network setup. By default, LXD creates an internal bridge network. Containers are set to access the Internet through Network Address Translation (NAT) but are not accessible from the Internet. We will learn to open a service on a container to the Internet, share a physical network with a host, and set a static IP address to a container.

Getting ready

As always, you will need access to the root account or an account with sudo privileges.

Make sure that you have created at least one container.

How to do it…

By default, LXD sets up a NAT network for containers. This is a private network attached to the lxdbr0 port on the host system. With this setup, containers get access to the Internet, but the containers themselves or the services running in the containers are not accessible from an outside network. To open a container to an external network, you can either set up port forwarding or use a bridge to attach the container directly to the host's network:

To set up port forwarding, use the iptables command, as follows:

$ sudo iptables -t nat -A PREROUTING -p tcp -i eth0 \

--dport 80 -j DNAT --to 10.106.147.244:80

This will forward any traffic on the host TCP port 80 to the containers' TCP port 80 with the IP 10.106.147.244. Make sure that you change the port and IP address as required.

You can also set a bridge that connects all containers directly to your local network. The bridge will use an Ethernet port to connect to the local network. To set a bridge network with the host, we first need to create a bridge on the host and then configure the container to use that bridge adapter.

To set up a bridge on the host, open the /etc/network/interfaces file and add the following lines:

auto br0

iface br0 inet dhcp

bridge_ports eth0

Make sure that you replace eth0 with the name of the interface connected to the external network.

Enable IP forwarding under sysctl. Find the following line in /etc/sysctl.conf and uncomment it:

net.ipv4.ip_forward=1

Start a new bridge interface with the ifup command:

$ sudo ifup br0

If required, you can restart the networking service, as follows:

$ sudo service networking restart

Next, we need to update the LXD configuration to use our new bridge interface. Execute a reconfiguration of the LXD daemon and choose <No> when asked to create a new bridge:

$ sudo dpkg-reconfigure -p medium lxd

Then on the next page, choose <Yes> to use an existing bridge:

Enter the name of the newly created bridge interface:

This should configure LXD to use our own bridge network and skip the internal bridge. You can check the new configuration under the default profile:

$ lxc profile show default

Now, start a new container. It should receive the IP address from the router on your local network. Make sure that your local network has DHCP configured:

How it works…

By default, LXD sets up a private network for all containers. A separate bridge, lxdbr0, is set up and configured in the default profile. This network is shared (NAT) with the host system, and containers can access the Internet through this network. In the previous example, we used IPtables port forwarding to make the container port 80 available on the external network. This way, containers will still use the same private network, and a single application will be exposed to the external network through the host system. All incoming traffic on host port 80 will be directed to the container's port 80.

You can also set up your own bridge connected to the physical network. With this bridge, all your containers can connect to and be directly accessible over your local network. Your local DHCP will be used to assign IP addresses to containers. Once you create a bridge, you need to configure it with LXD containers either through profiles or separately with container configuration. In the previous example, we reconfigured the LXD network to set a new bridge.

LXD supports more advanced network configuration by attaching the host eth interface directly to a container. The following settings in the container configuration will set the network type to a physical network and use the host's eth0 directly inside a container. The eth0 interface will be unavailable for the host system till the container is live:

$ lxc config device add c1 eth0 nic nictype=physical parent=eth0

There's more…

LXD creates a default bridge with the name lxdbr0. The configuration file for this bridge is located at /etc/default/lxd-bridge. This file contains various configuration parameters, such as the address range for the bridge, default domain, and bridge name. An interesting parameter is the additional configuration path for dnsmasq configurations.

The LXD bridge internally uses dnsmasq for DHCP allocation. The additional configuration file can be used to set up various dnsmasq settings, such as address reservation and name resolution for containers.

Edit /etc/default/lxd-bridge to point to the dnsmasq configuration file:

# Path to an extra dnsmasq configuration file

LXD_CONFILE="/etc/default/dnsmasq.conf"

Then, create a new configuration file called /etc/default/dnsmasq.conf with the following contents:

dhcp-host=c5,10.71.225.100

server=/lxd/10.71.225.1

#interface=lxdbr0

This will reserve the IP 10.71.225.100 for the container called c5, and you can also ping containers with that name, as follows:

$ ping lxd.c5

See also

Read more about bridge configuration at https://wiki.debian.org/LXC/SimpleBridge

Find out more about LXD bridge at the following links:

https://insights.ubuntu.com/2016/04/07/lxd-networking-lxdbr0-explained/

http://askubuntu.com/questions/754323/lxd-2-0-local-networking

https://insights.ubuntu.com/2015/11/10/converting-eth0-to-br0-and-getting-all-your-lxc-or-lxd-onto-your-lan /

Read more about dnsmasq at https://wiki.debian.org/HowTo/dnsmasq

Sample dnsmasq configuration file: http://oss.segetech.com/intra/srv/dnsmasq.conf

Check the dnsmasq manual pages with the man dnsmasq command

Help Category:

What Our Clients Say