How to install LXD container under KVM or Xen virtual machine

For security and ease of admin, I want to install LXD on my cloud server either powered by XEN or KVM. How do I install LXD on Ubuntu Linux server powered by KVM virtualization technology?

You can implement the Linux container (LXD/LXC) to partition a your cloud server. Both cloud server, its files, and resources are only given the access to the right services such as Apache, Nginx, MySQL, Proxy, Memcached and so on. Canonical’s LXD is a pure-container hypervisor that runs unmodified Linux operating systems and applications with VM-style operations at incredible speed and density. In this quick tutorial you will learn how to install the latest stable version of LXD container under KVM cloud server hosted at Linode for security mechanism on Ubuntu Linux 16.04.xx LTS server.

Step 1 – LTS vs Backported release

There are two releases

  1. LTS releases are recommended for production environments.
  2. To get all the latest features and monthly updates to LXD, use the feature release branch.

Step 2 – Install lxd

Type the following apt command or apt-get command to install LXD LTS release:
$ sudo apt-get install lxd
$ sudo apt install lxd
To install latest stable release using backported on Xenial, run:
$ sudo apt install -t xenial-backports lxd lxd-client
Sample outputs:

Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  acl dns-root-data dnsmasq-base ebtables liblxc1 liblzo2-2 libnetfilter-conntrack3 lxc-common lxcfs squashfs-tools uidmap xdelta3
Suggested packages:
  criu lxd-tools
The following NEW packages will be installed:
  acl dns-root-data dnsmasq-base ebtables liblxc1 liblzo2-2 libnetfilter-conntrack3 lxc-common lxcfs lxd lxd-client squashfs-tools uidmap xdelta3
