Ravindra BagaleCourses & study guides मराठी

Chapter 75: DevOps Projects Part 5: Kubernetes Cluster Deploy Ingress TLS HPA Probes StatefulSet Blue-Green

75.2 Project 32: Deploy an app with a Deployment and a Service

Friends, a Pod alone is not enough. Today we ship a Deployment with two replicas, expose it with a ClusterIP Service, prove DNS inside the cluster, and reach it with port-forward.

What you will build in this project

  1. Deployment shop-web with 2 replicas.
  2. ClusterIP Service on port 80.
  3. Pods selected by label app=shop-web.
  4. curl via port-forward returns 200.

1. Start from a real company story

At Infosys in Pune, a demo app ran as a lone Pod. When the node rebooted, the Pod vanished and the client demo failed.

The account team lost face. Rough cost: about ₹8 lakh in a delayed deal.

Rohit replaced the Pod with a Deployment and a Service so the name stayed stable even when Pods restarted.

Today we build that Deployment plus Service pair.

Deploymentreplicas 2labelsapp=shop-webServiceClusterIP:80DNSshop-web.default
Picture 1: Deployment replicas behind a Service

Ravindra Bagale's Tip

Many students expose a Pod by its IP. Pod IPs change. Always put a Service in front. Keep that habit.

2. Start and prepare

Step 1: Write Deployment YAML

Why: YAML is desired state. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: printf. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 1: yaml

Type this:

mkdir -p /tmp/k8s32 && printf '%s\n' 'apiVersion: apps/v1' 'kind: Deployment' 'metadata: {name: shop-web}' 'spec:' '  replicas: 2' '  selector: {matchLabels: {app: shop-web}}' '  template:' '    metadata: {labels: {app: shop-web}}' '    spec:' '      containers:' '      - name: web' '        image: nginx:1.27-alpine' '        ports: [{containerPort: 80}]' > /tmp/k8s32/deploy.yaml && wc -l /tmp/k8s32/deploy.yaml

You will see:

12 /tmp/k8s32/deploy.yaml

What it means: Deployment YAML with two replicas and app label.

Example 2: grep rep

Type this:

grep replicas /tmp/k8s32/deploy.yaml

You will see:

replicas: 2

What it means: Replica count pinned at two.

Example 3: grep img

Type this:

grep image: /tmp/k8s32/deploy.yaml

You will see:

image: nginx:1.27-alpine

What it means: Pinned nginx Alpine image.

Step 2: Apply Deployment

Why: apply creates the controller. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: kubectl apply. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 4: apply

Type this:

kubectl apply -f /tmp/k8s32/deploy.yaml

You will see:

deployment.apps/shop-web created

What it means: Deployment created in the current namespace.

Example 5: get

Type this:

kubectl get deploy shop-web

You will see:

NAME READY UP-TO-DATE AVAILABLE
shop-web 0/2 2 0

What it means: Controller is reconciling two Pods.

Example 6: rs

Type this:

kubectl get rs -l app=shop-web --no-headers | awk '{print $2,$3,$4}'

You will see:

2 2 2

What it means: ReplicaSet desired and current match eventually.

Step 3: Wait Available

Why: Available means ready replicas. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: kubectl wait. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 7: wait

Type this:

kubectl wait --for=condition=available deploy/shop-web --timeout=90s

You will see:

deployment.apps/shop-web condition met

What it means: Both replicas Available.

Example 8: pods

Type this:

kubectl get pods -l app=shop-web --no-headers | wc -l

You will see:

2

What it means: Two Pods exist.

Example 9: ready

Type this:

kubectl get pods -l app=shop-web --no-headers | awk '{print $2}' | sort | uniq

You will see:

1/1

What it means: Every Pod reports 1/1 Ready.

3. Build the main pieces

Step 4: List Pods

Why: Pods must match labels. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: kubectl get pods. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 10: labels

Type this:

kubectl get pods -l app=shop-web --show-labels | head -3

You will see:

NAME READY STATUS LABELS
shop-web-... 1/1 Running app=shop-web,...

What it means: Label app=shop-web is on each Pod.

Example 11: jsonpath

Type this:

kubectl get pods -l app=shop-web -o jsonpath='{.items[*].metadata.labels.app}'; echo

You will see:

shop-web shop-web

What it means: Both Pods carry the selector label.

Example 12: why

Type this:

echo 'Service selector must match these Pod labels exactly'

You will see:

Service selector must match these Pod labels exactly

What it means: Label contract tip.

Step 5: Write Service YAML

Why: Service selects those labels. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: printf Service. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 13: svc yaml

Type this:

printf '%s\n' 'apiVersion: v1' 'kind: Service' 'metadata: {name: shop-web}' 'spec:' '  selector: {app: shop-web}' '  ports: [{port: 80, targetPort: 80}]' > /tmp/k8s32/svc.yaml && cat /tmp/k8s32/svc.yaml

You will see:

apiVersion: v1
kind: Service
...

What it means: ClusterIP Service YAML selecting app=shop-web.

Example 14: type default

Type this:

grep -c type /tmp/k8s32/svc.yaml || echo 0

You will see:

0

What it means: No type field means ClusterIP by default.

Example 15: port

Type this:

grep port: /tmp/k8s32/svc.yaml

You will see:

port: 80, targetPort: 80

What it means: Service port 80 to container 80.

Step 6: Apply Service

Why: ClusterIP is virtual. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: kubectl apply. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 16: apply svc

Type this:

kubectl apply -f /tmp/k8s32/svc.yaml

You will see:

service/shop-web created

