Thursday, August 8, 2019

How I set up LXD on my Ubuntu 19.04 server

I have a lovely little server that is slowly filling with LXD containers.

Here is how I set up LXD on the server (host).

Install LXD:

My host started as a 19.04 minimal install, so snapd wasn't included. LXD is packaged only for snap now (the deb simply installs the snap).
These references were extremely helpful. Read (or re-read) them: reference 1 reference 2

    host:~$ sudo apt install snapd
    host:~$ sudo snap install lxd
    host:~$ sudo adduser me lxd     // Add me to the LXD group
    host:~$ newgrp lxd              // New group takes effect without logout/login

First Run:

The very first time you run LXD, it must be initialized. It asks a set of questions to set up the default profile. I find that the defaults are quite satisfactory, with one exception - I named the storage:

    host:~$ lxd init               // First run of LXD only - creates profile
        Would you like to use LXD clustering? (yes/no) [default=no]:
        Do you want to configure a new storage pool? (yes/no) [default=yes]:
        Name of the new storage pool [default=default]: container_storage
        Name of the storage backend to use (btrfs, ceph, dir, lvm, zfs) [default=zfs]:
        Create a new ZFS pool? (yes/no) [default=yes]:
        Would you like to use an existing block device? (yes/no) [default=no]:
        Size in GB of the new loop device (1GB minimum) [default=15GB]:
        Would you like to connect to a MAAS server? (yes/no) [default=no]:
        Would you like to create a new local network bridge? (yes/no) [default=yes]:
        What should the new bridge be called? [default=lxdbr0]:
        What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
        What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
        Would you like LXD to be available over the network? (yes/no) [default=no]:
        Would you like stale cached images to be updated automatically? (yes/no) [default=yes]:
        Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:

My Preferences:

Yours preferences may vary.
  1. I prefer nano over vi for the default text editor. I know it's silly to have such a preference, but I do.
  2. My containers get their IP address from the LAN router instead of the host, using macvlan. This means that containers can talk to the LAN, and to each other, but not to the host. Personally, I see this as a feature, not a bug.

Set default editor as nano (instead of vi). This is obviously nothing but catering to my personal taste, and has no effect on other steps:

    host:~$ echo 'export EDITOR=nano' >> ~/.profile
    host:~$ source ~/.profile

Change the networking profile from default (NAT) to instead pull IP addresses for each container from the LAN router (macvlan). This is a matter of personal taste - it simply means I have one place to set IP addresses, the router, for all devices and containers. This only works with wired networking...if you are using wifi to connect a server full of containers to the LAN, then you really should rethink your plan anyway! (Reference)

    host:~$ ip route show default 0.0.0.0/0                          // Learn the eth interface
        default via 192.168.2.1 dev enp0s3 proto dhcp metric 600     // Mine is enp0s3 

    host:~$ lxc profile copy default lanprofile                      // Make mistakes on a copy, not the original
    host:~$ lxc profile device set lanprofile eth0 nictype macvlan   // Change nictype field
    host:~$ lxc profile device set lanprofile eth0 parent enp0s3     // Change parent field to real eth interface

Test:

Now that LXD is installed and configured, we can set up an unprivileged test container. An "unprivileged" container means that the container runs as an ordinary user on the larger system - if a process escapes the container, it has only normal (non-sudo, non-root) user permissions. LXD creates unprivileged containers by default so this part is pretty easy. Let's use the "lanprofile" networking profile we just created. Let's use Ubuntu Disco (19.04). And let's call the container "test":

    host:~$ lxc launch -p lanprofile ubuntu:disco test

The container is now running. Login to the LAN's router (or wherever your DHCP server is), and see that it's there among the dhcp clients.

That's all for LXD setup, Now I'm ready to create containers and fill them with services.

No comments: