How to install a ZFS-backed LXD server on Xenial

I recently wanted to move some of my cloud-based infrastructure to LXD. So I took the opportunity to document the process, which turned out to be very easy. Here's how I did it.

Prerequisites

If you want to use ZFS, you'll need to ensure that your cloud instance uses "full virtualization"; that is, if your cloud instance is itself a container, or is running on top of a paravirtualization solution such as Xen, you won't be able to insert the kernel module.

In this case I was working with a Linode instance running Xenial. I had to do the following to get it to work:

sudo apt-get install -y linux-image-virtual grub2
sudo update-grub

Then I changed my profile to Full-virtualization and set it up to boot from GRUB 2 (under "Boot Settings > Kernel"), rebooted, and got started!

Procedure

Setting up LXD was a simple matter of installing a couple of packages, and answering some questions related to setting up the Ethernet bridge I wanted to use, plus the configuration of the ZFS loopback device. (You can use ZFS on a "normal" block device, but I chose not to in this case; it would probably be wise to remove the extra filesystem and run directly on a block device, on a production system.)

Here's a summary of the commands, and what they do.

First, you'll need to install LXD, and the ZFS utilities for Linux:

sudo apt-get install lxd zfsutils-linux

Next, initialize LXD (and configure the network used for the containers; the video shows how I configured it, but that part is up to you):

sudo lxd init

Next, you can either log out and log back in, or simply use the newgrp command to open a subshell with the permissions of the lxd group:

newgrp lxd

Next you can run the lxd info command to look at your configuration, to ensure everything is set up the way you expect:

lxc info

Finally, launch the container:

lxc launch ubuntu:t

To check if the container is running, you can use the lxc list command.

lxc list

Finally, use the lxc exec command to get a root shell inside the container. Note that it might take a few seconds before the new container is usable.

lxc exec container-name -- bash

Note: This was done on a linode KVM instance, which was configured to boot with grub 2 after doing sudo apt-get install -y linux-image-virtual grub2 && sudo update-grub. If you're using linode, you must use a node with full virtualization rather than paravirtualization.