Why "boring" wins
A workload is four files you can read. If you cannot explain the hop from hostname to container port, you do not own the cluster — you rent a dashboard.
What we are deploying
Uptime Kuma in its own namespace, one replica, pinned tag, ClusterIP, hostname via ingress.
- The workload lives in its own namespace — not default.
- One replica, pinned image tag, readiness probe attached.
- A ClusterIP Service fronts the pod. Nothing is exposed raw.
- You verified it with port-forward before trusting the browser.
The request path
When you type kuma.bench.local, the request walks this path. Every box to the right of DNS is plumbing you own.
The deploy, step by step
- STEP01
Namespace first
Nothing in this series ships into default.
Namespace firstyamlapiVersion: v1kind: Namespacemetadata:name: kuma - STEP02
Pin the image
Save the Deployment. If you swap apps later, three lines change: image, port, probe path.
Pin the imageyamlapiVersion: apps/v1kind: Deploymentmetadata:name: uptime-kumanamespace: kumaspec:replicas: 1selector:matchLabels:app: uptime-kumatemplate:metadata:labels:app: uptime-kumaspec:containers:- name: uptime-kumaimage: louislam/uptime-kuma:1.23.16ports:- containerPort: 3001
When it breaks
Every bad state has a name, and every name has a first command.
| Symptom | First command | What you are looking for |
|---|---|---|
| ImagePullBackOff | kubectl describe pod -n kuma | A tag typo, or the node cannot reach the registry. |
| CrashLoopBackOff | kubectl logs -n kuma --previous | The dying words of the last container. |
Homework
- Apply the stack and watch the pod cross to 1/1 Running with -w.
- Hit it via port-forward, then via the hostname.
- Delete the pod and watch the Deployment conjure a replacement.
.jpg)


