The Anatomy of YAML
The language of Kubernetes.
Typing commands is fine for experiments. But real work is done with files. Kubernetes reads Y A M L, a simple format for describing things. Once you can read one Kubernetes file, you can read them all, because they all share the same four parts. Let's learn them.

- Files describe your wishes
- Y A M L is simple text
- Every file has four parts
YAML in sixty seconds
First, the Y A M L basics. It is plain text, and the structure is made of indentation, using spaces, never tabs. A key and a value are written with a colon, like name colon hello. A list item starts with a dash. And a line starting with a hash sign is a comment, ignored by everything. That is nearly all the syntax. The most common mistake is wrong indentation, so keep your spaces tidy.
| Syntax | Example | Meaning |
|---|---|---|
| key: value | name: hello | a setting |
| indent 2 spaces | spec: then nested | belongs to the line above |
| - item | - name: web | one item of a list |
| # note | # a comment | ignored |
The four top-level fields
Now, a real Kubernetes file. Every object has four top level fields. First, A P I version, which says which version of the Kubernetes A P I knows this kind of object. For pods, it is simply v one. Second, kind, the type of object, here, a pod. Third, metadata, which holds the name, and labels. And fourth, spec, the specification, the heart of the file, where you describe what you want. Here we ask for one container, called web, using the engine X image, and listening on port eighty.
apiVersion: v1
kind: Pod
metadata:
name: hello
labels:
app: hello
spec:
containers:
- name: web
image: nginx:1.25
ports:
- containerPort: 80Apply a file
Let's apply this file, with kube control apply, and the dash f flag, which means file. Kubernetes answers, pod hello created. Now watch what happens if we apply the exact same file again. It says, unchanged. That is the declarative model at work, because the wish already matches reality, so nothing happens. Now we apply a second version of the file, which uses a newer image. This time it says configured. Kubernetes compared the wish with the existing pod, and changed only the difference.
kubectl apply -f pod.yaml pod/hello created kubectl apply -f pod.yaml pod/hello unchanged kubectl apply -f pod-v2.yaml pod/hello configured kubectl get pod hello -o jsonpath='{.spec.containers[0].image}' nginx:1.27
File used: pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: hello
labels:
app: hello
spec:
containers:
- name: web
image: nginx:1.25
ports:
- containerPort: 80File used: pod-v2.yaml
apiVersion: v1
kind: Pod
metadata:
name: hello
labels:
app: hello
spec:
containers:
- name: web
image: nginx:1.27
ports:
- containerPort: 80Generate YAML for free
Here is a trick that experts use every day. You never have to write a Y A M L file from a blank page. Ask kube control to generate one. The dash dash dry run flag means, do not really create anything, and dash o yaml prints the file, instead. Copy it into a file, change what you need, and apply it. And to see the full live version of an object, ask for it with dash o yaml. It includes the status, which Kubernetes fills in.
kubectl run demo --image=nginx:1.27 --dry-run=client -o yaml apiVersion: v1 kind: Pod metadata: labels: run: demo name: demo spec: containers: - image: nginx:1.27 name: demo resources: {} dnsPolicy: ClusterFirst restartPolicy: Always status: {}
Summary
Excellent. Every Kubernetes file has four parts, A P I version, kind, metadata, and spec. Apply creates or updates, and repeating it changes nothing. And you can generate a starting file, with dry run. Next, how Kubernetes finds things, with labels and selectors.
Key takeaways- apiVersion, kind, metadata, spec
- apply is safe to repeat
- --dry-run=client -o yaml generates files