How to Install LXD / LXC on Ubuntu

This tutorial details how to install LXD on Ubuntu. We will look at how to install and initialize LXD manually, then how to install LXD using a preseed file, which helps speed things up.

We will then show how you can automate the LXD install by putting everything into a BASH script.

Lets get started by saying a few words about what LXD is and what it is used for.

What is LXC/LXD?

We will be using the terms LXC and LXD a lot throughout this article. So what are they?

LXC vs LXD

LXC (otherwise known as Linux Containers) is for virtualizing software at the operating system level. It is a container platform that allows you to run containers for the purpose of serving a single application, or a whole operating system from the LXC host.

As with Docker, you can run multiple LXC containers on the same host system, and configure networking to allow them to interact with each other and with the host (and remote hosts). If this all sounds similar to Docker, it’s worth noting that LXC used to be the technology that Docker was dependent upon.

LXC uses Linux cgroups to prioritize hardware resources such as CPU, memory and I/O, whilst sharing the linux kernel. Namespace isolation ensures each container works as a separate entity.

LXC has a bunch of commands that allow you to create and interact with LXC containers. These commands are prefixed with lxc-.

So, where does LXD come in? You can think of LXD as an extension to LXC, which adds a lot of functionality. LXD (Linux Container Daemon) provides an API to allow you to interact with LXC (connecting to the liblxc library). This means you can manage your local containers, but you can also manage remote containers on other LXC hosts and you can interact with container image repositories. From the Linux command line you can interact with LXD using commands that all start with lxc, which can be a little confusing to begin with! You can check out the list of commands available by running lxc --help once you have it LXD installed:

$ lxc --help
Description:
  Command line client for LXD

  All of LXD's features can be driven through the various commands below.
  For help with any of those, simply call them with --help.

Usage:
  lxc [command]

Ok! So let’s get started!

Check if LXD is already installed on Ubuntu

Before we do anything else, the first step is to check if you already have LXD installed on your system:

$ lxc version
Client version: 3.0.3
Server version: 3.0.3

On my system I have 3.0.3 installed already. This is not the latest version however, so lets run through the process of installing the latest using snap.

How to Install LXD on an Ubuntu Host

To install LXD using snap, use the snap install lxd command. This will take a few seconds to run:

With that complete, we now want to remove the version of LXD that was already installed (if applicable):

$ sudo apt remove lxd lxd-client -y

The last step of the LXD install is to add your user account to the LXD group so that we can run LXD commands without being root:

$ sudo usermod username -aG lxd

After doing this, you will need to log out as that user then log in again to get a new session. After doing so, run the lxd version command again:

$ lxc version
Client version: 4.10
Server version: 4.10

And that’s it, we now have LXD installed, with the latest version. But we aren’t done yet! The next step is to initialize LXD by running the lxc init command. We are going to look at two different ways to do this.

How to Initialise LXD Manually after Installing

After we have gone through the process to install LXD, we then need to initialise it. This is simply the process of setting up LXD for the first time, and is an activity that needs to be carried out when ever you install LXD for the first time. It involves providing answers to a number of questions so that your LXD environment is configured to your needs. The command to initialise LXD is lxd init.

When you run lxc init you will be asked a bunch of questions, which you will need to provide answers for or accept the defaults. An example of the questions you will be prompted with:

Would you like to use LXD clustering? (yes/no) [default=no]: no
Do you want to configure a new storage pool? (yes/no) [default=yes]: yes
Name of the new storage pool [default=default]: default
Name of the storage backend to use (btrfs, ceph, dir, lvm, zfs) [default=zfs]: zfs
Create a new ZFS pool? (yes/no) [default=yes]: yes
Would you like to use an existing block device? (yes/no) [default=no]: no
Size in GB of the new loop device (1GB minimum) [default=15GB]: 15GB
Would you like to connect to a MAAS server? (yes/no) [default=no]: 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]: yes

As you can see, you will be asked to provide answers to questions around clustering, storage and networking. I’ve provided answers above, or accepted the defaults in most cases. The result of which will give you a basic default LXD configuration, which will be adequate for test environments. More detailed configuration will be required for a production environment.

Lets have a look at running the command:

