# Day 26 - Kubernetes Services Deep Dive

### **1\. What this session is about**

You gave a long demo where you:

* Create a Kubernetes **deployment**
    
* Create different types of **services**
    
* Test **traffic flow**
    
* Use **Kubeshark** to see how traffic flows inside the cluster
    

The goal:  
**Understand Service Discovery, Load Balancing & Exposing Apps inside/outside Kubernetes.**

---

# ✅ **2\. Kubernetes Cluster Setup (Minikube)**

You use:

```plaintext
minikube status
```

to confirm the cluster is running.

Then you clean the namespace:

```plaintext
kubectl get all
kubectl delete deploy <name>
kubectl delete svc <name>
```

Only the default Kubernetes service remains.

---

# ✅ **3\. Build the Application Image**

You go to a GitHub repo (`docker-zero-to-hero`), use a Django app and build your image:

```plaintext
docker build -t python-sample-app-demo:v1 .
```

---

# ✅ **4\. Create Deployment (deployment.yaml)**

You take a template from Kubernetes docs and modify:

* `replicas: 2`
    
* Add labels:
    
    ```plaintext
    app: sample-python-app
    ```
    
* Add container image:
    
    ```plaintext
    image: python-sample-app-demo:v1
    ```
    
* Add containerPort:
    
    ```plaintext
    containerPort: 8000
    ```
    

Apply it:

```plaintext
kubectl apply -f deployment.yaml
```

Check:

```plaintext
kubectl get deploy
kubectl get pods -o wide
```

⚠️ You highlight that **Pod IPs keep changing**, so you **cannot** rely on Pod IPs directly.

---

# ✅ **5\. Why Services Are Needed**

Because:

* Pod IPs change
    
* Pods scale up/down
    
* Pods restart
    

So you need **stable networking** via:

1. **Labels**
    
2. **Selectors**
    
3. **Services**
    

Services always look for pods **by label**, not by IP.

---

# ✅ **6\. Create the Service (service.yaml)**

You create a **NodePort** service:

```plaintext
type: NodePort
selector:
  app: sample-python-app
ports:
  - port: 80
    targetPort: 8000
    nodePort: 30007
```

Apply:

```plaintext
kubectl apply -f service.yaml
```

Check:

```plaintext
kubectl get svc
```

---

# ✅ **7\. How NodePort Works**

NodePort exposes the app on:

```plaintext
<NodeIP>:<NodePort>
```

You get Minikube IP:

```plaintext
minikube ip
```

Then access:

```plaintext
curl http://<minikube-ip>:30007/demo
```

Or via browser:

```plaintext
http://<minikube-ip>:30007/demo
```

This works only **inside the same network** (internal users).

---

# ✅ **8\. LoadBalancer Mode**

You edit the service:

```plaintext
kubectl edit svc <name>
```

Change:

```plaintext
type: LoadBalancer
```

In cloud providers (AWS/GCP/Azure) you get:

```plaintext
EXTERNAL-IP = Public IP
```

But in Minikube this stays:

```plaintext
pending
```

(You mention **MetalLB** as an alternative.)

---

# ✅ **9\. Service Discovery Test**

You break the selector on purpose:

```plaintext
selector:
  app: sample-python
```

This no longer matches:

```plaintext
app: sample-python-app
```

Result:

* Service can’t find pods
    
* No traffic
    
* Proves **services depend 100% on correct labels/selectors**
    

---

# ✅ **10\. Load Balancing Concept**

Since you created **2 pods**, NodePort or ClusterIP service will:

* Split traffic between pods
    
* Do round-robin
    
* Always discover new pods automatically (because labels match)
    

---

# ✅ **11\. Kubeshark**

Used at the end (not included in detail in your text) to:

* Capture real traffic
    
* Show how service selects pods
    
* Show internal communication inside the cluster
    

---

# 🎉 **Summary of Your Entire Content in 10 Sentences**

1. You start a Minikube cluster and clean the namespace.
    
2. You build a Python/Django Docker image.
    
3. You create a Kubernetes deployment with 2 replicas.
    
4. You explain Pod IPs change, so they cannot be used directly.
    
5. You create a NodePort service with proper labels/selectors.
    
6. You show how NodePort exposes the app on `<NodeIP>:<NodePort>`.
    
7. You demonstrate using the app from browser and using curl.
    
8. You convert service type to LoadBalancer for external traffic (cloud only).
    
9. You intentionally break selectors to show service discovery failure.
    
10. You use Kubeshark to visualize pod-to-service traffic inside Kubernetes.
