Networking with LXD
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 port80
with the IP10.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
Note
Note that if you are connected to a server over SSH, your connection will break. Make sure to have a snapshot of the working state before changing your network configuration.
- 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.
Tip
If you are using virtual machines for hosting containers and want to set up a bridge, then make sure that you have enabled promiscuous mode on the network adapter of the virtual machine. This can be enabled from the network settings of your hypervisor. Also, a bridge setup may not work if your physical machine is using a wireless network.
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:
- 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