Intermediate · Kubernetes fundamentals · topic 21 of 53 · 35 min
Pods, ReplicaSets and Deployments
Explanation
Pods: the smallest unit
A Pod is a wrapper around one or more containers that always run together on the same node. The containers in a pod share one network identity (one IP address, so they can talk to each other on localhost) and can share storage volumes. Most pods have one main container. Sometimes a helper container runs next to it, called a sidecar, for example to ship logs or act as a network proxy.
Pods are ephemeral, which means temporary. If a node dies, its pods are gone; they are not moved. A new pod is created elsewhere with a new name and a new IP. So you should never depend on a pod's name or IP, and you should almost never create bare pods for an app. Let a controller such as a Deployment create them.
apiVersion: v1
kind: Pod
metadata:
name: hello
labels:
app: hello
spec:
containers:
- name: web
image: nginx:1.27
ports:
- containerPort: 80Labels and selectors
Labels are key-value tags you stick on objects, such as app: payments-api, tier: backend or env: prod. A selector is a query that picks objects by their labels. This is how Kubernetes objects find each other: a Deployment finds its pods by label, and a Service finds the pods to send traffic to by label. You can use them too: kubectl get pods -l app=payments-api.
ReplicaSets and Deployments
A ReplicaSet keeps a set number of identical pods running. A Deployment sits on top: it creates and manages ReplicaSets, and adds rolling updates and a history you can roll back to. In practice you write Deployments and let them handle ReplicaSets for you.
apiVersion: apps/v1
kind: Deployment
metadata:
name: payments-api
namespace: payments
labels:
app: payments-api
spec:
replicas: 4
selector:
matchLabels:
app: payments-api # must match the template labels below
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25% # up to 1 extra pod during an update (25% of 4)
maxUnavailable: 25% # at most 1 pod below 4 during an update
template: # the blueprint for every pod
metadata:
labels:
app: payments-api
spec:
containers:
- name: api
image: registry.example.com/payments-api:1.4.2
ports:
- containerPort: 8080
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
memory: 512Mi
readinessProbe:
httpGet:
path: /ready
port: 8080Rolling updates
When you change the pod template, for example a new image tag, the Deployment creates a new ReplicaSet and moves pods over a few at a time: start some new pods, wait until they are ready, stop some old ones, repeat. Users keep being served throughout. Two settings control the speed and safety:
- maxSurge: how many pods above the desired replicas may exist during the update. A percentage is rounded up.
- maxUnavailable: how many pods below the desired replicas may be unavailable. A percentage is rounded down.
- Both default to 25%. They cannot both be 0, or the update could never make progress.
Worked example: replicas is 10 with the defaults. Surge is 25% of 10 = 2.5, rounded up to 3, so at most 13 pods exist. Unavailable is 2.5 rounded down to 2, so at least 8 pods stay available. With replicas 4 you get at most 5 pods and at least 3 available.
The other strategy is Recreate: stop all old pods first, then start the new ones. It causes downtime, but it is needed when two versions must never run at the same time, for example when the app takes an exclusive lock on a file or database.
kubectl apply -f deployment.yaml # after changing the image tag in the file
kubectl rollout status deployment/payments-api -n payments # wait and watch
kubectl rollout history deployment/payments-api -n payments # list revisions
kubectl rollout undo deployment/payments-api -n payments # back to the previous revision
kubectl rollout undo deployment/payments-api -n payments --to-revision=3
kubectl scale deployment/payments-api -n payments --replicas=8Scaling automatically
kubectl scale changes replicas by hand. A HorizontalPodAutoscaler (HPA) changes them for you, for example to keep average CPU use near 70% of the requested CPU, between a minimum and a maximum. The HPA needs a metrics source, usually metrics-server, installed in the cluster.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: payments-api
namespace: payments
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: payments-api
minReplicas: 4
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70Pod statuses and how to debug them
The STATUS column of kubectl get pods shows either the pod phase (Pending, Running, Succeeded, Failed) or, when a container is stuck, the reason it is waiting, such as CrashLoopBackOff.
| Status | What it means | First thing to check |
|---|---|---|
| Pending | Accepted but not running yet: no node has enough free CPU or memory, or a volume is not ready | kubectl describe pod: read the Events |
| Running | Bound to a node and at least one container is running | Is it Ready? Check the READY column |
| Succeeded | All containers finished with exit code 0 (typical for Jobs) | Nothing, it worked |
| Failed | Containers ended with an error and will not be restarted | kubectl logs |
| CrashLoopBackOff | The container starts, crashes, and is restarted with longer and longer waits | kubectl logs <pod> --previous |
| ImagePullBackOff / ErrImagePull | The node cannot download the image: wrong name or tag, or a private registry without credentials | kubectl describe pod: the Events show the pull error |
kubectl get pods -n payments
kubectl describe pod payments-api-6c9f-zt4qp -n payments # Events at the bottom
kubectl logs payments-api-6c9f-zt4qp -n payments --previous # output of the crashed run
kubectl get events -n payments --sort-by=.metadata.creationTimestampNeed help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Pods, ReplicaSets and Deployments · 1/8
In this lesson you will learn how Kubernetes runs your app: pods, ReplicaSets and Deployments.
Prefer a video by a teacher? Find free videos on “kubernetes pods deployments rolling update tutorial” on YouTube ↗
In real life: Updating a UPI payments API without downtime
A payments company runs its UPI collect API as a Deployment with 10 replicas and the default 25% rolling update settings. On Tuesday at 11 am, the CI pipeline changes the image tag from 3.8.1 to 3.8.2 and applies the Deployment. Kubernetes starts 3 new pods (surge) while at most 2 old ones are taken away, so at least 8 pods serve traffic at all times. A new pod receives traffic only when its readiness probe passes. Ten minutes later the error rate rises, so the on-call engineer runs kubectl rollout undo, and the old ReplicaSet scales back up in under a minute.
kubectl rollout status deployment/upi-collect -n payments
# Waiting for deployment "upi-collect" rollout to finish: 6 of 10 updated replicas are available...
# deployment "upi-collect" successfully rolled out
kubectl rollout undo deployment/upi-collect -n paymentsPractice (0/3 done)
A pod shows CrashLoopBackOff and kubectl logs prints nothing useful. What should you run next?
Write rolling_bounds(replicas, max_surge, max_unavailable). Each setting is either a whole number (like 1) or a percentage string (like "25%"). Turn percentages into pod counts the way Kubernetes does: surge rounds UP, unavailable rounds DOWN. Return a tuple (min_available, max_total): the fewest pods that must stay available and the most pods that may exist during the update.
Write a Deployment YAML for a college results website: image registry.example.com/results-web:2.1.0, 3 replicas, container port 3000, label app: results-web, a rolling update that never drops below 3 available pods, and a CPU request of 100m with a memory request and limit of 128Mi and 256Mi.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Services, Ingress and the Gateway APIKubernetes fundamentals · same module
- Namespaces, ConfigMaps, Secrets, resources and probesKubernetes fundamentals · same module
- Kubernetes securityDevSecOps
- Managed Kubernetes: EKS, AKS and GKECloud Computing (AWS, Azure, Google Cloud) · Containers in the cloud
- Deployment strategies, feature flags and GitOpsCI/CD pipelines
- Amazon ECS and AWS FargateCloud Computing (AWS, Azure, Google Cloud) · Containers in the cloud
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
What do containers in the same pod share?
Answer: A network identity (one IP) and optionally volumes
Containers in a pod share the network namespace, so they reach each other on localhost, and can mount the same volumes.
What are the default maxSurge and maxUnavailable of a Deployment?
Answer: 25% and 25%
Both default to 25%. Surge is rounded up, unavailable is rounded down.
Which strategy stops all old pods before starting new ones?
Answer: Recreate
Recreate causes a short outage but guarantees that two versions never run together.
A pod stays Pending and its events say "0/3 nodes are available: insufficient memory". What is the cause?
Answer: No node has enough free memory for the pod's memory request
The scheduler cannot find a node with room for the request. Lower the request, free capacity, or add nodes.
How does a Deployment know which pods belong to it?
Answer: By its label selector
spec.selector.matchLabels picks the pods; the template must carry the same labels.
A Deployment wants 3 replicas. You delete one of its pods by hand. What happens?Related
Answer: A new pod is created to get back to 3
The ReplicaSet controller sees 2 of 3 and creates a replacement. That is self-healing.
You changed a ConfigMap that a Deployment reads with envFrom. Why do the pods still see the old values?Related
Answer: Environment variables are read when the container starts, so the pods must be restarted
Run kubectl rollout restart deployment/<name> to start fresh pods with the new values.
Which object replaced PodSecurityPolicy (removed in Kubernetes 1.25) for enforcing Pod Security Standards?Related
Answer: Pod Security Admission, configured with namespace labels
The built-in Pod Security Admission controller enforces privileged, baseline or restricted per namespace.
From Kubernetes security
In Kubernetes, which part picks a node for each new pod?Related
Answer: The scheduler in the control plane
The scheduler is a control plane component that assigns pods to nodes.
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 3 more topics in “Kubernetes fundamentals” before its exam: Services, Ingress and the Gateway API, Namespaces, ConfigMaps, Secrets, resources and probes, Helm and Kustomize.
- Module 5 exam: Kubernetes fundamentals · 13 questions · 20 min, without help. 5 topics of this module still to finish first.
- Then the next module, CI/CD pipelines. 53 topics left in the course before the final exam.