Sunday, November 13, 2022

Bridging LXD Containers in Ubuntu Core

I'm setting up a set of server containers on an Ubuntu Core 22 base.

This is slightly different from deb-based Ubuntu in several ways.

The hardware is a salvaged laptop motherboard, without keyboard or monitor.

Installing Ubuntu Core on most amd64 hardware:

Preparation on an existing system

  1. If you lack an ssh private and public key pair, create one using the ssh-keygen command on an existing system. If you already have your own private key, you can reuse it...or not. That's your choice.
  2. If you lack an Ubuntu SSO account, create one.
  3. Add your public key to that Ubuntu SSO account.
  4. If you lack a bootable Ubuntu Desktop (not Core) LiveUSB, create one.

Installation of the new system:

  1. A monitor and keyboard and network connection are required. Attach them to the hardware.
  2. Boot the Ubuntu (or any distro) LiveUSB. Select the Live ("Try Ubuntu") environment. Don't install anything.
  3. Download and install Ubuntu Core from within that live environment. Unplug the LiveUSB and reboot into Ubuntu Core.
  4. Once you have successfully connected to Ubuntu Core via ssh, the LiveUSB, monitor, and keyboard are no longer required.
  5. Do NOT install LXD yet. Set up the bridge on Ubuntu Core first.
  6. Finally, after the bridge is working, set up LXD.

Detail on Step #9 (Set up the bridge on Ubuntu Core)

  • On the stock install of Ubuntu Core, netplan is NOT in /etc. Instead, look in /writable/system-data/etc/
  • Also note that more commands in Ubuntu Core require sudo.

Here's the stock Netplan YAML from the setup. Your interfaces (enp3s0, wlp2s0) are likely to vary. Since this was a laptop motherboard, it included wi-fi:

$ sudo cat /writable/system-data/etc/netplan/*
# This is the network config written by 'console-conf'
network:
  ethernets:
    enp3s0:
      dhcp4: true
  version: 2
  wifis:
    wlp2s0:
      access-points:
        My-open-wireless-SSID: {}
      dhcp4: true

We want to add a bridge to this YAML. Use the vi command to edit, since no other editor is included with Ubuntu Core. (vi tutorial) When complete, it should look more like this:

$ sudo cat /writable/system-data/etc/netplan/*
# This is the network config written by 'console-conf'
network:
  ethernets:
    enp3s0:
      dhcp4: false   <--- The original interface no longer gets the IP address
  version: 2
  wifis:
    wlp2s0:
      access-points:
        My-open-wireless-SSID: {}
      dhcp4: true
  bridges:           <--- New section for the bridge
    br0:             <--- Bridge interface name. Use this instead of the original enp3s0 interface name  
      dhcp4: true    <--- The bridge interface gets the IP address
      interfaces: [ enp3s0 ]

Here's the first trap and how to avoid it: When these changes are applied, the new bridge will instantly get control of the network interface.

Unfortunately, that new bridge will have a different MAC address, and thus will receive a different IP address. Your existing ssh session over ethernet will be severed and unrecoverable. Ubuntu Core WON'T tell you the new IP address.

You must have access to your dhcp server (or another SSH connection over an unchanged interface...like wireless) to learn the bridge's new IP address. Set that up now.

And then the commands netplan generate (check for errors) and netplan apply (execute the changes).

Login again to Ubuntu Core using the new IP address

Detail on Step #10 (Install LXD)

sudo snap install lxd
sudo lxd init

Here's the second trap and how to avoid it: During setup (lxd init) LXD offers to create a bridge (lxdbr0). That default bridge is *internal*; it has no external network access. Let it create the bridge, but specify the existing bridge (br0) that you created in Step 9. There's no difference between the two bridges, except that br0 happens to have network access already.

Would you like to create a new local network bridge? (yes/no) [default=yes]: yes
What should the new bridge be called? [default=lxdbr0]: br0

Let's take a look at our LXD settings now:

$ sudo lxc profile show defaul
config: {}
description: Default LXD profile
devices:
  eth0:
    name: eth0
    nictype: bridged
    parent: br0
    type: nic
  root:
    path: /
    pool: default
    type: disk
name: default

And now our soon-to-be-created containers will all have bridged network access. Each container will each get a separate IP address from the real LAN router. Each container will be accessible from anywhere on the LAN.

Easy!

No comments: