Adetayo Akinsanya unkletayo.dev

The Atomic Unit of Scheduling: Why Kubernetes Uses Pods Instead of Containers

Understanding co-scheduling guarantees, shared namespaces, sidecars, and init containers.

Adetayo Akinsanya (unkletayo) 2026-09-11

Part 8 in Series — Catch up on the previous article: Informers, Listers, and the HTTP/2 Watch API: Efficient State Synchronization (Part 7) before diving into this post.

A software team designs a microservice that writes application access logs to a local disk path: /var/log/app.log.

To ship these logs to a central Elasticsearch cluster, the team configures a secondary log-shipper container (Fluentd).

In a raw container management system, the team deploys both containers independently.

The scheduling algorithm evaluates cluster resource availability:

  • It schedules the web-app container onto Worker Node 01.
  • It schedules the fluentd log-shipper container onto Worker Node 04.

The deployment fails immediately.

The fluentd container on Node 04 searches for /var/log/app.log, but the file does not exist because the web-app container is generating log files on physical disk drives attached to Node 01, hundreds of miles away across the cloud data center.

Why did scheduling individual containers fail?

To support tightly coupled multi-container helper patterns, Kubernetes does not schedule raw containers. The atomic scheduling unit in Kubernetes is the Pod.


1. What Is a Pod?

A Pod is the smallest deployable, schedulable computing unit in Kubernetes.

A Pod represents a single instance of a running application process, consisting of one or more containers that share network namespaces, storage volumes, and IPC resources:

+-------------------------------------------------------------------+
|                            POD SANDBOX                            |
|                                                                   |
|   +-----------------------------------------------------------+   |
|   |                  PAUSE CONTAINER (IP: 10.244.1.15)        |   |
|   |         Holds open Network & IPC Namespaces               |   |
|   +-----------------------------------------------------------+   |
|         |                                         |               |
|         | Shared NetNS / IPC                      | Shared NetNS  |
|         v                                         v               |
|   +-----------------------+             +---------------------+   |
|   | Container 1: App      |             | Container 2: Sidecar|   |
|   | (Node.js API Server)  |             | (Envoy Proxy / Log) |   |
|   +-----------------------+             +---------------------+   |
|               \                             /                     |
|                v                           v                      |
|   +-----------------------------------------------------------+   |
|   | SHARED POD VOLUMES (Mounted into both containers)         |   |
|   +-----------------------------------------------------------+   |
+-------------------------------------------------------------------+
                  PHYSICAL WORKER NODE (Node 01)

2. The Three Fundamental Guarantees of a Pod

When containers are grouped into a Pod, Kubernetes enforces three structural guarantees:

Guarantee 1: Co-Location Scheduling

All containers belonging to the same Pod are guaranteed to be scheduled onto the exact same physical or virtual worker node. They are never split across multiple machines.

Guarantee 2: Shared Network Namespace

All containers in a Pod share the exact same Network Namespace (created by the infra Pause Container):

  • They share a single IP address (e.g., 10.244.1.15).
  • They can communicate with each other over localhost on different port numbers (e.g., web-app listens on localhost:8080, sidecar communicates over localhost:9090).

Guarantee 3: Shared Storage Volumes

Pod-level volumes are mounted into the filesystems of all containers inside the Pod, enabling high-speed in-memory or disk file sharing between co-located containers.


3. Multi-Container Pod Design Patterns

While most Pods contain a single application container (1-to-1 mapping), multi-container Pods enable three powerful software design patterns:

Pattern A: The Sidecar Pattern

An auxiliary container enhances or extends the primary application container without modifying its source code.

  • Example: An Envoy proxy container sitting alongside a web app to handle TLS termination, circuit breaking, and rate limiting.

Pattern B: The Init Container Pattern

Init Containers (initContainers) run before main application containers start. They execute sequentially to completion:

spec:
  # Executed sequentially BEFORE main containers start:
  initContainers:
  - name: wait-for-db
    image: busybox
    command: ['sh', '-c', 'until nc -z db-service 5432; do sleep 2; done;']

  # Main application containers:
  containers:
  - name: web-app
    image: my-app:v1.0

Benefit: Guarantees that database schema migrations or network dependency checks complete successfully before launching the primary web server!


Pattern C: The Adapter / Ambassador Pattern

  • Adapter: Standardizes application outputs (e.g., transforming non-standard log formats into unified JSON metrics before sending to Prometheus).
  • Ambassador: Proxies outgoing connections, masking complex external endpoints behind a simplified localhost address.

Raw Containers vs Kubernetes Pods

Capability / AttributeRaw Standalone ContainerKubernetes Pod
Atomic Scheduling UnitSingle container processGroup of co-located containers
Placement GuaranteeScheduled independently across clusterGuaranteed placement on the SAME node
IP Address AllocationIndividual IP per containerSingle shared IP address for all Pod containers
Localhost Inter-CommunicationRequires custom network bridgeSupported natively (localhost:port)
Lifecycle DependencyIsolated lifecycleShared volume mounts & init container sequencing

Summary & Next Steps

Pods provide the atomic scheduling abstraction required for modern microservice architectures:

  • Raw Containers scheduled independently break co-located file sharing and proxy patterns.
  • Pods guarantee that co-located containers share host nodes, network namespaces (IP addresses), and storage volumes.
  • Pause Containers hold open shared network and IPC namespaces.
  • Sidecar and Init Container Patterns enable modular separation of concerns without modifying primary application code.

In the next article, we examine Controllers Deep Dive: ReplicaSets, Deployments, and Rolling Update Mechanics.

References & Further Reading

  1. Cloud Native Computing Foundation. Service VIPs and Service Routing Architecture. CNCF Docs.
  2. Tigera. Calico Linux Kernel Netfilter, BGP, and IPVS Routing in Kubernetes. Calico Docs.
  3. Kerrisk, M. (2010). The Linux Programming Interface (Sockets & Networking). No Starch Press.

Up Next in Series →

Part 9: Controllers Deep Dive: ReplicaSets, Deployments, and Rolling Update Mechanics

Continue to Part 9 →