A pod is the smallest deployable unit in Kubernetes: a group of one or more containers that are always scheduled together on the same node and share a network namespace, an IP address and storage volumes. Kubernetes never runs a bare container; it runs pods, and every higher-level object such as a Deployment or a Job ultimately creates pods.
Pods are ephemeral by design. A pod is created, runs, and eventually terminates; if it is deleted or its node fails, Kubernetes does not repair it but lets a controller such as a ReplicaSet create a replacement pod with a new name and a new IP address. Stable access to a changing set of pods is provided by a Service.
What containers in a pod share
Containers in one pod behave like processes on a single logical host. They reach each other over localhost, share the same port space and can mount the same volumes, while each keeps its own filesystem image and resource limits.
| Property | Shared across the pod | Notes |
|---|---|---|
| IP address and ports | Yes | Two containers cannot listen on the same port |
| Volumes | Yes, when mounted by each container | emptyDir is a common shared scratch space |
| Node placement | Yes | All containers land on one node |
| Container image and filesystem | No | Each container has its own root filesystem |
| CPU and memory limits | No, set per container | The pod total is the sum for scheduling |
| Process namespace | Optional | Enabled with shareProcessNamespace |
This sharing is implemented by a hidden pause container that holds the network namespace, so the application containers can restart without the pod losing its IP address.
Pod lifecycle and phases
Every pod moves through a defined set of phases, reported in its status field. Within a running pod, the kubelet on the node restarts failed containers according to the restart policy, which is Always, OnFailure or Never.
| Phase | Meaning | Common causes of staying here |
|---|---|---|
| Pending | Accepted but not all containers are running | No node with enough resources, image still pulling |
| Running | Bound to a node, at least one container running | Normal operating state |
| Succeeded | All containers exited with code 0 | Completed Jobs |
| Failed | All containers ended, at least one with an error | Application error under restart policy Never |
| Unknown | State cannot be obtained | Lost contact with the node |
A frequently seen status, CrashLoopBackOff, is not a phase but a container state: the container keeps failing and the kubelet waits an increasing back-off delay, capped at five minutes, between restarts.
Pod design patterns
Most pods run a single application container. Additional containers are justified only when they must share the network or files with the main container and scale together with it.
| Pattern | What the extra container does | Example |
|---|---|---|
| Init container | Runs to completion before the app starts | Database schema migration or config download |
| Sidecar | Runs alongside the app for its whole life | Log shipper or service mesh proxy |
| Ambassador | Proxies outbound connections | Local proxy to a sharded database |
| Adapter | Transforms the app output | Converting metrics to a standard format |
Since Kubernetes 1.29, sidecars can be declared as init containers with restartPolicy Always, which guarantees they start before and stop after the main container.
Pods compared with higher-level objects
Pods are rarely created directly in production. Controllers manage them, adding replication, rolling updates and self-healing.
| Object | Relation to pods | Typical use |
|---|---|---|
| Pod | The running unit itself | Debugging, one-off tests |
| ReplicaSet | Keeps a set number of identical pods running | Managed by Deployments |
| Deployment | Manages ReplicaSets for rolling updates | Stateless services |
| StatefulSet | Pods with stable names and storage | Databases and clustered stores |
| DaemonSet | One pod on each selected node | Node agents and log collectors |
| Service | Stable address routing to matching pods | Load balancing across replicas |
Controllers find their pods through labels and selectors, not through names. A Service, for example, routes to every ready pod whose labels match its selector, which is why a careless label change can silently remove pods from load balancing or attach unrelated pods to it. Pod definitions are therefore usually written as a template inside a Deployment and packaged with tools such as Helm, so that every replica is created from the same specification.
Resource settings, probes and common mistakes
The scheduler places a pod based on its resource requests, while limits cap actual use. A container that exceeds its memory limit is OOM-killed; one that exceeds its CPU limit is throttled. Requests and limits together also set the pod’s quality-of-service class: Guaranteed, Burstable or BestEffort.
- Missing requests let the scheduler overpack nodes, and BestEffort pods are evicted first under pressure.
- No readiness probe sends traffic to pods that are still starting.
- An aggressive liveness probe restarts healthy but slow pods in an endless loop.
- Storing data in the container filesystem loses it whenever the pod is replaced; persistent volumes are required.
- Relying on pod IP addresses breaks after rescheduling, because replacements get new addresses.
In plain words
Think of a pod as a small shared apartment for programs. The programs living there share one street address, one front door and a common storage room, and they always move house together.
Usually only one program lives in each apartment. Sometimes a helper moves in, such as one that collects the main program’s notes. If the apartment is damaged, Kubernetes does not repair it; it builds an identical new one and moves the work there.
A real-world example
An online learning platform runs its web API on Kubernetes through a Deployment with six replicas. Each pod contains the API container, with a request of 250 millicores of CPU and 512 MiB of memory, and a log-shipping sidecar that reads log files from a shared emptyDir volume and forwards them to central storage.
A readiness probe on the API’s health endpoint ensures that new pods receive traffic only after their caches are warm. When a node fails at night, its two pods are lost, the ReplicaSet creates two replacements on healthy nodes within about a minute, and the Service routes requests only to ready pods. Students see no interruption, and the team investigates the failed node the next morning.