What is a Kubernetes Pod? The Smallest Deployable Unit Explained
Kubernetes has a lot of moving parts, but everything starts with the pod. Before you can understand Deployments, Services, DaemonSets, or StatefulSets, you need a clear mental model of what a pod is and how it behaves. Almost every other Kubernetes resource is, at its core, a way to manage groups of pods.
What a Pod Actually Is
A pod is not a container. It is a shared execution environment that holds one or more containers. The containers in a pod share:
- Network namespace -- all containers in a pod share one IP address and one set of ports. They communicate with each other over
localhost. - Volumes -- pods can define storage volumes, and any container in the pod can mount them. This is how sidecar containers share data with the main container.
The practical consequence: if you have two containers in a pod, and container A listens on port 8080, container B cannot also listen on port 8080. They are on the same network.
Pods themselves are ephemeral. They are not rescheduled -- they are replaced. If a pod dies on a node, Kubernetes creates a new pod (with a new name and IP) to take its place. Nothing in Kubernetes assumes a pod will live for any particular amount of time.
A Basic Pod Manifest
You rarely create pods directly in production (you use Deployments), but understanding the pod spec is the foundation for everything else. Here is a pod running an Nginx container:
apiVersion: v1
kind: Pod
metadata:
name: web-server
labels:
app: web
environment: production
spec:
containers:
- name: nginx
image: nginx:1.27-alpine
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 80
initialDelaySeconds: 3
periodSeconds: 5
A few things to note here:
Resource requests and limits are critical. requests tell the scheduler how much to reserve when placing the pod on a node. limits cap what the container can actually use. Without requests, the scheduler places pods blindly and nodes get overcommitted. Without limits, one runaway container can starve everything else on the node.
Probes tell Kubernetes how to check whether the container is healthy. The livenessProbe restarts the container if it stops responding. The readinessProbe controls whether the pod receives traffic from a Service. A container that is running but not yet ready will not have requests sent to it.
The Sidecar Pattern
The most useful reason to put multiple containers in one pod is the sidecar pattern. A sidecar is a helper container that runs alongside the main application container, augmenting it without modifying it.
Common sidecar uses:
Log shipping -- The main container writes logs to a shared volume. A Fluentd or Vector sidecar reads from that volume and forwards logs to a central aggregation system. The application does not need to know anything about the logging backend.
Service mesh proxy -- Tools like Istio inject an Envoy proxy sidecar into every pod. All network traffic flows through the proxy, which handles mTLS, circuit breaking, retries, and telemetry. The application container talks to localhost; the proxy handles everything external.
Init containers -- These run to completion before any regular containers start. They are used for database migration checks, downloading configuration, or populating shared volumes with data the main container needs at startup.
Pods vs Deployments
Standalone pods are rarely used in production. The reason is simple: if the node a pod is on goes down, the pod is gone and is not replaced. Kubernetes does not reschedule pods -- it replaces pods managed by a controller.
A Deployment is the standard way to run stateless application pods. It wraps a pod template and a replica count, and a ReplicaSet controller ensures the desired number of pods matching that template is always running. If a pod crashes, the controller creates a new one. If a node fails, the pods are rescheduled elsewhere.
Deployment
└── ReplicaSet
├── Pod (replica 1)
├── Pod (replica 2)
└── Pod (replica 3)
You define the pod spec in the Deployment's template field. Everything you know about pods -- probes, resource limits, volumes, sidecars -- applies identically when written inside a Deployment.
What CrashLoopBackOff Means
When a pod container keeps exiting, Kubernetes restarts it with exponential backoff: 10s, 20s, 40s, 80s, up to 5 minutes between restarts. This state is shown as CrashLoopBackOff in kubectl get pods.
It does not mean Kubernetes has given up -- it keeps trying. The backoff prevents a broken application from hammering a downstream dependency it cannot connect to. To diagnose:
# Check what the container printed before dying
kubectl logs <pod-name> --previous
# Check events for the pod
kubectl describe pod <pod-name>
The --previous flag shows the last failed container's logs, not the currently-running (or waiting) container. That is usually where the error is.
Understanding pods is the foundation for understanding containerization in Kubernetes. The devops tools guide covers how Kubernetes fits into a broader cloud-native toolchain, and infrastructure as code covers how to manage Kubernetes manifests at scale using Helm and GitOps.
