docs: add Kubernetes CKS study notes

This commit is contained in:
2026-08-04 23:18:45 +02:00
parent a6ee7a2b07
commit 91a1849009
57 changed files with 8313 additions and 0 deletions

View File

@@ -0,0 +1,112 @@
# Assignment
The Nautilus DevOps team is gearing up to deploy applications on a Kubernetes cluster for migration purposes. A team member has been tasked with creating a ReplicaSet outlined below:
Create a ReplicaSet using httpd image with latest tag (ensure to specify as httpd:latest) and name it httpd-replicaset.
Apply labels: app as httpd_app, type as front-end.
Name the container httpd-container. Ensure the replica count is 4.
Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.
# Solution
# Kubernetes ReplicaSet — `httpd-replicaset`
A ReplicaSet maintaining 4 `httpd:latest` pods, labeled `app: httpd_app` and
`type: front-end`. Applied inline via a heredoc — no manifest file on disk.
## Apply (heredoc → kubectl)
```bash
kubectl apply -f - <<'EOF'
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: httpd-replicaset
labels:
app: httpd_app
type: front-end
spec:
replicas: 4
selector:
matchLabels:
app: httpd_app
type: front-end
template:
metadata:
labels:
app: httpd_app
type: front-end
spec:
containers:
- name: httpd-container
image: httpd:latest
EOF
```
## How it works
### The heredoc apply pattern
- **`kubectl apply -f -`** reads from **stdin**; the heredoc feeds the YAML in, nothing on
disk.
- **`<<'EOF'` (delimiter quoted)** disables shell expansion, keeping `$VAR`/backticks
literal — the right default for Kubernetes YAML.
### The manifest, field by field
- **`apiVersion: apps/v1` / `kind: ReplicaSet`** — a ReplicaSet ensures a specified number
of identical pod replicas are running at all times, recreating any that die. (In
practice you'd usually use a Deployment, which manages ReplicaSets and adds rollouts —
but the task asks for a bare ReplicaSet.)
- **`metadata.name: httpd-replicaset`** — the RS name, exactly as required.
- **`metadata.labels`** — `app: httpd_app` and `type: front-end` on the ReplicaSet object
itself, as required.
- **`spec.replicas: 4`** — the desired pod count. The RS controller works continuously to
keep exactly 4 matching pods running.
- **`spec.selector.matchLabels`** — how the RS identifies the pods it owns. This **must**
match the pod template's labels, or the API rejects the manifest with `selector does not
match template labels`.
- **`spec.template`** — the pod blueprint:
- **`template.metadata.labels`** — `app: httpd_app`, `type: front-end` stamped on every
pod. These are what the selector targets.
- **`template.spec.containers`** — one container: **`name: httpd-container`** with
**`image: httpd:latest`** (tag stated explicitly, as required).
### Why the selector and template labels must agree
A ReplicaSet is decoupled from its pods and tracks them purely by label selector.
`spec.selector.matchLabels` is the query; `spec.template.metadata.labels` is what gets
stamped on each pod. If they don't match, the RS couldn't recognize its own pods, so
Kubernetes rejects the config outright. Both carry `app: httpd_app` + `type: front-end`
to satisfy that contract.
> Selector caution: because a ReplicaSet adopts **any** existing pod matching its selector,
> reusing labels that other pods already carry can cause it to adopt (or fight over) them.
> The two-label selector here is specific enough to avoid that in a clean environment.
## Verify
```bash
# ReplicaSet exists with 4 ready replicas
kubectl get rs httpd-replicaset
# Pods are running and labeled
kubectl get pods -l app=httpd_app,type=front-end --show-labels
# Container image is correct
kubectl get rs httpd-replicaset \
-o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'
```
Expected — `httpd-replicaset` showing `DESIRED 4 / CURRENT 4 / READY 4`, four pods
`Running` with both labels, and the image printing `httpd:latest`.
> If pods sit in `ImagePullBackOff`, the `httpd:latest` pull failed (node offline /
> rate-limited). `kubectl describe pod <name>` shows the pull events.