Kubernetes YAML syntax

https://betterprogramming.pub/understanding-kubernetes-yaml-syntax-83359d33f9c2

Key-values

multiple key-values

key1: value 1
key2: value 2

single key with map

key1:
	subkey1: value 1
	subkey1: value 2
	subkey1: value 3

equivalent json for above

{
  "key1": {
    "subkey1": "subvalue1",
    "subkey2": "subvalue2",
    "subkey3": "subvalue3"
  }
}

Lists

list:
  - item1
  - item2
  - item3
  - item4
  - item5

equivalent json

{
  "list": ["item1", "item2", "item3", "item4", "item5"]
}

List can contain multiple maps

list:
  - item1
  - mapItem1: value
    mapItem2: value
  - item3
  - item4
  - item5

equivalent json

[
  "item1",
  {
    "mapItem1": "value",
    "mapItem2": "value"
  },
  "item3",
  "item4",
  "item5"
]

Example deployment.yaml

spec:
  selector:
    matchLabels:
      app: nginx

equivalent json

"spec": {
      "selector": {
         "matchLabels": {
            "app": "nginx"
         }
      }
}

Another yaml with lists

spec:
  containers:
    - name: nginx
      image: nginx:1.7.9
      ports:
        - containerPort: 80

json equivalent

"spec": {
            "containers": [
               {
                  "name": "nginx",
                  "image": "nginx:1.7.9",
                  "ports": [
                     {
                        "containerPort": 80
                     }
                  ]
               }
            ]
         }

Required Arguments in Kubernetes YAML

  • apiVersion
  • kind
  • metadata
  • spec

  • apiVersion - “Which version of the Kubernetes API you’re using to create this object?”

  • kind - “what kind of object are you creating?”

  • metadata - Data that helps uniquely identify the object, including a name string, UID, and optional namespace

Example deployment.yaml

apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2 # tells deployment to run 2 pods matching the template
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.7.9
          ports:
            - containerPort: 80

Converted json file

{
  "apiVersion": "apps/v1",
  "kind": "Deployment",
  "metadata": {
    "name": "nginx-deployment"
  },
  "spec": {
    "selector": {
      "matchLabels": {
        "app": "nginx"
      }
    },
    "replicas": 2,
    "template": {
      "metadata": {
        "labels": {
          "app": "nginx"
        }
      },
      "spec": {
        "containers": [
          {
            "name": "nginx",
            "image": "nginx:1.7.9",
            "ports": [
              {
                "containerPort": 80
              }
            ]
          }
        ]
      }
    }
  }
}

Each object has unique name and every kubernetes object has unique id across whole cluster.

You can have 1 pod named myapp-1234 within same namespace but you can have one Pod and one Deployment that are each named myapp-1234

Names

A client-provided string that refers to an object in a resource URL, such as /api/v1/pods/some-name.

Only one object of a given kind can have a given name at a time. However, if you delete the object, you can make a new object with the same name.

Names must be unique across all API versions of the same resource. API resources are distinguished by their API group, resource type, namespace (for namespaced resources), and name. In other words, API version is irrelevant in this context.

Naming convections with length restrictions and character limits are mentioned here https://kubernetes.io/docs/concepts/overview/working-with-objects/names/

Labels and Selectors

Labels are key-value pairs attached to objects such as pods. They are used to specify attributes of objects meaningful and relevant to users.

"metadata": {
  "labels": {
    "key1" : "value1",
    "key2" : "value2"
  }
}

Use case: Labels enable users to map their own organizational structures onto system objects in a loosely coupled fashion, without requiring clients to store these mappings.

Image 1.png

See examples here - https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/ Image 2


Namespaces

In Kubernetes, namespaces provides a mechanism for isolating groups of resources within a single cluster. Names of resources need to be unique within a namespace, but not across namespaces.

Namespaces cannot be nested inside one another and each Kubernetes resource can only be in one namespace.

Namespaces are a way to divide cluster resources between multiple users

Image 3.png

Not all objects are in namespace. Low level resources such as nodes and persistentVolumes are not in any namespace.

Annotations

These are arbitrary non-identifying metadata to objects. Annotations, like labels, are key/value maps:

"metadata": {
  "annotations": {
    "key1" : "value1",
    "key2" : "value2"
  }
}

Field Selectors

Field selectors let you select Kubernetes objects based on the value of one or more resource fields. Here are some examples of field selector queries:

  • metadata.name=my-service
  • metadata.namespace!=default
  • status.phase=Pending

example - kubectl get pods --field-selector status.phase=Running

It supports operators - =, !=, ==

kubectl get services --all-namespaces --field-selector metadata.namespace!=default

Chained Selectors - kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always

Finalizers

Finalizers are namespaced keys that tell Kubernetes to wait until specific conditions are met before it fully deletes resources marked for deletion. Finalizers alert controllers to clean up resources the deleted object owned. When you attempt delete, -

  • Modifies the object to add a metadata.deletionTimestamp field with the time you started the deletion.
  • Prevents the object from being removed until its metadata.finalizers field is empty.
  • Returns a 202 status code (HTTP “Accepted”)

Owners and Dependents

Some objects are owners of other objects such as ReplicaSet is owner of pods. These owned objects are dependents of their owner.

Ownership is different from labels/selectors. Services uses labels to allow control pane to determine EndpointSlice objects for that service. Each EndpointSlice has owner reference. Owner references help different parts of Kubernetes avoid interfering with objects they don’t control.