Kubernetes Kubernetes

Write Your First Kubernetes Manifest

YAML essentials, the four fields every object has, and the create, inspect, delete loop with a Pod.

12 min Beginner

Everything you create in Kubernetes is an object described in a manifest, a YAML file that says what you want. This guide covers just enough YAML to read one, explains the structure every manifest shares, and walks through running a Pod from a file. It assumes a working cluster (see the previous guide).

YAML in five minutes

YAML has two building blocks you need to recognize.

A map is a set of key: value pairs. Indentation shows nesting, and everything indented under a key belongs to it. A list is a series of items, each starting with a dash:

app:
  name: shop
  enabled: true
  labels:
    tier: frontend
  ports:
    - 80
    - 443

Here app is a map with the keys name, enabled, labels, and ports. labels is itself a map, and ports is a list of two numbers. Use spaces, never tabs. Wrong indentation is the most common cause of a manifest that won’t apply, and it silently changes what belongs to what. Several objects can share one file if you separate them with a line containing ---.

Anatomy of a manifest

Every Kubernetes object has the same top-level fields:

  • apiVersion says which version of the API defines this kind of object.
  • kind is the type of object, such as Pod or Deployment. It is case-sensitive.
  • metadata identifies the object: its name, optionally a namespace, and any labels and annotations.
  • spec is the desired state, and its contents depend on the kind.

Kubernetes adds a fourth section, status, which describes the actual state. You don’t write it. Here is a minimal Pod:

apiVersion: v1
kind: Pod
metadata:
  name: web
  labels:
    app: web
spec:
  containers:
    - name: nginx
      image: nginx:1.25
      ports:
        - containerPort: 80

containers is a list, so a Pod could run several containers, each starting with its own dash. The image field is the one to double-check. A typo means Kubernetes can’t pull it and the Pod will sit in an error state.

Don’t write manifests from scratch

Copy a working example from the Kubernetes documentation or have kubectl generate one:

kubectl run web --image=nginx:1.25 --port=80 --dry-run=client -o yaml > pod.yaml

--dry-run=client builds the object locally without creating it, and -o yaml prints it as YAML. That gives you a valid starting point to edit.

Get the apiVersion right

Different kinds live in different API groups and versions. Pods are v1, Deployments are apps/v1, Ingresses are networking.k8s.io/v1. If you pick the wrong one, or use a version that a newer cluster has removed, you get an error such as no matches for kind "X" in version "Y". To find the right value:

kubectl api-resources | grep -i deployment
kubectl explain deployment | head

The first shows the group for each kind, and the second shows its VERSION. This matters most when you upgrade a cluster, because old manifests can stop working when a version is removed. The Kubernetes deprecation guide lists what changed in each release.

Create, inspect, and delete

kubectl apply -f pod.yaml
kubectl get pods
kubectl describe pod web
kubectl delete -f pod.yaml

In kubectl get pods, the READY column shows how many of the Pod’s containers are ready (1/1 is healthy), STATUS shows its phase, and RESTARTS counts container restarts. A number that keeps climbing means something keeps killing the container. describe prints the Pod’s full details, with the recent events at the bottom, which is the first place to look when something is wrong.

apply is declarative: it creates the object if it doesn’t exist and updates it if it does, so you can edit the file and apply again. kubectl create -f fails if the object already exists.

Imperative vs declarative

Commands like kubectl run and kubectl create are imperative: you tell Kubernetes to do something now. They are quick for experiments and for certification exams. Manifests applied with kubectl apply -f are declarative, and that is what you want for anything real, because the files can live in Git, be reviewed, and be reapplied. The Argo CD guides in this series show how to take that idea to its conclusion.

Popular Guides