# Day 23 - Kubernetes Pods

## 🧠 1. Transition from Docker to Kubernetes

We are moving from **Docker (container)** to **Kubernetes (container orchestration)**.  
In Docker, you directly deploy **containers** using commands like:

```plaintext
docker run -d -p 8080:80 nginx
```

But in **Kubernetes**, you **cannot directly deploy a container**.  
Instead, you deploy your application as a **Pod** — which is the **smallest deployable unit in Kubernetes**.

---

## 📦 2. What is a Pod?

A **Pod** is the **basic unit of deployment in Kubernetes**.

> 📘 Definition:  
> A Pod is a **wrapper around one or more containers** that defines **how a container should run** in Kubernetes.

---

### 🧩 Why not deploy containers directly?

Because Kubernetes is a **declarative system** — it doesn’t want you to manually type commands for every run like Docker.  
Instead, Kubernetes expects you to **declare the desired state** in a file (usually YAML).

Example:

* In Docker → you write:  
    `docker run -d -p 80:80 nginx`
    
* In Kubernetes → you define a `pod.yaml` with all specifications.
    

This allows:

* Standardization across environments
    
* Easier automation
    
* Consistency in deployment
    

---

## 🧾 3. Pod YAML File (Specification)

A Pod is defined using a YAML file.

Example:

```plaintext
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
    - name: nginx
      image: nginx:1.14.2
      ports:
        - containerPort: 80
```

🟢 This YAML replaces all the Docker CLI flags like:  
`-p`, `-v`, `--network`, etc.

---

### 🔄 Equivalent Docker Command

The above YAML is equivalent to:

```plaintext
docker run -d --name nginx -p 80:80 nginx:1.14.2
```

So, a **Pod** = Docker container + YAML configuration wrapper.

---

## 👥 4. Single vs Multiple Containers in a Pod

A Pod can have:

* **One container** (most common)
    
* **Multiple containers** (special use-cases)
    

### Why multiple containers?

Some applications need **helper containers** (sidecars) for:

* Logging
    
* Config loading
    
* Proxying traffic
    

If you place containers inside one Pod:

* They share the **same network** (`localhost`)
    
* They share the **same storage volume**
    

Example:

* `containerA` can talk to `containerB` using `localhost:port`
    
* Both can read/write shared files
    

---

## 🌐 5. Networking & IPs in Pods

* Each Pod gets a **unique Cluster IP** (assigned by `kube-proxy`)
    
* Containers inside the same Pod share the **same IP address**
    
* Other Pods in the cluster can communicate using this **Pod IP**
    

---

## ⚙️ 6. Understanding kubectl (Kubernetes CLI)

Like Docker uses `docker` commands, Kubernetes uses `kubectl` (pronounced *cube control*).

### Common Commands

| Task | Command |
| --- | --- |
| List all nodes | `kubectl get nodes` |
| List pods | `kubectl get pods` |
| Create a resource | `kubectl create -f <filename>.yaml` |
| Delete a resource | `kubectl delete pod <name>` |
| View logs | `kubectl logs <pod-name>` |
| Describe a pod (troubleshoot) | `kubectl describe pod <pod-name>` |

👉 All Kubernetes interaction happens through `kubectl`.

---

## 💻 7. Setting up Kubernetes Locally

For local practice, we use **Minikube** (lightweight Kubernetes cluster).  
Other options include **kind**, **k3s**, **microk8s**.

### Steps:

#### 🧩 Step 1: Install kubectl

Search → “install kubectl”  
Follow instructions for your OS (Linux/Mac/Windows).

Example for macOS:

```plaintext
brew install kubectl
kubectl version
```

#### 🧩 Step 2: Install Minikube

Search → “install Minikube”  
Then follow commands based on your OS and CPU architecture (Intel/ARM).

Example:

```plaintext
brew install minikube
minikube version
```

#### 🧩 Step 3: Start the Cluster

```plaintext
minikube start
```

🖥️ This creates a **single-node Kubernetes cluster** (1 virtual machine).

> In production, you’d have multiple master and worker nodes.  
> But for learning, 1 node (control plane + worker) is enough.

---

## 🚀 8. Deploying Your First Pod

### Create a pod YAML file:

```plaintext
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80
```

### Deploy it:

```plaintext
kubectl create -f pod.yaml
```

### Verify it:

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

### Access it inside cluster:

```plaintext
minikube ssh
curl <pod-cluster-ip>
```

It should return → “Thank you for using nginx”.

---

## 🔍 9. Debugging Pods

If your pod has issues, use:

```plaintext
kubectl describe pod <pod-name>
```

→ Shows Pod events, errors, status, etc.

To view logs of the application:

```plaintext
kubectl logs <pod-name>
```

---

## 💡 10. Cleanup

To delete your Pod:

```plaintext
kubectl delete pod <pod-name>
```

---

## 📘 11. Reference – kubectl Cheat Sheet

For all kubectl commands:  
🔗 Kubernetes Official kubectl Cheat Sheet

Keep this handy — even experienced DevOps engineers refer to it.

---

## ⚙️ 12. From Pod → Deployment

You learned:

* Pod = single or multi-container unit
    
* Defined using YAML
    

Next step:

* To enable **Auto-healing** & **Auto-scaling**,  
    you use **Deployments** — which are wrappers around Pods.
    

---

## ✅ Summary

| Concept | Description |
| --- | --- |
| **Pod** | Smallest deployable unit in Kubernetes |
| **Purpose** | Runs one or more containers |
| **Definition** | Written in a YAML file |
| **Command-line Tool** | kubectl |
| **Local Cluster** | Minikube |
| **Debug Commands** | `kubectl describe pod`, `kubectl logs` |
| **Next Topic** | Deployment (adds auto-scaling, self-healing) |
