Files
kodekloud-engineer/100 - days of devops/devops-51-60.md

18 KiB

Task 51

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.18 with the latest updates.

Execute a rolling update for this application, integrating the nginx:1.18 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 to nginx:1.18

Check current state first

kubectl get deployment nginx-deployment
kubectl describe deployment nginx-deployment | grep -i image

Note the container name from the describe output (needed for the set image command).

Perform the rolling update

kubectl set image deployment/nginx-deployment nginx-container=nginx:1.18

Replace nginx (left of =) with the actual container name if it differs — check the describe output above.

Watch the rollout

kubectl rollout status deployment/nginx-deployment

Verify

kubectl rollout status deployment/nginx-deployment
kubectl get pods
kubectl describe deployment nginx-deployment | grep -i image

Want: rollout successfully rolled out, all pods Running, image now nginx:1.18.

Task 52

Earlier today, the Nautilus DevOps team deployed a new release for an application. However, a customer has reported a bug related to this recent release. Consequently, the team aims to revert to the previous version.

There exists a deployment named nginx-deployment; initiate a rollback to the previous revision.

Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.

Solution

Rollback nginx-deployment to previous revision

Check history first (optional but good)

kubectl rollout history deployment/nginx-deployment

Shows the revisions — confirms there's a previous one to roll back to.

Perform the rollback

kubectl rollout undo deployment/nginx-deployment

Watch + verify

kubectl rollout status deployment/nginx-deployment
kubectl get pods
kubectl describe deployment nginx-deployment | grep -i image

Want: rollout successfully rolled out, all pods Running, image reverted to the previous version.

Task 53

We encountered an issue with our Nginx and PHP-FPM setup on the Kubernetes cluster this morning, which halted its functionality. Investigate and rectify the issue:

The pod name is nginx-phpfpm and configmap name is nginx-config. Identify and fix the problem.

Once resolved, copy /home/thor/index.php file from the jump host to the nginx-container within the nginx document root. After this, you should be able to access the website using Website button on the top bar.

Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.

Solution

Fix nginx-phpfpm pod

Step 1 — recon: inspect the pod and configmap

# pod state + how it's configured
kubectl describe pod nginx-phpfpm
kubectl get pod nginx-phpfpm -o yaml

# the nginx config
kubectl describe configmap nginx-config
kubectl get configmap nginx-config -o yaml

Step 2 — identify the mismatch

Compare two things:

  • The document root in the nginx config (from the configmap) — look for root /some/path;
  • The shared volume mountPath in the pod spec — where the shared emptyDir volume is mounted in both the nginx and php-fpm containers

The bug: these two paths don't match. nginx serves from one path, but the shared volume (where files land) is mounted at a different path → nginx can't find the files.

Step 3 — fix the mismatch

The fix is to make them consistent. Usually the configmap's root directive is edited to match the volume mountPath (or vice versa). Edit the configmap:

kubectl edit configmap nginx-config

Change the root line so it matches the shared volume's mountPath in the pod spec. Common correct value: /var/www/html.

Step 4 — recreate the pod (configmap changes need a pod restart)

kubectl get pod nginx-phpfpm -o yaml > /tmp/nginx-phpfpm.yaml
kubectl delete pod nginx-phpfpm
kubectl apply -f /tmp/nginx-phpfpm.yaml

Step 5 — copy index.php into the nginx container's docroot

kubectl cp /home/thor/index.php nginx-phpfpm:/var/www/html/index.php -c nginx-container

(Use the actual docroot path confirmed in step 2/3, and -c nginx-container to target the right container.)

Step 6 — verify

kubectl get pod nginx-phpfpm
kubectl exec nginx-phpfpm -c nginx-container -- ls -l /var/www/html/

Then hit the Website button.

Task 54

We are working on an application that will be deployed on multiple containers within a pod on Kubernetes cluster. There is a requirement to share a volume among the containers to save some temporary data. The Nautilus DevOps team is developing a similar template to replicate the scenario. Below you can find more details about it.

Create a pod named volume-share-nautilus.

For the first container, use image debian with latest tag only and remember to mention the tag i.e debian:latest, container should be named as volume-container-nautilus-1, and run a sleep command for it so that it remains in running state. Volume volume-share should be mounted at path /tmp/blog.

For the second container, use image debian with the latest tag only and remember to mention the tag i.e debian:latest, container should be named as volume-container-nautilus-2, and again run a sleep command for it so that it remains in running state. Volume volume-share should be mounted at path /tmp/games.

Volume name should be volume-share of type emptyDir.

After creating the pod, exec into the first container i.e volume-container-nautilus-1, and just for testing create a file blog.txt with the content Welcome to xFusionCorp Industries under the mounted path of first container i.e /tmp/blog.

