How Linux Implements LXC for Virtualization
Linux Containers (LXC) implement lightweight system virtualization by using built-in Linux kernel primitives rather than emulating physical hardware through a hypervisor. By combining kernel namespaces for process isolation, control groups (cgroups) for resource constraints, and security modules for confinement, LXC creates isolated user environments that share the host system’s kernel. This architecture provides the look and feel of a traditional virtual machine—complete with init systems and system services—with near-native performance and minimal system overhead.
Kernel Namespaces: Complete Environment Isolation
The core of LXC’s isolation mechanism is Linux namespaces. A namespace wraps a global system resource in an abstraction that makes it appear to processes within the namespace that they have their own isolated instance of the resource. LXC configures several key namespaces:
- PID Namespace: Isolates the process ID space. The
container's primary process becomes PID 1 (often an init system like
systemd), completely unaware of processes running on the host or in other containers. - NET Namespace: Provides independent network stacks,
including loopback interfaces, IP routing tables, firewall rules, and
virtual network interfaces (such as
vethpairs bridged to the host network). - MNT Namespace: Isolates filesystem mount points. The container can mount and unmount filesystems without affecting the host or other containers.
- UTS Namespace: Isolates the hostname and NIS domain name, allowing the container to maintain its own unique network identity.
- IPC Namespace: Isolates Inter-Process Communication resources, such as System V IPC objects and POSIX message queues, preventing cross-container messaging.
- USER Namespace: Maps user and group IDs between the container and the host. A root user (UID 0) inside the container can be mapped to an unprivileged non-root UID on the host, neutralizing most container-breakout attacks.
Control Groups (cgroups): Resource Metering and Enforcement
While namespaces prevent processes from seeing outside their sandbox, control groups (cgroups) ensure they do not consume more than their allotted share of system resources. LXC leverages cgroups to define strict resource quotas:
- Memory: Restricts total RAM and swap usage to prevent out-of-memory (OOM) conditions on the host.
- CPU: Allocates CPU shares, caps execution time via
the Completely Fair Scheduler (CFS), or pins processes to specific CPU
cores using
cpuset. - Block I/O (blkio): Throttles disk read and write speeds and assigns I/O priorities to prevent storage bottlenecks.
- Devices: Restricts which character and block
devices inside
/devthe container can create or access.
Filesystem Structure and
pivot_root
Unlike traditional virtual machines that require separate virtual disk images formatted with an emulated filesystem, LXC directly uses host directories or storage volumes.
During initialization, LXC prepares a root filesystem
(rootfs) for the container. It uses the
pivot_root system call—a more secure alternative to
chroot—to switch the container's root directory to the new
filesystem. The host's original root filesystem is then unmounted inside
the container's mount namespace, making it inaccessible to the
container’s processes. LXC can run on standard directories or take
advantage of advanced storage backends like ZFS, Btrfs, or LVM for
instantaneous snapshots and copy-on-write functionality.
Security Confinement
LXC secures the boundary between the container and the host kernel using multiple defense layers:
- POSIX Capabilities: Linux divides root privileges
into distinct capabilities. LXC drops dangerous capabilities—such as
CAP_SYS_ADMIN,CAP_SYS_RAWIO, andCAP_SYS_MODULE—ensuring that a root process inside a container cannot modify hardware, load kernel modules, or disrupt the host. - Seccomp (Secure Computing Mode): LXC applies seccomp filters to block unwanted system calls that are not needed by normal user-space programs, reducing the kernel attack surface.
- AppArmor and SELinux: Mandatory Access Control (MAC) profiles further restrict file access, network operations, and administrative functions, preventing processes inside the container from escaping their designated domains.
Userspace Management via
liblxc
At the userspace level, LXC provides liblxc, an API and
set of command-line tools (lxc-create,
lxc-start, lxc-attach) that coordinate these
kernel mechanisms. When a container is started, liblxc
reads the configuration file, sets up the network interfaces, constructs
the namespaces, applies cgroup rules, configures security policies,
mounts the root filesystem, and executes the designated init process.
The result is a fully functional, isolated Linux operating system
running alongside the host with zero hardware virtualization
overhead.