The Pause Container: Kubernetes' Silent Foundation
Table of Contents
TL;DR #
The pause container is a minimal container that runs in every Kubernetes pod, holding the Linux namespaces (network, IPC, PID) that other containers share. This enables localhost communication and maintains stable pod resources even when application containers restart.
What is the Pause Container? #
The pause container is an infrastructure container that Kubernetes automatically adds to every pod. It’s typically based on an extremely minimal image (often just a few hundred kilobytes) that does essentially nothing—it just sleeps indefinitely.
You can see it in action by inspecting the containers on a node:
CONTAINER ID IMAGE COMMAND
0c49f0950dcf rancher/mirrored-pause:3.6 "/pause"
Why Does Kubernetes Need It? #
The pause container serves as the “parent” container for all other containers in a pod. Here’s why that matters:
Namespace Holder #
In Linux, containers rely on namespaces to provide isolation—network namespaces, IPC namespaces, PID namespaces, and others. When multiple containers need to share these namespaces (as they do in a Kubernetes pod), one container must “own” them.
The pause container is that owner. It creates and holds the namespaces, and all other containers in the pod join those namespaces. This is what allows containers in a pod to:
- Share the same network interface and IP address
- Communicate via
localhost - Share Inter-Process Communication (IPC) resources
- See each other’s processes (when PID namespace sharing is enabled)
Stability During Restarts #
Application containers crash and restart. When a container restarts, it typically gets new namespaces. But in a pod, we want continuity—the network IP should remain the same, shared volumes should stay mounted, and sibling containers shouldn’t be affected.
Because the pause container runs throughout the pod’s lifecycle and doesn’t restart (unless the entire pod is recreated), it maintains these shared namespaces. Application containers can come and go, but the foundational infrastructure persists.
PID 1 Responsibilities #
In Linux, PID 1 has special responsibilities, including reaping zombie processes. The pause container acts as PID 1 within the pod’s PID namespace, handling these system-level tasks so application containers don’t have to implement this logic.
How It Works in Practice #
When Kubernetes creates a pod, the sequence looks like this:
- Create pause container — Kubernetes starts the pause container first
- Establish namespaces — The pause container creates the network, IPC, and optionally PID namespaces
- Join namespaces — Application containers are started with flags to join the pause container’s namespaces
- Share resources — All containers in the pod now share the same network stack, IPC mechanisms, and more
Here’s a visual representation of a pod with a pause container and two application containers:
Holds: Network, IPC, PID Namespaces
Pod IP: 10.0.1.5"] App["app Container
Port: 8080"] Envoy["envoy Sidecar
Port: 15001"] Pause -->|shares namespaces| App Pause -->|shares namespaces| Envoy App <-.->|communicate via localhost| Envoy
You can see this namespace sharing using docker inspect:
| |
"NetworkMode": "container:a1b2c3d4e5f6"
The application container’s network mode points to the pause container’s ID, indicating namespace sharing.
The Pause Container Image #
The pause container image is deliberately minimal. The actual implementation is just a simple C program that fits in about 50 lines of code.
The program performs a few key functions:
- Signal handlers — Registers handlers for
SIGINTandSIGTERMto shut down gracefully - Zombie reaper — The
sigreapfunction handlesSIGCHLDsignals to reap zombie processes (more on this below) - Infinite sleep — The
pause()call suspends execution until a signal is received - Minimal footprint — No networking logic, no volume management, just namespace holding and process management
Reaping Zombie Processes #
One critical but often overlooked responsibility of the pause container is cleaning up zombie processes. Let’s break down what this means in simple terms.
What Are Zombie Processes? #
When a process finishes running in Linux, it doesn’t immediately disappear. The operating system keeps a small entry for it (storing its exit code) until the parent process retrieves that exit code using the wait system call. Until the parent calls wait, the dead process is called a “zombie”—it’s not really running, but it’s still taking up space in the process table.
Normally, zombies exist for just a split second. But if a parent process crashes or forgets to call wait, zombies can pile up indefinitely, wasting memory.
The PID 1 Responsibility #
In every Linux process namespace, one process has PID 1—the init process. This process has a special job: when any process becomes orphaned (its parent dies), the init process automatically becomes the new parent. The init process must then call wait on these orphaned children to clean them up.
In a Kubernetes pod with PID namespace sharing enabled, the pause container runs as PID 1. Here’s what the process tree looks like:
How the Pause Container Reaps Zombies #
The pause.c source code includes a sigreap function that handles zombie reaping. When any child process exits, the kernel sends a SIGCHLD signal to the parent. The pause container catches this signal and calls waitpid in a loop to clean up all zombie processes.
This simple mechanism ensures that even if application containers don’t properly clean up their child processes, zombies won’t accumulate in the pod.
PID Namespace Sharing Configuration #
It’s important to note that PID namespace sharing is not always enabled by default:
- Kubernetes 1.7 — Enabled by default with Docker 1.13.1+ (can be disabled with
--docker-disable-shared-pid=true) - Kubernetes 1.8+ — Disabled by default (enable with
--docker-disable-shared-pid=false)
Without PID namespace sharing, each container has its own PID 1 and must handle zombie reaping itself. Most applications don’t do this properly, which can lead to memory leaks from accumulated zombie processes.
Implications for Pod Design #
Understanding the pause container helps explain several Kubernetes behaviors:
Why Pods Share localhost #
Because all containers in a pod share the pause container’s network namespace, they share the same loopback interface. A container listening on localhost:8080 is accessible to sibling containers at that same address. This is commonly used in service mesh architectures where an Envoy sidecar proxy intercepts traffic to and from the application container.
Why Pods Have a Single IP #
The pause container gets assigned the pod’s IP address. All other containers share this network namespace and therefore share the IP.
Why Container Restarts Don’t Change Pod IP #
The pause container maintains the network namespace throughout the pod’s life. Even if every application container restarts, the pod IP remains stable because it’s anchored to the pause container.
Observability and Troubleshooting #
The pause container is usually invisible in standard Kubernetes operations, but you can observe it:
Using crictl (on the node):
| |
Checking resource usage:
The pause container consumes minimal resources, but in large clusters with thousands of pods, these can add up. Some organizations customize the pause image or tune resource requests accordingly.
Custom pause images:
You can configure Kubernetes to use a custom pause container image via kubelet configuration:
| |
Modern Alternatives and Evolution #
While the pause container is standard in Kubernetes, there are ongoing discussions about alternatives:
- Rootless containers — Projects exploring rootless Kubernetes need special handling for namespace management
- Windows containers — Windows uses different primitives, leading to different implementations of shared namespaces
- Alternative runtimes — Container runtimes like
gVisororKata Containersimplement pod semantics differently while maintaining API compatibility
Despite these variations, the fundamental concept—a stable infrastructure container holding shared namespaces—remains central to the pod abstraction.
Conclusion #
The pause container is Kubernetes’ elegant solution to a complex problem: how do you group multiple containers together with shared resources while allowing them to restart independently? By introducing a minimal, stable infrastructure container that holds Linux namespaces, Kubernetes provides the foundation for pod networking and inter-container communication.
Next time you see /pause in a container listing, you’ll know it’s not a bug or an artifact—it’s the invisible glue holding your pods together.