Container

Also known as: containerization

On this page 7

A container is a running, isolated set of processes that packages an application together with its libraries, runtime and configuration, while sharing the kernel of the host operating system. In cloud computing and the Containers topic, the container is the standard unit for building, shipping and running software, because the same packaged workload behaves the same way on a laptop, a test server and a production cluster.

A container is not a lightweight virtual machine. It contains no kernel of its own and boots nothing; it is an ordinary process that the kernel isolates with namespaces, limits with control groups and starts from a read-only container image. That design explains its main advantages, fast startup and high density, and its main weakness, a thinner isolation boundary.

How containers isolate processes on a shared kernel

A container is built from Linux kernel features, not from a separate product. Namespaces give a process its own view of system resources, so it sees only its own process tree, network stack and file system. Control groups (cgroups) cap and account for CPU, memory and I/O, and security layers such as seccomp, capabilities and SELinux or AppArmor restrict what the process may ask the kernel to do.

The table below summarizes the kernel mechanisms that together form a container.

MechanismWhat it isolates or limitsPractical effect
PID namespaceProcess IDsThe application sees itself as PID 1
Network namespaceInterfaces, routes, portsEach container has its own IP and port space
Mount namespaceFile system viewThe container sees only its image and volumes
User namespaceUser and group IDsRoot inside can map to an unprivileged host user
cgroups v2CPU, memory, I/O, process countA memory limit triggers an out-of-memory kill
seccomp filterSystem callsBlocks rarely needed, risky kernel calls
Kernel features behind a Linux container

The file system comes from a layered container image mounted through a union file system such as OverlayFS. Image layers are read-only and shared between all containers that use them, and each container adds a thin writable layer that disappears when the container is removed. Data that must survive therefore belongs in volumes, not in the container itself.

Container standards, runtimes and lifecycle

Containers are portable because the industry agreed on Open Container Initiative (OCI) specifications: the image specification defines how layers and metadata are packaged, the runtime specification defines how a bundle is started, and the distribution specification defines how registries serve images. Any compliant tool can run an image built by any other compliant tool.

Several layers of software cooperate to run a single container, each with a distinct responsibility.

LayerExamplesResponsibility
Build toolDocker build, BuildKit, BuildahTurns a Dockerfile into an OCI image
RegistryPublic or private OCI registriesStores and distributes image layers
High-level runtimecontainerd, CRI-OPulls images, manages container lifecycle
Low-level runtimerunc, crunCreates namespaces and cgroups, starts the process
Sandboxed runtimegVisor, Kata ContainersAdds a user-space kernel or a microVM boundary
OrchestratorKubernetes, NomadSchedules containers across many hosts
Software layers that run a container

The lifecycle is short and predictable: a container is created from an image, started, stopped and removed. Because a new container can replace an old one in seconds, teams treat containers as immutable and disposable: they rebuild the image and redeploy instead of patching a running container.

Containers compared with virtual machines

The essential difference is the level of virtualization: a virtual machine emulates hardware and runs its own kernel, while a container shares the host kernel and isolates only the user space. The comparison below shows how this affects everyday operations.

PropertyContainerVirtual machine
KernelShared with the hostOwn guest kernel
Startup timeTypically under one secondTens of seconds to minutes
Typical image sizeTens to hundreds of megabytesSeveral gigabytes
Isolation strengthProcess-level, kernel attack surface sharedHardware-enforced by the hypervisor
OS flexibilityLinux containers need a Linux kernelAny guest OS for the architecture
Best fitMicroservices, CI jobs, scalable stateless appsMixed operating systems, strong tenant isolation
Container versus virtual machine

The two technologies are complementary. In public clouds, containers usually run inside virtual machines, which provide the tenant boundary, while containers provide packaging and density. Where untrusted code must run in containers, sandboxed runtimes such as gVisor or Kata Containers restore much of the VM-level isolation.

Designing applications for containers

An application gains the most from containers when it follows a few design rules. The most important is one main process per container, so that the container’s lifecycle equals the application’s lifecycle and health checks, logs and restarts stay unambiguous.

  • Keep containers stateless: store sessions, uploads and databases in volumes or external services.
  • Configure through environment variables and mounted files, so the same image runs in every environment.
  • Log to standard output and standard error, letting the platform collect and ship the logs.
  • Set CPU and memory limits so that one container cannot starve its neighbors on the node.
  • Run as a non-root user and drop Linux capabilities that the application does not need.
  • Use small base images and multi-stage builds to reduce size and vulnerability count.

A single container is easy to run by hand; dozens are not. Local multi-container setups are typically described with Docker Compose, while production fleets rely on an orchestrator that handles scheduling, scaling, service discovery and rolling updates.

Common container problems and their causes

Most container incidents come from a small set of misunderstandings about ephemeral storage, resource limits and privileges. The table below links typical symptoms to their usual cause and fix.

SymptomLikely causeFix
Data lost after restartFiles written to the writable layerMount a persistent volume
Exit code 137Memory limit exceeded, OOM killRaise the limit or reduce memory use
Slow, throttled responsesCPU quota reached within each periodAdjust CPU limits, profile hot paths
Image with hundreds of CVEsLarge, outdated base imageUse a minimal base and rebuild regularly
Container escape riskPrivileged mode or mounted Docker socketRemove privileges, use rootless runtimes
Zombie processesNo init to reap child processesAdd a minimal init or use the runtime flag
Typical container failures

The largest misconception is that a container is a security boundary equal to a VM. A kernel vulnerability can affect every container on the host, so multi-tenant platforms layer additional isolation rather than relying on namespaces alone.

The short version

A container is like a standardized shipping container for software. Before shipping containers, every cargo was packed differently and loading ships was slow. After standardization, any crane, truck or ship could move any container without caring what was inside.

Software containers do the same. A program is packed together with everything it needs to run, so it works the same way on any computer that can run containers. Many containers share one machine efficiently because they share its core operating system instead of each bringing a full copy.

Where it makes a difference

An online retailer runs its checkout service on three virtual machines that were configured by hand over several years. Each server has slightly different library versions, so a release that passes testing occasionally fails in production, and adding capacity before a holiday sale takes about two days of manual setup.

The team packages the checkout service as a container image of roughly 120 MB, built automatically on every merge and stored in a private registry. The same image runs on developer laptops, in the test pipeline and in production, with only environment variables changing between them. Each container gets a limit of 1 vCPU and 512 MiB of memory.

During the next sale, the platform scales from 6 to 40 checkout containers in under two minutes as traffic rises, then scales back down overnight. Release failures caused by environment differences disappear, because what was tested is exactly what runs.