Kubernetes Pods vs Deployments
How Pods, ReplicaSets, and Deployments relate, why you almost never create Pods directly, and how rolling updates and rollbacks actually happen.
What you'll learn
- ✓What a Pod actually is in Kubernetes
- ✓How ReplicaSets sit between Pods and Deployments
- ✓How rolling updates and rollbacks happen
- ✓When to choose Deployments over StatefulSets or DaemonSets
- ✓Common Deployment misconfigurations to avoid
Prerequisites
- •Basic Kubernetes concepts
What and why
A Pod is the smallest deployable unit in Kubernetes: one or more containers that share network, storage, and a lifecycle. A Deployment is a higher-level controller that manages Pods through ReplicaSets, handling scaling, rolling updates, and rollbacks for you.
You almost never create Pods directly. A bare Pod has no self-healing: if the node it runs on dies, the Pod is gone. A Deployment ensures that the desired number of identical Pods is always running, replacing them when they fail, when nodes drain, or when you change the image.
Mental model
A Deployment owns ReplicaSets. A ReplicaSet owns Pods. When you change the Deployment’s pod template, it creates a new ReplicaSet, scales it up while scaling the old one down, and keeps the old one around for rollback.
apply Deployment v1
|
v
+----------------- Deployment: api -----------------+
| ReplicaSet api-abc (v1, image=app:1.0) |
| Pod api-abc-1 Pod api-abc-2 Pod api-abc-3 |
+---------------------------------------------------+
kubectl set image deploy/api app=app:1.1
|
v
+----------------- Deployment: api -----------------+
| ReplicaSet api-abc (v1, scaling down) |
| Pod api-abc-1 |
| ReplicaSet api-def (v2, scaling up) |
| Pod api-def-1 Pod api-def-2 |
+---------------------------------------------------+
|
v rollout finishes
+----------------- Deployment: api -----------------+
| ReplicaSet api-abc (v1, 0 pods, kept for undo) |
| ReplicaSet api-def (v2) |
| Pod api-def-1 Pod api-def-2 Pod api-def-3 |
+---------------------------------------------------+ Hands-on example
A typical Deployment manifest:
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
replicas: 3
selector:
matchLabels:
app: api
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: ghcr.io/acme/api:1.4.0
ports:
- containerPort: 8000
readinessProbe:
httpGet: { path: /healthz, port: 8000 }
periodSeconds: 5
livenessProbe:
httpGet: { path: /healthz, port: 8000 }
initialDelaySeconds: 10
resources:
requests: { cpu: 100m, memory: 128Mi }
limits: { cpu: 500m, memory: 256Mi }
Apply it:
kubectl apply -f api.yaml
kubectl rollout status deploy/api
When you bump the image to 1.5.0 and apply again, Kubernetes creates a new ReplicaSet, scales it up one Pod at a time (maxSurge: 1), and scales the old one down only after the new Pod’s readiness probe passes (maxUnavailable: 0). Zero downtime, controlled blast radius.
Roll back when something is wrong:
kubectl rollout undo deploy/api
kubectl rollout undo deploy/api --to-revision=3
The old ReplicaSet is still around because Kubernetes keeps revisionHistoryLimit (default 10) ReplicaSets per Deployment.
Bare Pods exist mostly for one-off debugging:
kubectl run debug --image=busybox --rm -it -- sh
That is appropriate for a transient shell. For anything that should survive, use a Deployment, Job, CronJob, or StatefulSet.
Common pitfalls
Missing readiness probes. Without one, Kubernetes considers a Pod ready as soon as the container is running, even if the application is still starting up. The rolling update declares the rollout complete and routes traffic to a Pod that returns 503.
Identical liveness and readiness probes. A failed liveness probe restarts the container; a failed readiness probe just stops routing traffic to it. Conflating the two can cause crash loops during transient slowness.
maxUnavailable: 25% (the default) on a 4-replica Deployment with stateful in-flight requests can drop one replica during deploys. For critical services, set maxUnavailable: 0.
Changing immutable fields. The Deployment’s selector cannot change after creation; if you need to, delete and recreate the Deployment.
Resource requests too low. Kubernetes schedules based on requests, not limits. Pods with no requests get scheduled anywhere and trampled when nodes fill up. Always set both requests and limits.
Production tips
Use kubectl rollout pause and kubectl rollout resume for canary-style validation between scaling steps.
Set progressDeadlineSeconds so the Deployment surfaces a failure if a rollout stalls. Without it, a broken image silently hangs.
spec:
progressDeadlineSeconds: 600
Watch for ImagePullBackOff and CrashLoopBackOff early. kubectl describe pod shows events; kubectl logs --previous shows the prior container’s logs.
For applications that need stable identities or ordered startup (databases, brokers), use a StatefulSet, not a Deployment. For one-pod-per-node agents (log shippers, metric exporters), use a DaemonSet.
Pair Deployments with a HorizontalPodAutoscaler to scale on CPU, memory, or custom metrics. A single Deployment plus an HPA covers most stateless workloads.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata: { name: api }
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource: { name: cpu, target: { type: Utilization, averageUtilization: 60 } }
Wrap-up
A Pod is a runnable unit; a Deployment is the controller that keeps the right number of Pods alive and rolls them over safely. Always run Pods via a higher-level controller, set readiness probes that match reality, configure conservative rolling update parameters, and pair with HPAs for elasticity. Bare Pods are for debug shells; Deployments are for everything else stateless.
Related articles
- DevOps Kubernetes Deployments vs StatefulSets: When to Use Each
Understand the real differences between Deployments and StatefulSets in Kubernetes. Learn which workloads belong in each, with concrete YAML and rollout behavior.
- DevOps Kubernetes Services Explained: ClusterIP, NodePort, LoadBalancer
A clear guide to Kubernetes Services. Learn what ClusterIP, NodePort, LoadBalancer, and headless Services do, and when to use each in real clusters.
- AWS AWS EKS vs ECS vs Fargate: Choosing the Right Container Platform
A practical comparison of EKS, ECS, and Fargate covering control planes, pricing models, and when to choose each option for production container workloads.
- Docker Docker Compose vs Kubernetes: When to Use Which
A pragmatic comparison of Docker Compose and Kubernetes covering scope, operational cost, and the signals that tell you it is time to graduate.