LXD

On this page 7

LXD is a management daemon for system containers and virtual machines on Linux. It runs complete Linux distributions as lightweight containers built on LXC, and since version 4.0 it can also run full virtual machines through QEMU and KVM, all controlled through one REST API, one image catalog and one command-line client.

In Linux virtualization, LXD occupies the space between application containers such as Docker and full hypervisor stacks such as libvirt or Proxmox VE. It is developed by Canonical and distributed mainly as a snap package; the community fork Incus, created in 2023, continues the same design under the Linux Containers project.

How LXD manages containers and virtual machines

LXD runs as a privileged daemon that exposes a REST API, locally over a Unix socket and optionally over HTTPS with client certificates. The command-line tool, confusingly named lxc, is just one client of that API. For containers, LXD uses liblxc to create namespaces, cgroups and security profiles; for virtual machines, it starts QEMU with KVM acceleration and a small agent inside the guest for file transfer and command execution.

Every instance is created from an image, a root file system plus metadata, downloaded from a remote image server and cached locally. Configuration is layered: profiles hold reusable settings such as network interfaces, storage and limits, and each instance can add its own overrides. Projects separate instances, images and profiles for different teams or purposes on the same host.

The following table summarizes the main building blocks of an LXD installation.

Building blockPurposeTypical example
InstanceA container or virtual machineUbuntu 24.04 container named web1
ImageTemplate for new instancesDistribution image from a remote server
ProfileReusable configuration setDefault profile with bridge and root disk
Storage poolBackend for root disks and volumesZFS, Btrfs, LVM, Ceph or a directory
NetworkConnectivity for instancesManaged bridge such as lxdbr0 or OVN
ProjectIsolated namespace for resourcesSeparate projects for test and production
Main LXD building blocks

System containers compared with application containers and VMs

LXD’s containers are system containers: they boot a full init system such as systemd, run several services and behave like lightweight virtual machines. Application containers in Docker or Podman usually run one process per container from an immutable image.

TechnologyUnit of isolationKernelTypical use
LXD containerFull Linux systemShared host kernelLong-lived servers and dev environments
LXD virtual machineFull machineOwn guest kernelOther kernels, Windows, stronger isolation
LXC aloneFull Linux systemShared host kernelLow-level tooling without a daemon API
Docker or PodmanSingle applicationShared host kernelPackaging and deploying applications
libvirt with KVMFull machineOwn guest kernelTraditional VM management
systemd-nspawnFull Linux systemShared host kernelSimple containers on systemd hosts
LXD compared with neighboring technologies

Because containers share the host kernel, they start in about a second and add very little memory overhead, but they can only run Linux and must be compatible with the host kernel features. LXD virtual machines boot more slowly and use more memory, but provide a separate kernel and a stronger isolation boundary.

Storage, networking and clustering

LXD’s practical strength lies in storage drivers with copy-on-write. On ZFS or Btrfs, creating an instance from a cached image or taking a snapshot is nearly instant and initially consumes almost no extra space. The plain directory driver works everywhere but copies files and lacks efficient snapshots.

DriverSnapshots and clonesBest suited to
ZFSFast, space-efficient, with quotasMost single-host and production setups
BtrfsFast copy-on-write subvolumesHosts already using Btrfs
LVM thinBlock-level thin snapshotsEnvironments standardized on LVM
Ceph RBDShared, distributed storageClusters needing migration between hosts
DirectoryFull copies, slowTesting and simple laptops
Storage drivers and their characteristics

For networking, LXD can create a managed bridge with DHCP, DNS and NAT, attach instances directly to physical networks with macvlan or bridged interfaces, or use OVN for software-defined networks across hosts. Several LXD servers can form a cluster with a shared database, distributing instances and allowing migration between members.

Typical workflows and configuration

A typical workflow begins with lxd init, which configures a storage pool, a network and optional clustering. Instances are then created with commands such as lxc launch ubuntu:24.04 web1 for a container or the same command with --vm for a virtual machine. Resource limits are set with keys such as limits.cpu and limits.memory.

  • Snapshots before changes: lxc snapshot and lxc restore make risky upgrades reversible in seconds.
  • Cloud-init integration: user data in a profile configures packages, users and SSH keys at first boot.
  • Device passthrough: GPUs, USB devices and host directories can be attached to instances.
  • Remote management: one client can control several LXD servers added as remotes.
  • Export and migration: instances can be exported as backups or copied between hosts.

Security considerations and common pitfalls

LXD containers are unprivileged by default: root inside the container is mapped to an unprivileged user ID range on the host, so a process escaping the container has no host root privileges. Setting security.privileged=true removes this protection and should be reserved for exceptional cases.

  • Membership in the lxd group equals root access on the host, because group members can create privileged instances and mount host paths.
  • Nested containers such as Docker inside LXD need security.nesting=true and careful review.
  • Kernel-dependent workloads such as custom modules or a different kernel version belong in a virtual machine, not a container.
  • Confusing the lxc client with classic LXC tools leads to wrong commands; they are separate interfaces.
  • Image server changes after the Incus fork mean some community image sources may not be available to LXD, so image remotes should be checked.

A plain-language summary

LXD lets one Linux computer act like many separate small computers. Each one has its own name, its own network address and its own installed programs, as if it were a different machine.

Most of them are very light, because they share the main computer’s core. When stronger separation is needed, LXD can create a complete virtual machine instead. Both kinds are managed with the same simple commands.

An example from practice

A university computer science department needs isolated Linux servers for about sixty students in a networking course. Each student must have root access, install packages and break things without affecting others, and the department has only two physical servers.

The administrator installs LXD on both servers, forms a small cluster with a ZFS storage pool on each node and creates a project for the course. A profile sets limits of two CPUs and two gigabytes of memory per container, and cloud-init adds each student’s SSH key. Before every lab, a script takes snapshots of all instances.

Containers start in seconds, a broken system is restored from its snapshot almost instantly, and a few students who need a custom kernel get LXD virtual machines from the same tools. The two servers handle the whole course comfortably.