be private and internal to the system or publicly accessible (for example, an
API). Containers make it easier to create systems using this architecture.
Chapter 12, “Command-Line Master Class, Part 2,” has a section that
describes a way to confine a script to a directory, which is often called
running in a chroot jail. This concept, borrowed from the FreeBSD world, can
be used to prevent processes from accessing files or resources outside the
directory (the chroot jail) in which the process is confined. You can think of
containers as a stronger, more powerful, and better-isolated version of a
chroot jail.
You need infrastructure, which could be a local machine such as a developer’s
laptop or a set of physical servers in a data center or a set of cloud-based
servers running as virtual machines in one of the public clouds mentioned in
Chapter 31, “Ubuntu in the Cloud.”
On top of the infrastructure you run an operating system—in this case,
Ubuntu. Over the past several years, changes to the Linux kernel (specifically
the addition of control groups, or cgroups) and the development of a new
initialization system called systemd (which uses cgroups) have expanded the
ability to control and isolate user processes. Combining this with Linux kernel
work on user namespaces, which allow the mapping of user and group IDs on
a per-namespace basis, provides the foundation for containers. The user
namespaces work allows a process to have root privileges within a defined
user namespace while being a normal unprivileged process outside it. Because
it is now possible to contain user and group privileges for operations to a
certain subset of a system, the idea became known as running in a container.
The following sections of this chapter list and describe specific technologies.
They are presented so that each section builds on the preceding one. There are
“brands” and options out there besides the ones listed here, but this chapter
presents prime examples of breakthrough technologies that have made the
idea of containers progressively easier and more practical. As with some of
the other overview-style chapters in this book, entire books could be and have
been written about each of these, so we must content ourselves here with a
high-level overview that provides enough information to give you a basic
understanding and a few guideposts to help you discover where you might
want to learn more.
LXC and LXD
Once user namespaces existed, it became possible to contain processes, but it
still was not terribly easy or even practical to do this at any scale. The Linux