top of page
  • admin

Understanding and Using LXC and LXD

LXC/LXD is a Virtual Machine-like (VM), yet lightweight, Linux container system. Each container has its own filesystem, process space and network stack, thus firewalling a container from its host and the other containers. Rather than emulating hardware they all use the same kernel, so the containers run much more efficiently.

Interesting uses for lxc:

• compartmentalization (for security, or imposing resource limits)self-contained build or application

• environments that are independent of the host OS

• run an older OS version than the host (e.g. run a Ubuntu 12.04 container on a 16.04 host)

• run a different distro than the host (e.g. run a Fedora container on an Ubuntu host)

What is LXC (lex-see)?

“LXC containers are often considered as something in the middle between a chroot and a full fledged virtual machine. The goal of LXC is to create an environment as close as possible to a standard Linux installation but without the need for a separate kernel.”

“LXC is a userspace interface for the Linux kernel containment features. Through a powerful API and simple tools, it lets Linux users easily create and manage system or application containers.

“Current LXC uses the following kernel features to contain processes:

Kernel namespaces (ipc, uts, mount, pid, network and user)Apparmor and SELinux profilesSeccomp policiesChroots (using pivot_root)Kernel capabilitiesCGroups (control groups)

What is LXD (lex-dee)?

“LXD is a container ‘hypervisor’ and a new user experience for LXC.” Basically it’s a layer above lxc that manages containers using liblxc and a Go binding. “The daemon exports a REST API both locally and, if enabled, over the network.”

“It's basically an alternative to LXC's tools and distribution template system with the added features that come from being controllable over the network.”

How does LXC/LXD differ from Virtualbox, Docker?

Virtualbox is a full VM, emulating hardware and running a kernel on top of it, whereas lxc does not emulate hardware and uses the same kernel as the host.

Docker containers only run a single process and do not have init, whereas lxc does have init and therefore can run a full userspace. Docker containers also have less networking flexibility. It is possible to run Docker in an lxc container.


By default, when a container is created it assigned a non-routable IP address dynamically via DHCP, and that address is added to the bridge lxdbr0 running NAT. All kinds of configurations are possible, such as:

routable IP address so packets flow directly to the containerbridge two interfaces, e.g. for a front-end container that needs a routable IP address to talk to the internet while bridging to containers running various back-end application components on non-routable IP addressesfan networking, for very dense virtualization

Note that lxd 2.3+ has much better networking support, since most networking config happens in lxd with its config stored alongside all the other container config, instead of having to configure it all separately.

A Word about ZFS

ZFS is the preferred filesystem to use with lxd, due to:

instantaneous snapshotsper-filesystem quotas and reservationspartition-less, so any number of filesystems can be created dynamicallydeduplicationease of transferring filesystems between hosts (zfs send/recv), which is useful for migrating containers between hosts

Further reading

Installation (Ubuntu 16.04 or newer)

	$ sudo apt install lxd
	$ sudo apt install zfsutils-linux
        $ sudo lxd init

LXC/LXD Crib Sheet

Launch a new container

	lxc launch ubuntu falcon
	lxc launch ubuntu:16.04 falcon
	lxc launch ubuntu:12.04/i386 falcon

Get a list of OS images

	lxc image list images:

Start a shell inside a container

	lxc exec falcon bash

See running containers

	lxc list

Start/stop a container

	lxc start falcon
	lxc stop falcon
	lxc restart falcon
	lxc pause falcon

Move files into/out of a container

	lxc file push myfile falcon/path/to/dest
	lxc file pull falcon/path/to/source myfile
	lxc file edit <container>/<path>

Limit how much disk space a container can use (ZFS/btrfs only)

	lxc config device set falcon root size 20GB

Add a remote lxd to control

	lxc remote add tatooine

Create and launch a container on a remote host

	lxc launch ubuntu:16.04 tatooine:cantina

Connect to a remote container

	lxc exec tatooine:cantina bash

Move a container from one instance of lxd to another

       lxc stop falcon
        lxc move falcon tatooine:bar

Automatic Container Setup upon First Boot

Cloud-init is a de facto standard for specifying container configuration. May have originated with AWS. With it you can do things on first boot like:

copy ssh keys into the containerupdate all packages to the latestpre-install packagesetc.


   lxc launch ubuntu:16.04 falcon --config=user.user-data="$(cat cloud-init.yaml)"


# Update apt database on first boot
# (ie run apt-get update)
# Default: true
# Aliases: apt_update
package_update: true

# Upgrade the instance on first boot
# (ie run apt-get upgrade)
# Default: false
# Aliases: apt_upgrade
package_upgrade: true

 - rsync

# add each entry to ~/.ssh/authorized_keys for the configured user or the
# first user defined in the user definition directive.
  - ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAu815gmOvEKtfzWp2YQvhz/vpeNX5XczpfKgSxExocjuUV2L70mRHhtF45TwgNdcgWoW5QmYVDrAyuJvywG8NVM77s+UzDrllm+4s7sBBYqZ8kawLjVlHF6NNJn5EhPE5AJGGiTtI0QgM7YGUGx8ZkIC2/VFOxiYjfJV2S9oTHZW3NNc8THb7gBfROxu5KVHIC2Mz9JToZSLX3Evl05HFjYW6Ijs+00af7VBcgXRnEWCZNmbI8G4PSHLSo0NzH1mPPNzAavCfLKZ4MGF10KPWDdsx/YbNPPlr8ZIDCDW3W2N/ldKu8GSfOfNti7KlAj2HUVgupwOQlClWnIozye3eBw==
  - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCUPpQPBwOhs2Bk20ZJO0OdjZOVyYOsJxldl+P8s8LTvYDLkaxLZGtaIyaQISybI/5kUQa6soPhxn8x1lzDWnQU109pdFNbTlqtnQZi/lBu8qwMzeaWf2PL/Dd7F7ha5VA11omtBM87f5rRm4hGT3i96WxDg6/KW2/oqVBufa9P7WMQKRyKuSB0Tw5GzJrFcUvUDYDJ2KYIeCVfPUiinTrdVSCUMuPdhLxbRag//8OrN4+ACON+Gbe0l0cx172HHHcfaQZmrlb3W7JuyQg2m6BO45SC8/qpL50fDld1LmswrqzwOqwwlF3dq3x67sei3puP5vZIVhOEq3gGIQxyvb/5
439 views0 comments


bottom of page