This episode breaks down the anatomy of LXC: namespaces (PID, mount, network, UTS, IPC, user) as isolation, cgroups (cgroup2) as resource limits, plus the liblxc components, CLI tooling, and the configuration directory structure that make up a container.

Now that we understand LXC's history from episode 1, let's break down its anatomy. How can LXC run a full distro as if it were its own machine when it's actually just a process on the host? The answer lies in two kernel pillars: namespaces for isolation and cgroups for resource limits. Plus the software components that wire the two together into a user-friendly interface.
Episode 2 is the conceptual foundation. Every number, flag, and config line in the following episodes will trace back to the concepts here. Master these first, and everything else is just practice.
Namespaces make each container see its own environment as if it were the only system in the world. The six main namespaces LXC uses:
init, not the host's init.Try viewing the currently active namespaces for a host process:
ls -l /proc/self/ns/Each line points to the respective namespace inode. Two processes sharing the same inode means they're in the same namespace — that's how you check isolation.
cgroups (control groups) limit and measure resources: CPU, memory, and I/O. Modern LXC uses cgroup2 (unified hierarchy), which is cleaner and more consistent. With cgroups, one memory-hungry container can't starve the host — its allocation is already capped.
stat -fc %T /sys/fs/cgroup/An output of cgroup2fs indicates the unified hierarchy is active. In episode 7 we'll configure limits via lxc.cgroup2.memory.max and lxc.cgroup2.cpu.max.
Tip
The most fitting metaphor: namespaces are the walls between rooms (each room can't see the contents of another room), while cgroups are the electricity and water meters per room (you can't use more than your quota). Together they let one host house many "homes".
liblxc is the core library written in C. It manages the container lifecycle: create, start, stop, attach, plus namespaces isolation and cgroups setup. All the tooling on top is just a wrapper around this library. If you later write your own integrations (e.g. via Python or Go), you'll still be talking to liblxc.
The official tooling follows the lxc-<action> pattern:
lxc-create — creates a container.lxc-start — starts a container.lxc-stop / lxc-shutdown — stops a container.lxc-attach — runs a command inside a container.lxc-ls — lists containers.lxc-info — runtime information.lxc-snapshot / lxc-copy — snapshots and cloning.lxc-checkconfig — kernel readiness verification.They can also be invoked through one modern binary lxc with subcommands, e.g. lxc-ls -f.
LXC stores its configuration in several locations:
/etc/lxc/ — global host configuration: lxc.conf, default.conf, lxc-usernet, and templates./etc/lxc/lxc.conf — global configuration (e.g. lxc.lxcpath for the container location)./etc/lxc/default.conf — the defaults every new container uses (e.g. the lxcbr0 network bridge).~/.config/lxc/ — per-user configuration for unprivileged containers, including a private default.conf./var/lib/lxc/<name>/ — the container directory: config, rootfs, and logs.Look at what already exists on your host:
ls -la /etc/lxc/
ls -la ~/.config/lxc/To wrap up the anatomy, follow its lifecycle:
lxc-create copies a template/system image into a new rootfs and writes the container config.lxc-start asks liblxc to create new namespaces, set up cgroups, then execs the container init as PID 1.lxc-attach enters the already-running namespaces to run a command.lxc-stop sends a signal for the container to stop, then cleans up the namespaces and cgroups.We'll actually execute each of these steps starting in episode 4.
Key takeaways:
liblxc is the low-level C runtime that executes everything.lxc-* tooling is the CLI interface on top of liblxc./etc/lxc/, ~/.config/lxc/, and /var/lib/lxc/<name>/.In the next episode 3 we'll install LXC and verify the kernel — the lxc package on Ubuntu, the lxc-* tools and templates, and making sure lxc-checkconfig passes for namespaces, cgroups, and overlayfs. This is the first practical step now that our conceptual foundation is solid.