The file blog.txt should be present under the mounted path /tmp/games on the second container volume-container-nautilus-2 as well, since they are using a shared volume.

Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.

Solution

Create volume-share-nautilus pod

Create the pod

kubectl apply -f - <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: volume-share-nautilus
spec:
  containers:
    - name: volume-container-nautilus-1
      image: debian:latest
      command: ["sleep", "infinity"]
      volumeMounts:
        - name: volume-share
          mountPath: /tmp/blog
    - name: volume-container-nautilus-2
      image: debian:latest
      command: ["sleep", "infinity"]
      volumeMounts:
        - name: volume-share
          mountPath: /tmp/games
  volumes:
    - name: volume-share
      emptyDir: {}
EOF

Wait for it to be Running

kubectl get pod volume-share-nautilus -w

Write the file in container 1

kubectl exec volume-share-nautilus -c volume-container-nautilus-1 -- \
  bash -c 'echo "Welcome to xFusionCorp Industries" > /tmp/blog/blog.txt'

Verify it appears in container 2 (shared volume)

kubectl exec volume-share-nautilus -c volume-container-nautilus-2 -- \
  cat /tmp/games/blog.txt

Want: Welcome to xFusionCorp Industries — proving the emptyDir is shared across both containers at their respective mount paths.

Task 55

We have a web server container running the nginx image. The access and error logs generated by the web server are not critical enough to be placed on a persistent volume. However, Nautilus developers need access to the last 24 hours of logs so that they can trace issues and bugs. Therefore, we need to ship the access and error logs for the web server to a log-aggregation service. Following the separation of concerns principle, we implement the Sidecar pattern by deploying a second container that ships the error and access logs from nginx. Nginx does one thing, and it does it well - serving web pages. The second container also specializes in its task - shipping logs. Since containers are running on the same Pod, we can use a shared emptyDir volume to read and write logs.

Create a pod named webserver.

Create an emptyDir volume named shared-logs.

Create a regular container in the webserver pod from the nginx:latest image named nginx-container, and an init container from the ubuntu:latest image named sidecar-container.

Add the following command to the sidecar-container "sh","-c","while true; do cat /var/log/nginx/access.log /var/log/nginx/error.log; sleep 30; done"

Mount the shared-logs volume in both containers at /var/log/nginx. Ensure all containers are in a running state.

Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.

Solution

Create webserver sidecar pod

kubectl apply -f - <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: webserver
spec:
  volumes:
    - name: shared-logs
      emptyDir: {}
  initContainers:
    - name: sidecar-container
      image: ubuntu:latest
      restartPolicy: Always
      command: ["sh", "-c", "while true; do cat /var/log/nginx/access.log /var/log/nginx/error.log; sleep 30; done"]
      volumeMounts:
        - name: shared-logs
          mountPath: /var/log/nginx
  containers:
    - name: nginx-container
      image: nginx:latest
      volumeMounts:
        - name: shared-logs
          mountPath: /var/log/nginx
EOF

Verify

kubectl get pod webserver
kubectl get pod webserver -o jsonpath='{.status.phase}{"\n"}'
kubectl describe pod webserver | grep -A2 -i "state"

Want: pod Running, both nginx-container and sidecar-container up (Ready/Running).

Task 56

Some of the Nautilus team developers are developing a static website and they want to deploy it on Kubernetes cluster. They want it to be highly available and scalable. Therefore, based on the requirements, the DevOps team has decided to create a deployment for it with multiple replicas. Below you can find more details about it:

Create a deployment using nginx image with latest tag only and remember to mention the tag i.e nginx:latest. Name it as nginx-deployment. The container should be named as nginx-container, also make sure replica counts are 3.

Create a NodePort type service named nginx-service. The nodePort should be 30011.

Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.

Solution

nginx deployment + NodePort service

Deployment

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-container
          image: nginx:latest
          ports:
            - containerPort: 80
EOF

NodePort Service

kubectl apply -f - <<'EOF'
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30011
EOF

Verify

kubectl get deployment nginx-deployment
kubectl get pods -l app=nginx
kubectl get service nginx-service

Want: deployment 3/3 ready, three pods Running, service nginx-service type NodePort exposing 30011.

Task 57

The Nautilus DevOps team is working on to setup some pre-requisites for an application that will send the greetings to different users. There is a sample deployment, that needs to be tested. Below is a scenario which needs to be configured on Kubernetes cluster. Please find below more details about it.

Create a pod named print-envars-greeting.

Configure spec as, the container name should be print-env-container and use bash image.

Create three environment variables: a. GREETING and its value should be Welcome to b. COMPANY and its value should be Stratos c. GROUP and its value should be Industries

