132 lines
4.6 KiB
Markdown
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`. |