docs: add Kubernetes CKS study notes
This commit is contained in:
106
kubernetes/level 1/task-13.md
Normal file
106
kubernetes/level 1/task-13.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# 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 (`30000–32767`), 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`.
|
||||
Reference in New Issue
Block a user