Files
kodekloud-engineer/kubernetes/level 1/task-13.md

106 lines
3.8 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
The Nautilus DevOps team has already deployed a ReplicaSet to host an application that requires a highly available infrastructure. Your task is to expose the application running in the existing ReplicaSet by creating a Kubernetes NodePort Service.
Follow the specifications below to create the Service and ensure the application pods are accessible:
A ReplicaSet named httpd-replicaset is already running in the cluster.
The pods managed by the ReplicaSet use the following labels:
Assign labels app as httpd_app, and type as front-end.
Create a NodePort Service named httpd-service to expose the application.
Set the NodePort to 30080.
Expose port 80 of the application.
Note: Do not delete or modify the configuration of the deployed ReplicaSet application.
# Solution
# Kubernetes NodePort Service — `httpd-service`
A NodePort Service that exposes the pods already managed by the `httpd-replicaset`, matched
by their labels. Applied inline via a heredoc — no manifest file on disk, and the ReplicaSet
is left untouched.
## Apply (heredoc → kubectl)
```bash
kubectl apply -f - <<'EOF'
apiVersion: v1
kind: Service
metadata:
name: httpd-service
spec:
type: NodePort
selector:
app: httpd_app
type: front-end
ports:
- port: 80
targetPort: 80
nodePort: 30080
EOF
```
## How it works
### The heredoc apply pattern
- **`kubectl apply -f -`** reads from **stdin**; nothing written to disk.
- **`<<'EOF'` (delimiter quoted)** disables shell expansion — the right default for k8s YAML.
### A Service finds pods by label selector
A Service has no direct link to the ReplicaSet — it targets **pods** whose labels match its
`selector`. This is the crux of the task:
- **`selector: {app: httpd_app, type: front-end}`** — must exactly match the labels on the
pods the ReplicaSet manages. Any pod carrying **both** labels becomes an endpoint of this
Service, regardless of what created it. Since the ReplicaSet stamps its pods with these
labels, the Service automatically picks them up. A mismatched selector would yield a Service
with **zero endpoints** — it'd exist but route nowhere.
This is also why we don't touch the ReplicaSet: the Service attaches by label, so exposing the
app needs no change to the existing workload at all.
### NodePort and the port fields
`type: NodePort` opens a port on **every node** that forwards to the Service, which in turn
load-balances across the matching pods. The three port fields each mean something distinct:
| Field | Meaning |
|-------|---------|
| `port: 80` | The port the **Service** itself listens on (its ClusterIP:80). |
| `targetPort: 80` | The port on the **pod/container** traffic is forwarded to — Apache's port 80. |
| `nodePort: 30080` | The port opened on **each node's** IP for external access. |
So the path is: `<node-ip>:30080` → Service `:80` → pod `:80`. `30080` is inside the valid
NodePort range (`3000032767`), so the API accepts it.
### Why all three ports are set explicitly
`targetPort` defaults to `port` if omitted (both 80 here, so it'd work either way), and
`nodePort` would be auto-assigned from the range if omitted — but the task pins it to `30080`,
so it's set explicitly. Being explicit also makes the manifest self-documenting.
## Verify
```bash
# Service created as NodePort with the right ports
kubectl get service httpd-service
# Endpoints populated = selector matched the ReplicaSet's pods (this is the key check)
kubectl get endpoints httpd-service
# Confirm it reaches the app (from a node or the jump-host)
curl -s http://<node-ip>:30080 | head -n 5
```
Expected — `httpd-service` of type `NodePort` showing `80:30080/TCP`, and
`kubectl get endpoints httpd-service` listing one IP per matching pod. If endpoints is empty,
the selector doesn't match the pods' labels — recheck them with
`kubectl get pods --show-labels`.