Docker and Kubernetes course menu
Kubernetes Pods and Deployments Tutorial
Write Kubernetes YAML for pods and deployments, apply it with kubectl, scale replicas, do rolling updates and rollbacks, and debug pods with logs and describe.
On this page
In Kubernetes, you usually write the desired state in YAML files, and keep them in Git.
A pod#
A pod is one or more containers that share a network address. You rarely create pods by hand, but this shows the format that every Kubernetes object uses:
cat > pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: hello
labels:
app: hello
spec:
containers:
- name: web
image: nginx:1.30-alpine
ports:
- containerPort: 80
EOF
kubectl apply -f pod.yaml
kubectl wait --for=condition=Ready pod/hello --timeout=90s
kubectl get pod hello --no-headers | awk '{print $1, $2, $3}'pod/hello created
pod/hello condition met
hello 1/1 RunningLabels are key-value tags, and they matter later. See inside the pod with commands that look like Docker's:
kubectl exec hello -- nginx -v
kubectl delete pod hello --wait=false > /dev/null
sleep 3
kubectl get pods --no-headers 2> /dev/null | grep -c Runningnginx version: nginx/1.30.6
0Once deleted, this pod does not come back. Nothing is managing it. For that, you need a Deployment.
A deployment#
A Deployment says "keep this many copies of this pod running":
cat > deployment.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.29-alpine
ports:
- containerPort: 80
resources:
requests:
cpu: 50m
memory: 32Mi
limits:
memory: 64Mi
EOF
kubectl apply -f deployment.yaml
kubectl rollout status deployment/web --timeout=120s | tail -n 1
kubectl get deployment web --no-headers | awk '{print $1, $2}'
kubectl get pods -l app=web --no-headers | awk '{print $2, $3}'deployment.apps/web created
deployment "web" successfully rolled out
web 3/3
1/1 Running
1/1 Running
1/1 Runningreplicasis the number of pods.templateis the pod to create.selectortells the Deployment which pods belong to it, by label.requestsis what the scheduler reserves, andlimitsis the maximum.
A Deployment manages a ReplicaSet, which in turn manages the pods.
Scaling#
kubectl scale deployment web --replicas=5
kubectl rollout status deployment/web --timeout=90s | tail -n 1
kubectl get pods -l app=web --no-headers | wc -ldeployment.apps/web scaled
deployment "web" successfully rolled out
5Changing replicas in the file and applying it again is the better way, because the file stays correct. A HorizontalPodAutoscaler can scale automatically, based on CPU.
Rolling updates#
Change the image, and Kubernetes replaces pods gradually, so that the app stays up:
sed -i 's/replicas: 3/replicas: 4/; s/nginx:1.29-alpine/nginx:1.30-alpine/' deployment.yaml
kubectl apply -f deployment.yaml
kubectl rollout status deployment/web --timeout=120s | tail -n 1
kubectl rollout history deployment/web | tail -n +3 | awk '{print $1}' | grep -c .
kubectl get deployment web -o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'deployment.apps/web configured
deployment "web" successfully rolled out
2
nginx:1.30-alpineRolling back#
Suppose a bad version is deployed. This image tag does not exist:
kubectl set image deployment/web nginx=nginx:0.0.0-missing
sleep 12
kubectl get pods -l app=web --no-headers | awk '{print $3}' | sort | uniq -cdeployment.apps/web image updated
2 ErrImagePull
3 RunningThe old pods stay up while the new ones fail, so users are not affected. Roll back:
kubectl rollout undo deployment/web 2> /dev/null
kubectl rollout status deployment/web --timeout=120s | tail -n 1
kubectl get deployment web -o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'deployment.apps/web rolled back
deployment "web" successfully rolled out
nginx:1.30-alpineDebugging pods#
kubectl describe deployment web | grep -E '^Replicas:|Image:' | sed 's/ */ /g'
kubectl delete -f deployment.yamlReplicas: 4 desired | 4 updated | 4 total | 4 available | 0 unavailable
Image: nginx:1.30-alpine
deployment.apps "web" deleted from default namespaceCommon mistakes#
Key takeaway#
Next: Services and Networking.
Finished this lesson?
Related lessons
Recommended Docker and Kubernetes resources
- Docker Deep Dive by Nigel Poulton
A practical guide to how Docker works, for readers who have finished the basics.
Some links are affiliate links. If you buy through them, Laviyx Learn may earn a commission at no extra cost to you. As an Amazon Associate, we earn from qualifying purchases.