YAML in Kubernetes: A Practical Guide
Kubernetes manifests are usually where people first feel genuinely intimidated by YAML — the files are longer, more deeply nested, and one wrong indent can mean a deployment silently doesn't do what you expect. The good news: the structure is more predictable than it looks.
The four sections every manifest has
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
labels:
app: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web-app
image: myregistry/web-app:1.4
ports:
- containerPort: 8080
apiVersion and kind tell Kubernetes what kind of object this is and which version of its API to use. metadata is naming and labeling — how you and Kubernetes will refer to this object later. spec is the actual desired state: what you want to be true.
Why manifests nest so deeply
Notice spec appears twice — once for the Deployment itself, and once inside template, describing the pods it creates. That's not a copy-paste error; a Deployment's spec describes how many replicas you want, while the template's spec describes what each individual pod should look like. It's genuinely two different things, which is why the nesting goes deep. Once you know to expect that pattern, it stops feeling arbitrary.
The single most common mistake
containers is a list (notice the dash before name), and everything belonging to one container needs to be indented consistently under that dash. A single space out of place here can cause the container to fail to be recognized correctly, and the resulting error from kubectl apply often doesn't point directly at the real cause.
Because Kubernetes manifests tend to be long, we'd genuinely recommend running them through the formatter after any hand-edit — it re-indents consistently and will flag a structural problem immediately, rather than after a failed kubectl apply.