Files

163 lines
5.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Assignment
There is a production deployment planned for next week. The Nautilus DevOps team wants to test the deployment update and rollback on Dev environment first so that they can identify the risks in advance. Below you can find more details about the plan they want to execute.
Create a namespace xfusion. Create a deployment called httpd-deploy under this new namespace, It should have one container called httpd, use httpd:2.4.27 image and 3 replicas. The deployment should use RollingUpdate strategy with maxSurge=1, and maxUnavailable=2. Also create a NodePort type service named httpd-service and expose the deployment on nodePort: 30008.
Now upgrade the deployment to version httpd:2.4.43 using a rolling update.
Finally, once all pods are updated undo the recent update and roll back to the previous/original version.
Note:
a. The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.
b. Please make sure you only use the specified image(s) for this deployment and as per the sequence mentioned in the task description. If you mistakenly use a wrong image and fix it later, that will also distort the revision history which can eventually fail this task.
# Solution
# Deployment Update + Rollback — `httpd-deploy` in `devops`
Create the deployment at `httpd:2.4.27`, roll it forward to `httpd:2.4.43`, then roll it back —
keeping revision history clean throughout.
> **Sequencing matters:** apply each image one at a time and let each rollout finish before the
> next. Do **not** put `2.4.43` in the initial manifest, and don't "fix" a wrong image mid-stream
> — either distorts the revision history.
## Step 1 — Namespace + deployment (`2.4.27`) + service
```bash
kubectl apply -f - <<'EOF'
apiVersion: v1
kind: Namespace
metadata:
name: devops
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd-deploy
namespace: devops
labels:
app: httpd
spec:
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 2
selector:
matchLabels:
app: httpd
template:
metadata:
labels:
app: httpd
spec:
containers:
- name: httpd
image: httpd:2.4.27
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: httpd-service
namespace: devops
spec:
type: NodePort
selector:
app: httpd
ports:
- port: 80
targetPort: 80
nodePort: 30008
EOF
# Let revision 1 fully settle BEFORE any update
kubectl rollout status deployment/httpd-deploy -n devops
```
## Step 2 — Rolling update to `httpd:2.4.43`
```bash
kubectl set image deployment/httpd-deploy httpd=httpd:2.4.43 -n devops
# Wait for the update to fully complete (revision 2)
kubectl rollout status deployment/httpd-deploy -n devops
```
## Step 3 — Roll back to the original version
```bash
kubectl rollout undo deployment/httpd-deploy -n devops
# Wait for the rollback to complete (revision 3, template of revision 1)
kubectl rollout status deployment/httpd-deploy -n devops
```
## How it works
### Sequencing keeps revision history clean
Each `kubectl` action that changes the pod template creates a new **revision**, each backed by a
ReplicaSet:
- **Revision 1** — the initial `2.4.27` deployment.
- **Revision 2** — the `set image` update to `2.4.43`.
- **Revision 3** — the `rollout undo`, which reuses revision 1's template (`2.4.27`).
`kubectl rollout status` between each step forces each rollout to **finish** before the next
begins, so the revisions are distinct and ordered. Firing the update before the create settles —
or applying a wrong image and correcting it — would inject extra revisions.
### The initial manifest
- **Namespace `devops`** created first so the deployment and service land in it.
- **Deployment** — `httpd-deploy`, container **`httpd`**, image **`httpd:2.4.27`**, `replicas: 2`.
- **`strategy.rollingUpdate`** — `maxSurge: 1` (at most 1 pod above the desired 2 during a
rollout) and `maxUnavailable: 2` (up to 2 pods down at once). With only 2 replicas and
`maxUnavailable: 2`, both pods can be replaced at once, so the rollout is fast.
- **`selector.matchLabels: app: httpd`** equals the template labels, and the **Service**'s
`selector: app: httpd` targets those same pods. `nodePort: 30008` is in the valid range
(`3000032767`).
### `set image` for the update, `rollout undo` for the rollback
- **`set image`** patches just the container image on the live deployment — the idiomatic way to
trigger a rolling update. Container name `httpd` is the left side of `httpd=httpd:2.4.43`.
- **`rollout undo`** with no `--to-revision` reverts to the **immediately previous** revision
(revision 1's `2.4.27` template) — exactly "the previous/original version" — and records it as a
new forward revision (3), preserving the audit trail.
## Verify
```bash
# Current image after rollback should be the ORIGINAL 2.4.27
kubectl get deployment httpd-deploy -n devops \
-o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'
# Revision history: expect revisions 1, 2, 3 in order
kubectl rollout history deployment/httpd-deploy -n devops
# All pods ready, service exposed on 30008
kubectl get deployment httpd-deploy -n devops
kubectl get service httpd-service -n devops
kubectl get endpoints httpd-service -n devops
```
Expected — after Step 3 the image is back to `httpd:2.4.27`, rollout history shows three
revisions, deployment `READY 2/2`, and `httpd-service` NodePort `80:30008/TCP` with two
endpoints.
> Everything is in `devops` — keep `-n devops` on every command. If endpoints is empty, the
> service selector doesn't match the pod labels.