Modifying Container Images in Kubernetes
Why Modify Images?
In production, you frequently need to update the container image for a workload — to deploy a new version, patch a vulnerability, or roll back a broken release. Kubernetes provides multiple approaches depending on the resource type.
Updating Deployment Images
Deployments are the most common workload. You can update their images imperatively or declaratively.
Imperative: kubectl set image
This is the fastest method for the CKAD exam:
# Update the image of the 'app' container in deployment 'web'
kubectl set image deployment/web app=nginx:1.27
# Verify the rollout
kubectl rollout status deployment/web
Syntax:
kubectl set image deployment/<deployment-name> <container-name>=<new-image>
You can update multiple containers at once:
kubectl set image deployment/web \
app=nginx:1.27 \
sidecar=fluentd:v1.16
Imperative: kubectl edit
Open the resource in your editor and change the image directly:
kubectl edit deployment web
Find the image: field, change it, save, and exit. The Deployment controller will trigger a rolling update.
Declarative: Update YAML and Apply
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
spec:
containers:
- name: app
image: nginx:1.27 # ← Updated from nginx:1.26
kubectl apply -f deployment.yaml
Rolling Updates
When you update a Deployment’s image, Kubernetes performs a rolling update by default:
Old Pods: [v1] [v1] [v1]
↓ Rolling update starts
Step 1: [v1] [v1] [v2] ← New Pod created
Step 2: [v1] [v2] [v2] ← Old Pod terminated
Step 3: [v2] [v2] [v2] ← Complete
Monitoring Rollouts
# Watch the rollout status
kubectl rollout status deployment/web
# View rollout history
kubectl rollout history deployment/web
# See details of a specific revision
kubectl rollout history deployment/web --revision=2
Rolling Back
If the new image has issues, roll back instantly:
# Roll back to the previous revision
kubectl rollout undo deployment/web
# Roll back to a specific revision
kubectl rollout undo deployment/web --to-revision=3
Exam tip: kubectl rollout undo is one of the fastest ways to recover from a bad deployment. Know this command well.
Editing Pod Images
Pods are immutable — you cannot change the image of a running Pod directly. To update a Pod’s image, you must delete and recreate it.
Method 1: Export, Edit, Recreate
# Export the current Pod definition
kubectl get pod my-pod -o yaml > pod.yaml
# Edit the image in the YAML file
vi pod.yaml
# Change: image: nginx:1.26
# To: image: nginx:1.27
# Delete the old Pod and create the new one
kubectl delete pod my-pod
kubectl apply -f pod.yaml
Method 2: kubectl replace –force
A quicker approach — deletes and recreates in one step:
# Get the Pod YAML, pipe to replace
kubectl get pod my-pod -o yaml | \
sed 's|nginx:1.26|nginx:1.27|' | \
kubectl replace --force -f -
Warning: --force deletes the Pod before recreating. There will be momentary downtime.
Method 3: kubectl edit (triggers recreate)
kubectl edit pod my-pod
If you change the image field, kubectl edit will attempt to apply the change. For Pods, Kubernetes will reject changes to most container fields (including image) on a running Pod. You’ll need to use the export-delete-recreate approach.
Note: Some fields on Pods can be edited in place (like metadata.labels, spec.activeDeadlineSeconds), but spec.containers[*].image is not one of them.
Updating Other Workload Types
StatefulSet
# Same syntax as Deployments
kubectl set image statefulset/db postgres=postgres:16.1
# StatefulSets update Pods in order (ordinal index)
kubectl rollout status statefulset/db
DaemonSet
kubectl set image daemonset/logging fluentd=fluentd:v1.17
kubectl rollout status daemonset/logging
CronJob / Job
Jobs and CronJobs are immutable once created. To update the image:
# For CronJobs: edit the template, new Jobs use the new image
kubectl edit cronjob my-backup
# Change the image in spec.jobTemplate.spec.template.spec.containers
# For existing Jobs: delete and recreate
kubectl delete job my-job
kubectl apply -f job.yaml
kubectl set image — Complete Reference
# Deployment
kubectl set image deployment/NAME CONTAINER=IMAGE
# StatefulSet
kubectl set image statefulset/NAME CONTAINER=IMAGE
# DaemonSet
kubectl set image daemonset/NAME CONTAINER=IMAGE
# ReplicaSet (rare — usually managed by Deployment)
kubectl set image replicaset/NAME CONTAINER=IMAGE
# Dry run — see what would change without applying
kubectl set image deployment/web app=nginx:1.27 --dry-run=client -o yaml
Practical Exam Scenarios
Scenario 1: Update a Deployment Image
# Task: Update deployment 'frontend' container 'web' to nginx:1.27
kubectl set image deployment/frontend web=nginx:1.27
kubectl rollout status deployment/frontend
Scenario 2: Roll Back a Failed Update
# Check current status
kubectl rollout status deployment/frontend
# → Waiting for deployment "frontend" rollout to finish: 1 old replicas pending
# Roll back
kubectl rollout undo deployment/frontend
# Verify
kubectl rollout status deployment/frontend
Scenario 3: Update a Pod Image
# Get the Pod YAML
kubectl get pod my-pod -o yaml > pod.yaml
# Edit the image
vi pod.yaml
# Recreate
kubectl delete pod my-pod
kubectl apply -f pod.yaml
# Verify
kubectl get pod my-pod -o wide
kubectl describe pod my-pod | grep "Image:"
Quick Reference
| Task | Command |
|---|---|
| Update Deployment image | kubectl set image deployment/NAME CONTAINER=IMAGE |
| Watch rollout | kubectl rollout status deployment/NAME |
| View rollout history | kubectl rollout history deployment/NAME |
| Roll back | kubectl rollout undo deployment/NAME |
| Roll back to revision | kubectl rollout undo deployment/NAME --to-revision=N |
| Edit resource live | kubectl edit deployment/NAME |
| Recreate Pod | Export YAML → Edit → Delete → Apply |