Files
kodekloud-engineer/kubernetes/level 2/task-3.md

121 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Assignment
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
# Kubernetes Deployment + NodePort Service — `nginx-deployment` / `nginx-service`
A 3-replica nginx Deployment exposed by a NodePort Service on port `30011`. Both objects in one
multi-document heredoc — no manifest file on disk.
## Apply (heredoc → kubectl)
```bash
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
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30011
EOF
```
## How it works
### The heredoc apply pattern
- **`kubectl apply -f -`** reads from **stdin**; `---` separates the two documents, applied in
order.
- **`<<'EOF'` (delimiter quoted)** keeps the manifest literal — the right default for k8s YAML.
### The Deployment
- **`apps/v1` / `kind: Deployment`** — manages a ReplicaSet, which keeps the desired number of
pods running and self-heals; the basis for the "highly available and scalable" requirement.
- **`metadata.name: nginx-deployment`** and container **`name: nginx-container`** — exactly as
required.
- **`replicas: 3`** — three identical pods spread across the cluster for availability.
- **`image: nginx:latest`** — tag stated explicitly, as required.
- **`selector.matchLabels: app: nginx`** must equal **`template.metadata.labels: app: nginx`** —
a Deployment finds the pods it owns by this label match; a mismatch makes the API reject the
manifest.
### The Service ties to pods by label, not to the Deployment
- **`type: NodePort`** opens a port on every node that forwards into the cluster.
- **`selector: app: nginx`** — this is what connects the Service to the Deployment's pods. The
Service targets any pod labeled `app: nginx` — which is exactly what the Deployment stamps on
its three pods — and load-balances across them. The Service has no direct reference to the
Deployment; the shared `app: nginx` label is the entire link. A mismatched selector would
leave the Service with **zero endpoints**.
- **Port fields:**
- `port: 80` — the Service's own ClusterIP port.
- `targetPort: 80` — the container port traffic is forwarded to (nginx serves on 80).
- `nodePort: 30011` — the port opened on each node for external access. `30011` is inside the
valid range (`3000032767`), so the API accepts it.
Traffic path: `<node-ip>:30011` → Service `:80` → one of the three pods `:80`.
### Why the label must be consistent in three places
`app: nginx` appears in the Deployment selector, the pod template labels, and the Service
selector. The first two tie the Deployment to its pods; the third ties the Service to those same
pods. Keeping the label identical across all three is what makes the whole chain — Deployment →
pods → Service — connect.
## Verify
```bash
# Deployment with 3 ready replicas
kubectl get deployment nginx-deployment
# Service is NodePort on 30011
kubectl get service nginx-service
# Endpoints populated = selector matched the pods (key check)
kubectl get endpoints nginx-service
# Reachable via the node port
curl -s http://<node-ip>:30011 | head -n 5
```
Expected — deployment `READY 3/3`, `nginx-service` of type `NodePort` showing `80:30011/TCP`,
and `kubectl get endpoints nginx-service` listing three pod IPs. Empty endpoints ⇒ selector/label
mismatch (check `kubectl get pods --show-labels`).