Use command ["/bin/sh", "-c", 'echo "$(GREETING) $(COMPANY) $(GROUP)"'] (please use this exact command), also set its restartPolicy policy to Never to avoid crash loop back.

You can check the output using kubectl logs -f print-envars-greeting command.

Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.

Solution

Create print-envars-greeting pod

kubectl apply -f - <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: print-envars-greeting
spec:
  restartPolicy: Never
  containers:
    - name: print-env-container
      image: bash
      command: ["/bin/sh", "-c", 'echo "$(GREETING) $(COMPANY) $(GROUP)"']
      env:
        - name: GREETING
          value: "Welcome to"
        - name: COMPANY
          value: "Stratos"
        - name: GROUP
          value: "Industries"
EOF

Check the output

kubectl logs -f print-envars-greeting

Want: Welcome to Stratos Industries in the logs, pod in Completed state.

Task 58

The Nautilus DevOps teams is planning to set up a Grafana tool to collect and analyze analytics from some applications. They are planning to deploy it on Kubernetes cluster. Below you can find more details.

1.) Create a deployment named grafana-deployment-xfusion using any grafana image for Grafana app. Set other parameters as per your choice. 2.) Create NodePort type service with nodePort 32000 to expose the app.

You do not need to make any configuration changes inside the Grafana app once deployed; just make sure you can access the Grafana login page.

Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.

Solution

Grafana deployment + NodePort service

kubectl apply -f - <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana-deployment-xfusion
  labels:
    app: grafana-deployment-xfusion
spec:
  replicas: 1
  selector:
    matchLabels:
      app: grafana-deployment-xfusion
  template:
    metadata:
      labels:
        app: grafana-deployment-xfusion
    spec:
      containers:
        - name: grafana
          image: grafana/grafana:latest
          ports:
            - containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
  name: grafana-service
spec:
  type: NodePort
  selector:
    app: grafana-deployment-xfusion
  ports:
    - port: 32000
      targetPort: 3000
      nodePort: 32000
EOF

Verify

kubectl get deployment grafana-deployment-xfusion
kubectl get pods -l app=grafana
kubectl get service grafana-service
kubectl rollout status deployment/grafana-deployment-xfusion

Want: deployment 1/1 ready, pod Running, service exposing 32000. Then hit the app — Grafana login page should load.

Task 59

Last week, the Nautilus DevOps team deployed a redis app on Kubernetes cluster, which was working fine so far. This morning one of the team members was making some changes in this existing setup, but he made some mistakes and the app went down. We need to fix this as soon as possible. Please take a look.

The deployment name is redis-deployment. The pods are not in running state right now, so please look into the issue and fix the same.

Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.

Solution

  • incorrect config map name
  • incorrect image on redis

Task 60

The Nautilus DevOps team is working on a Kubernetes template to deploy a web application on the cluster. There are some requirements to create/use persistent volumes to store the application code, and the template needs to be designed accordingly. Please find more details below:

Create a PersistentVolume named as pv-devops. Configure the spec as storage class should be manual, set capacity to 4Gi, set access mode to ReadWriteOnce, volume type should be hostPath and set path to /mnt/devops (this directory is already created, you might not be able to access it directly, so you need not to worry about it).

Create a PersistentVolumeClaim named as pvc-devops. Configure the spec as storage class should be manual, request 1Gi of the storage, set access mode to ReadWriteOnce.

Create a pod named as pod-devops, mount the persistent volume you created with claim name pvc-devops at document root of the web server, the container within the pod should be named as container-devops using image nginx with latest tag only (remember to mention the tag i.e nginx:latest).

Create a node port type service named web-devops using node port 30008 to expose the web server running within the pod.

Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.

Solution

PV + PVC + Pod + Service (devops)

kubectl apply -f - <<'EOF'
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-devops
spec:
  storageClassName: manual
  capacity:
    storage: 4Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /mnt/devops
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-devops
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-devops
  labels:
    app: web-devops
spec:
  containers:
    - name: container-devops
      image: nginx:latest
      ports:
        - containerPort: 80
      volumeMounts:
        - name: web-storage
          mountPath: /usr/share/nginx/html
  volumes:
    - name: web-storage
      persistentVolumeClaim:
        claimName: pvc-devops
---
apiVersion: v1
kind: Service
metadata:
  name: web-devops
spec:
  type: NodePort
  selector:
    app: web-devops
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30008
EOF

Verify

kubectl get pv pv-devops
kubectl get pvc pvc-devops
kubectl get pod pod-devops
kubectl get svc web-devops

Want: PV Bound, PVC Bound, pod Running, service exposing 30008.