What it means: Service object created.

Example 17: get svc

Type this:

kubectl get svc shop-web

You will see:

NAME TYPE CLUSTER-IP PORT(S)
shop-web ClusterIP 10.96.x.x 80/TCP

What it means: ClusterIP allocated.

Example 18: clusterip

Type this:

kubectl get svc shop-web -o jsonpath='{.spec.clusterIP}'; echo

You will see:

10.96.183.44

What it means: Stable virtual IP inside the cluster.

4. Automate and verify

Step 7: Check Endpoints

Why: Endpoints prove selection. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: kubectl get ep. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 19: ep

Type this:

kubectl get endpoints shop-web

You will see:

NAME ENDPOINTS
shop-web 10.244.0.5:80,10.244.0.6:80

What it means: Two Pod IPs behind the Service.

Example 20: ep count

Type this:

kubectl get endpoints shop-web -o jsonpath='{.subsets[0].addresses[*].ip}' | wc -w

You will see:

2

What it means: Endpoint address count matches replicas.

Example 21: not ready tip

Type this:

echo 'If Endpoints empty, check labels and readiness'

You will see:

If Endpoints empty, check labels and readiness

What it means: Debug tip when Service seems dead.

Step 8: DNS from a debug pod

Why: CoreDNS resolves the name. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: kubectl run debug. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 22: debug

Type this:

kubectl delete pod dnscheck --ignore-not-found >/dev/null 2>&1; kubectl run dnscheck --image=busybox:1.36 --restart=Never -- sleep 300 && kubectl wait --for=condition=Ready pod/dnscheck --timeout=60s

You will see:

pod/dnscheck condition met

What it means: Debug pod Ready for DNS tests.

Example 23: nslookup

Type this:

kubectl exec dnscheck -- nslookup shop-web.default.svc.cluster.local

You will see:

Name: shop-web.default.svc.cluster.local
Address: 10.96.x.x

What it means: CoreDNS resolves the Service name.

Example 24: wget

Type this:

kubectl exec dnscheck -- wget -qO- http://shop-web.default.svc.cluster.local/ | head -c 20

You will see:

<!DOCTYPE html>

What it means: HTTP body from nginx via Service DNS.

Step 9: Port-forward curl

Why: port-forward for local curl. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: kubectl port-forward. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 25: pf

Type this:

kubectl port-forward svc/shop-web 8081:80 >/tmp/k8s32/pf.log 2>&1 & echo $! > /tmp/k8s32/pf.pid; sleep 1; curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8081/

You will see:

200

What it means: Laptop curl through Service port-forward.

Example 26: stop

Type this:

kill $(cat /tmp/k8s32/pf.pid); echo stopped

You will see:

stopped

What it means: Forward stopped.

Example 27: why pf

Type this:

echo 'port-forward is for demos; Ingress comes in project 34'

You will see:

port-forward is for demos; Ingress comes in project 34

What it means: When to use port-forward.

5. Harden and accept

Step 10: Scale to 3

Why: scale changes replicas. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: kubectl scale. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 28: scale

Type this:

kubectl scale deploy/shop-web --replicas=3 && kubectl wait --for=condition=available deploy/shop-web --timeout=90s

You will see:

deployment.apps/shop-web condition met

What it means: Scaled to three and still Available.

Example 29: pods3

Type this:

kubectl get pods -l app=shop-web --no-headers | wc -l

You will see:

3

What it means: Three Pods now.

Example 30: ep3

Type this:

kubectl get endpoints shop-web -o jsonpath='{.subsets[0].addresses[*].ip}' | wc -w

You will see:

3

What it means: Endpoints grew with the scale.

Step 11: Describe Service

Why: describe shows events. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: kubectl describe. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 31: describe

Type this:

kubectl describe svc shop-web | head -15

You will see:

Name: shop-web
Type: ClusterIP
...

What it means: Describe confirms type and selector.

Example 32: cleanup debug

Type this:

kubectl delete pod dnscheck --ignore-not-found

You will see:

pod "dnscheck" deleted

What it means: Debug pod removed.

Example 33: leave

Type this:

echo 'Leave shop-web running for later projects or delete when done'

You will see:

Leave shop-web running for later projects or delete when done

What it means: Lab note.

Step 12: Acceptance checklist

Why: Rohit signs off. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: All green. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 34: ready

Type this:

kubectl get deploy shop-web -o jsonpath='{.status.readyReplicas}'; echo

You will see:

3

What it means: Three ready replicas.

Example 35: svc ok

Type this:

kubectl get svc shop-web -o jsonpath='{.spec.type}'; echo

You will see:

ClusterIP

What it means: Type still ClusterIP.

Example 36: Sign-off

Type this:

echo 'Rohit: PASS'

You will see:

Rohit: PASS

What it means: Project 32 accepted.

Check yourself

Q1. Who fixed Infosys demo?

Rohit

Q2. Replicas?

2

Q3. Service type?

ClusterIP

Q4. Label key?

app

Q5. Service name?

shop-web

Q6. Port?

80

Friends, you ran two replicas behind a ClusterIP Service. Did you understand? Let us try it once more. Scale to three and confirm Endpoints grows.

Lab: try at home

  1. Write Deployment YAML.
  2. Apply and wait Available.
  3. Write Service YAML.
  4. Prove Endpoints and DNS.
  5. Port-forward and curl.

Recap

  • Deployment keeps replicas alive.
  • Labels link Pods to Services.
  • ClusterIP is stable inside the cluster.
  • Endpoints list ready Pod IPs.
  • port-forward is for laptop tests.