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.

Lxd on Ubuntu VM powered by XEN or KVM

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

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

This entry is 3 of 20 in the LXD Tutorial series. Keep reading the rest of the series:
  1. Install LXD container hypervisor on Ubuntu 16.04 LTS
  2. How to install and setup LXC (Linux Container) on Fedora Linux 26
  3. Set up LXD container under KVM or Xen virtual machine
  4. List VM images in LXD (Linux Containers)
  5. Upgrade LXD containers powered by Ubuntu/Debian or CentOS Linux
  6. Auto start LXD containers at boot time in Linux
  7. Command to rename LXD / LXC container
  8. Run commands on Linux Container (LXD) instance at provision launch time
  9. Use LXD (Linux containers) in a shell script to create VM when the cloud instance launches
  10. Move/migrate LXD VM to another host on Linux
  11. Fedora install and set up LXD
  12. CentOS 7.x install and set up LXD server
  13. Install LXD pure-container hypervisor on Ubuntu 18.04 LTS
  14. Create snapshots with lxc command for LXD
  15. Set up and install LXD on CentOS/RHEL 8
  16. Ubuntu 20.04 LTS install and set up LXD
  17. Full backup and restore LXD containers
  18. Disable firewall and NAT rules on the LXD bridge
  19. Delete or remove LXD container using the lxc
  20. Linux Filesystem Error: Transaction failed solution

🐧 Get the latest tutorials on Linux, Open Source & DevOps via RSS feed or Weekly email newsletter.

🐧 0 comments... add one

CategoryList of Unix and Linux commands
Disk space analyzersdf ncdu pydf
File Managementcat tree
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network UtilitiesNetHogs dig 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.

Use HTML <pre>...</pre> for code samples. Still have questions? Post it on our forum