Files

132 lines
4.6 KiB
Markdown

# Assignment
An application currently running on the Kubernetes cluster employs the nginx web server. The Nautilus application development team has introduced some recent changes that need deployment. They've crafted an image nginx:1.17 with the latest updates.
Execute a rolling update for this application, integrating the nginx:1.17 image. The deployment is named nginx-deployment.
Ensure all pods are operational post-update.
Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.
# Solution
# Rolling Update — `nginx-deployment` → `nginx:1.17`
Update an existing deployment's image to `nginx:1.17` via a rolling update, then confirm
all pods are healthy.
## Primary method — `kubectl set image` (recommended)
Because the deployment already exists and you don't need its full manifest to change one
image, this is the canonical rolling-update command:
```bash
# Trigger the rolling update
kubectl set image deployment/nginx-deployment nginx=nginx:1.17
# Watch it roll out and block until complete
kubectl rollout status deployment/nginx-deployment
```
`nginx=nginx:1.17` means "set the container **named `nginx`** to image `nginx:1.17`."
Confirm the container's actual name first if unsure:
```bash
kubectl get deployment nginx-deployment \
-o jsonpath='{.spec.template.spec.containers[*].name}{"\n"}'
```
Use whatever name that prints on the left side of the `=`.
## Alternative — heredoc `apply`
You can also drive the update declaratively by re-applying the deployment with the new
image. **Caveat:** `apply` reconciles the whole pod template, so the manifest must match
the existing deployment's container name, labels, and selector — otherwise you'll change
more than intended. Grab the current spec first:
```bash
kubectl get deployment nginx-deployment -o yaml # note container name, labels, replicas
```
Then apply with the image bumped to `nginx:1.17` (adjust names/replicas to match what you
saw):
```bash
kubectl apply -f - <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.17
EOF
kubectl rollout status deployment/nginx-deployment
```
## How it works
### What a rolling update does
A Deployment's default strategy is `RollingUpdate`: when the pod template changes (here,
the image), the Deployment creates a **new ReplicaSet** for `nginx:1.17` and shifts pods
over **incrementally** — spinning up new pods and tearing down old ones a few at a time,
governed by `maxSurge` (how many extra pods above desired count are allowed) and
`maxUnavailable` (how many below). This keeps the app serving throughout, with no full
outage. Changing the image is exactly the kind of template change that triggers it.
### `set image` vs. heredoc `apply`
- **`set image`** patches just the container image on the live object. It's surgical,
needs no knowledge of the rest of the spec, and is the idiomatic way to roll a new
image onto an existing deployment. Preferred when you're changing one field.
- **`apply`** reconciles the entire manifest you feed it against the live object. It's the
right tool when you own the manifest as source of truth, but for a one-field image bump
on a deployment you didn't author, it forces you to reproduce the full spec correctly —
more surface area to get wrong. That's why `set image` is primary here.
Both produce the same underlying rolling update; they differ only in how the change is
expressed.
### `rollout status`
`kubectl rollout status` blocks until the new ReplicaSet is fully rolled out and all
updated pods report Ready — the "ensure all pods are operational post-update" requirement.
If the update stalls (e.g. a bad image), it surfaces there rather than silently leaving
old pods running.
## Verify
```bash
# All pods updated and running
kubectl get pods -l app=nginx -o wide
# Every pod now on nginx:1.17
kubectl get deployment nginx-deployment \
-o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'
# Rollout history (shows the new revision)
kubectl rollout history deployment/nginx-deployment
```
Expected — all pods `Running` and `READY`, the image printing `nginx:1.17`, and a new
revision recorded in the rollout history.
> If the rollout hangs with new pods in `ImagePullBackOff`, the `nginx:1.17` pull failed
> (node offline / rate-limited). `kubectl describe pod <name>` shows the cause; you can
> revert with `kubectl rollout undo deployment/nginx-deployment`.