0 upgraded, 14 newly installed, 0 to remove and 0 not upgraded.
Need to get 6,275 kB/7,162 kB of archives.
After this operation, 26.6 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 xenial-updates/main amd64 ebtables amd64 [79.4 kB]
Get:2 xenial-backports/main amd64 lxd-client amd64 2.21-0ubuntu2~16.04.1 [2,426 kB]
Get:3 xenial/universe amd64 xdelta3 amd64 3.0.8-dfsg-1ubuntu2 [67.1 kB]
Get:4 xenial-backports/main amd64 lxd amd64 2.21-0ubuntu2~16.04.1 [3,703 kB]
Fetched 6,275 kB in 0s (58.5 MB/s)
Selecting previously unselected package liblzo2-2:amd64.
(Reading database ... 41804 files and directories currently installed.)
Preparing to unpack .../liblzo2-2_2.08-1.2_amd64.deb ...
Unpacking liblzo2-2:amd64 (2.08-1.2) ...
Selecting previously unselected package acl.
Preparing to unpack .../acl_2.2.52-3_amd64.deb ...
Unpacking acl (2.2.52-3) ...
Selecting previously unselected package dns-root-data.
Preparing to unpack .../dns-root-data_2015052300+h+1_all.deb ...
Unpacking dns-root-data (2015052300+h+1) ...
Selecting previously unselected package libnetfilter-conntrack3:amd64.
Preparing to unpack .../libnetfilter-conntrack3_1.0.5-1_amd64.deb ...
Unpacking libnetfilter-conntrack3:amd64 (1.0.5-1) ...
Selecting previously unselected package dnsmasq-base.
Preparing to unpack .../dnsmasq-base_2.75-1ubuntu0.16.04.4_amd64.deb ...
Unpacking dnsmasq-base (2.75-1ubuntu0.16.04.4) ...
Selecting previously unselected package ebtables.
Preparing to unpack .../ebtables_2.0.10.4-3.4ubuntu2_amd64.deb ...
Unpacking ebtables ( ...
Selecting previously unselected package lxc-common.
Preparing to unpack .../lxc-common_2.0.8-0ubuntu1~16.04.2_amd64.deb ...
Unpacking lxc-common (2.0.8-0ubuntu1~16.04.2) ...
Selecting previously unselected package liblxc1.
Preparing to unpack .../liblxc1_2.0.8-0ubuntu1~16.04.2_amd64.deb ...
Unpacking liblxc1 (2.0.8-0ubuntu1~16.04.2) ...
Selecting previously unselected package lxcfs.
Preparing to unpack .../lxcfs_2.0.8-0ubuntu1~16.04.2_amd64.deb ...
Unpacking lxcfs (2.0.8-0ubuntu1~16.04.2) ...
Selecting previously unselected package lxd-client.
Preparing to unpack .../lxd-client_2.21-0ubuntu2~16.04.1_amd64.deb ...
Unpacking lxd-client (2.21-0ubuntu2~16.04.1) ...
Selecting previously unselected package squashfs-tools.
Preparing to unpack .../squashfs-tools_1%3a4.3-3ubuntu2.16.04.1_amd64.deb ...
Unpacking squashfs-tools (1:4.3-3ubuntu2.16.04.1) ...
Selecting previously unselected package uidmap.
Preparing to unpack .../uidmap_1%3a4.2-3.1ubuntu5.3_amd64.deb ...
Unpacking uidmap (1:4.2-3.1ubuntu5.3) ...
Selecting previously unselected package xdelta3.
Preparing to unpack .../xdelta3_3.0.8-dfsg-1ubuntu2_amd64.deb ...
Unpacking xdelta3 (3.0.8-dfsg-1ubuntu2) ...
Selecting previously unselected package lxd.
Preparing to unpack .../lxd_2.21-0ubuntu2~16.04.1_amd64.deb ...
Unpacking lxd (2.21-0ubuntu2~16.04.1) ...
Processing triggers for man-db (2.7.5-1) ...
Processing triggers for libc-bin (2.23-0ubuntu10) ...
Processing triggers for dbus (1.10.6-1ubuntu3.3) ...
Processing triggers for systemd (229-4ubuntu21) ...
Processing triggers for ureadahead (0.100.0-19) ...
Setting up liblzo2-2:amd64 (2.08-1.2) ...
Setting up acl (2.2.52-3) ...
Setting up dns-root-data (2015052300+h+1) ...
Setting up libnetfilter-conntrack3:amd64 (1.0.5-1) ...
Setting up dnsmasq-base (2.75-1ubuntu0.16.04.4) ...
Setting up ebtables ( ...
update-rc.d: warning: start and stop actions are no longer supported; falling back to defaults
Setting up lxcfs (2.0.8-0ubuntu1~16.04.2) ...
Setting up lxd-client (2.21-0ubuntu2~16.04.1) ...
Setting up squashfs-tools (1:4.3-3ubuntu2.16.04.1) ...
Setting up uidmap (1:4.2-3.1ubuntu5.3) ...
Setting up xdelta3 (3.0.8-dfsg-1ubuntu2) ...
Setting up liblxc1 (2.0.8-0ubuntu1~16.04.2) ...
Setting up lxd (2.21-0ubuntu2~16.04.1) ...
Setting up lxd dnsmasq configuration.
To go through the initial LXD configuration, run: lxd init
Old bridge configuration detected in /etc/default/lxd-bridge, upgrading
Unsetting deprecated profile options
Attempting to kill current lxd-bridge
Bringing down and renaming existing bridge lxdbr0 to lxd-upgrade
Creating a new LXD bridge
Network lxdbr0 created
Moving the old bridge into place
Configuring the new LXD bridge
Setting IPv4 network to
Setting IPv4 DHCP range to
Enabling IPv4 NAT
Done converting your bridge, renaming old configuration
Cleaning up lxd-bridge state files
Setting up lxc-common (2.0.8-0ubuntu1~16.04.2) ...
Processing triggers for libc-bin (2.23-0ubuntu10) ...
Processing triggers for dbus (1.10.6-1ubuntu3.3) ...
Processing triggers for systemd (229-4ubuntu21) ...
Processing triggers for ureadahead (0.100.0-19) ...

Step 3 – Add user account for lxd

Type the following command to add a user named vivek, run:
$ sudo adduser vivek
Make sure vivek is part of a secondary group named lxd group, enter:
$ sudo usermod -a -G lxd vivek
Verify it, run the id command as follows:
$ id vivek
Sample outputs:

uid=1002(vivek) gid=1002(vivek) groups=1002(vivek),118(lxd)

Step 4 – Configure lxd

To go through the initial LXD configuration, run:
$ sudo lxd init
Sample outputs:

Step 5 -Creating and using your first container

First login as vivek user:
$ ssh
$ su - vivek
Verify that the lxc client is talking to the LXD daemon:
$ lxc list
Sample outputs:


The syntax is as follows to create your first container:

lxc launch images:{distro}/{version}/{arch} {container-name-here}

To list all available images for various Linux distro, run:
$ lxc image list images:
To create a CentOS Linux v7.x container:
$ lxc launch images:centos/7/amd64 my-cenots
Sample outputs:

Creating my-cenots
Retrieving image: 100% (16.80MB/s)
Starting my-cenots

To create a Ubuntu Linux 16.4 LTS container:
$ lxc launch images:ubuntu/xenial/amd64 my-ubuntu
Sample outputs:

Animated gif.01: Lxc creating your VM

Step 6 – Login to your first container

Type the following command:
$ lxc exec my-centos bash
$ lxc exec my-ubuntu bash

You can now update your container or install needed software.

Step 6 – Lock down root user

You do not need root user or default user such as ubuntu/centos created in your container:
$ lxc exec my-ubuntu bash
Lock down root account access, run:
# passwd -l root
Delete unwanted user account using the userdel command, run:
# userdel -r ubuntu

Step 7 – Basic Linux containers management commands

Let us see important commands to manage your containers.

Start a container

$ lxc start containerName

Stop a container

$ lxc stop containerName

Restart a container

$ lxc restart containerName

Delete a container

$ lxc delete containerName

Get info about running container

$ lxc info containerName

Run the specified command in a container

$ lxc exec containerName command1
$ lxc exec containerName command1 opt1
$ lxc exec containerName date
$ lxc exec containerName -- command1 -arg1 -arg2
$ lxc exec my-cenots -- yum update -y

Auto start LXD VM at boot time

$ lxc config set containerName boot.autostart true
$ lxc config set my-centos boot.autostart true

Create a read-only snapshot of a container

$ lxc snapshot containerName snapShotName
$ lxc snapshot my-cenots snap0
$ lxc info my-cenots

Restore a container’s state to a previous snapshot

$ lxc restore containerName snapShotName
$ lxc restore my-cenots snap0
$ lxc info my-cenots
$ lxc exec my-cenots bash

I recommend that you let built-in DHCP assign a static IP to LXD container/VM based on name or MAC address for ease of management including talking with each other. I suggest that you setup LAMP stack as follows:
$ lxc launch images:ubuntu/xenial/amd64 db1
$ lxc launch images:ubuntu/xenial/amd64 nginx1
$ lxc launch images:ubuntu/xenial/amd64 apache-php1
$ lxc launch images:ubuntu/xenial/amd64 memcached

Once LXC VM up and running. Log into each container and setup services i.e. install Apache and PHP on apache-php1 VM. Use Nginx (or any other proxy server) or iptables on your cloud server to redirect traffic to port 80/443 from your public IP address to container service.

And there you have it. LXD container/VM is running for each service such as a web server, MySQL, Memcached, Proxy and so on. All of your services are running on separate LXD vm instance. Naturally, this limits the number of other services that can be cracked if an attacker can successfully exploit a software flaw in one network service.

See also

🐧 Please support my work on Patreon or with a donation.
🐧 Get the latest tutorials on Linux, Open Source & DevOps via:
CategoryList of Unix and Linux commands
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilitiesdig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
0 comments… add one

Leave a Reply

Your email address will not be published. Required fields are marked *

Use HTML <pre>...</pre> for code samples. Problem posting comment? Email me @