And that it is! At this point we are ready to create and run some LXC containers. As you can see this only took a little while, but there is a quicker way, and one which is useful if you are setting up many hosts.

How to Initialise LXD using Preseed

As an alternative to answering all the lxd init questions interactively, we can supply lxd init with a preseed file which has all the answers/configuration pre-populated. When running the command interactively, the last question you will be prompted with is:

Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]: yes

If yes is selected here, the YAML version of the answers you have provided during the init process will be displayed. It will look something like this:

config: {}
    networks:
    - config:
             ipv4.address: auto
             ipv6.address: auto
      description: ""
      managed: false
      name: lxdbr0
      type: bridge
    storage_pools:
    - config:
         size: 20GB
      description: ""
      name: default
      driver: zfs
    profiles:
    - config: {}
      description: ""
      devices:
              eth0:
                name: eth0
                nictype: bridged
                parent: lxdbr0
                type: nic
      root:
                path: /
                pool: default
                type: disk
      name: default
    cluster: null

Now, we can take this output and save it as a YAML file, for example lxdconfig.yaml. When we run lxd init, we can pass it this file using the --preseed option and LXD will be configured using the values in the file, with no further questions asked!

One advantage, other than speed and convenience, to using a YAML preseed file to initialise LXD is that we can add more configuration options than we would have had the opportunity to if we had ran the command interactively, which can help cut done on some configuration changes you may make later. For example, you can add additional storage pools, or profiles.

Once you have your YAML file prepared, you can initialise LXD by using the preseed option:

$ cat lxdconfig.yaml | lxd init --preseed

It will take a few seconds to run, but once complete you should have a configured LXD environment, ready to create some containers!

Automate LXD Install and Init using a Bash Script

We can take this a step further by putting all the steps covered so far into a bash script which can be ran to automation the LXD install. For example, I have created the following bash script to install lxd:

#!/bin/bash
echo "\e[32mInstalling LXD Using Snap \e[0m"
snap install lxd
echo "\e[32mRemoving Old LXD if exists \e[0m"
apt remove lxd lxd-client -y
echo "\e[32mAdding non-root user to LXD Group \e[0m"
usermod cloud_user -aG lxd

echo "\e[32mCreate Preseed File \e[0m"

cat >> lxdconfig.yaml << EOF
    config: {}
    networks:
    - config:
             ipv4.address: auto
             ipv6.address: auto
      description: ""
      managed: false
      name: lxdbr0
      type: bridge
    storage_pools:
    - config:
         size: 20GB
      description: ""
      name: default
      driver: btrfs
    profiles:
    - config: {}
      description: ""
      devices:
              eth0:
                name: eth0
                nictype: bridged
                parent: lxdbr0
                type: nic
              root:
                path: /
                pool: default
                type: disk
      name: default
    cluster: null
EOF

echo "\e[32mInitialise LXD Using Preseed File \e[0m"
cat lxdconfig.yaml | lxd init --preseed

echo "\e[32mDone!! \e[0m"
lxc version

This can be ran on a system for which we wish to configure a new LXD test environment. It will use the same configuration as shown in the preseed file section, though of course this can easily be changed to suit your needs. Lets see it in action!

We now have a working LXD installation with a mostly default configuration! Lets test it by launching a container.

Test your LXD Install by Launching a Container

We can quickly launch a container by using the lxc launch command:

# lxc launch ubuntu:18.04
Creating the instance
Instance name is: grateful-serval
Starting grateful-serval

It will take a little while to launch the first container, as it will first need to pull down the Ubuntu image. Once complete though we can confirm it has worked by listing lxc containers on the system, using the lxc list command:

There we go! A running LXC Ubuntu container!

Conclusion

In this article you have learned how to install LXD on an Ubuntu system. We started with some background information on LXC/LXD before demonstrating how to install LXD manually.

We then showed how to install and initialise LXD using the preseed option with a YAML file.

Finally we looked at how to combine everything by installing LXD using a bash script, before testing the LXD install by showing how to launch a LXD container.

Related posts

Mastering the Linux ifconfig Command

Docker Exec Command With Practical Examples

Debugging with Git Bisect

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Read More