Files

5.6 KiB
Raw Permalink Blame History

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

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

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

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.
  • Deploymenthttpd-deploy, container httpd, image httpd:2.4.27, replicas: 2.
  • strategy.rollingUpdatemaxSurge: 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

# 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.