Kubernetes conventions
None of these conventions are aesthetic. Each one came out of a real incident.
Labels
Every object carries the same four labels. Network policies, dashboards, and alert routing all select on them.
metadata:
labels:
app.kubernetes.io/name: payments-api
app.kubernetes.io/part-of: payments
app.kubernetes.io/version: "2.14.0"
mizban.io/oncall-rotation: payments-primaryResources
Every container sets requests. Memory limits are mandatory; CPU limits are not.
Why we skip CPU limits
A CPU limit throttles the container even when the node is idle. The result is p99 latency nobody can explain. Memory is different: without a limit, one leak takes the node down and its neighbours with it.
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
memory: 512MiProbes
Three probes, three distinct questions:
| Probe | Question | Failure effect |
|---|---|---|
| startup | Still booting? | Other probes stay suspended |
| readiness | Ready for traffic? | Removed from the endpoint |
| liveness | Alive, or wedged? | Container is restarted |
The most common mistake we find: a
livenessProbethat reaches through to a dependency such as the database. When the database slows down, Kubernetes restarts every pod at once, converting a brownout into a full outage.
Cluster infrastructure
Clusters are built with Terraform, and nothing is accepted outside of state.
module "production" {
source = "mizban/kubernetes/cloud"
version = "3.2.1"
name = "production"
region = "ir-tehran-1"
control_plane_ha = true
node_pools = {
general = { size = "c4.xlarge", min = 3, max = 12 }
memory = { size = "r4.2xlarge", min = 2, max = 6 }
}
}