Skip to main content

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-primary

Resources

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: 512Mi

Probes

Three probes, three distinct questions:

ProbeQuestionFailure effect
startupStill booting?Other probes stay suspended
readinessReady for traffic?Removed from the endpoint
livenessAlive, or wedged?Container is restarted

The most common mistake we find: a livenessProbe that 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 }
  }
}