Making sense of Kubernetes configuration files (YAML)

Sau-rav Adhikari
wesionaryTEAM
Published in
7 min readFeb 8, 2021

--

Hello everyone! In this article, we will be taking a deep dive into understanding the configuration files (YAML) that we write for Kubernetes objects. If you’re someone who is learning or working with Kubernetes, you will definitely be writing configuration files for Pods, Deployments, Services, Ingress, and other Kubernetes objects.

Being someone who had no actual understanding of what those well-formatted YAML lines in the configuration files meant when learning Kubernetes, all I was doing was making sure my applications were up and running without fully understanding the how and why?

I decided to write this article to help anyone starting to learn Kubernetes so that those well-formatted lines do not scare you, and you can write them right off the top of your head.

Before you get started, make sure you have “minikube” and “kubectl” installed and ready to go.

Installation guide: https://phoenixnap.com/kb/install-minikube-on-ubuntu

  • minikube is a tool that allows us to run a single-node Kubernetes cluster locally. This is a great tool to try out Kubernetes.
  • kubectl is a command-line tool that allows us to run commands against our Kubernetes cluster.

After installation, start your minikube cluster and make sure kubectl is working properly as well.

$ minikube start
minikube start

Let’s get started by looking at the required fields for every configuration file regardless of the Kubernetes object type.

  • apiVersion: Specifies the version of the Kubernetes API, we will be using to create our Kubernetes object
  • kind: Specifies the type of Kubernetes object we are trying to create
  • metadata: Contains information that helps us to uniquely identify our Kubernetes object
  • spec: Specifies the desired state of our object

What do we mean by “the desired state”?

A description of the characteristics we want the resource/object to have. For example,image you want run on the object, ports, memory & CPU limitations etc.

Bonus Tip

If you use VS Code, install the Kubernetes extension, among the many features, it provides us with snippets that we can use to generate our Kubernetes objects.

Kubernetes Extension

So, let’s get started with writing a configuration file that will help us to create Pods in the Kubernetes cluster.

Pods

Pods are the smallest deployable objects in Kubernetes, they contain one or more of our containers, such as Docker containers.

A Pod is meant to run a single instance of our application on the Kubernetes cluster. However, we will not be creating individual pods directly in Kubernetes when working rather we will be creating “deployments” to manage our pods. We will look at this in more detail when talking about “deployments”. For now, let’s look at the template for creating a basic pod in Kubernetes.

Kubernetes pod template

Be sure to format your document properly with indentation.

Here, line 1 and 2 specifies that we are trying to create a Pod object using version one (v1) of Kubernetes API.

From line 3 we start specifying the “metadata” for our pod.

  • name: Specifies the name that will be applied to our pod

This is the name that will be displayed when you run the following command.

$ kubectl get pods

From line 7 we start specifying the “desired state” for our pod.

Pods are capable of running multiple containers, we have to specify the containers in an lists format.

You can configure your pods even more by specifying the resource limits, container ports, etc. if you want to in the spec section.

Let’s create a simple pod that will run the “nginx” docker image. Create a new “app-pod.yaml” file and write the following content. (Make sure to give proper indentation)

Kubernetes pod example

Now we are ready to actually create our pod in the cluster. To create a pod go to the terminal and type the following command.

// If you are in the directory where you have saved your file
$ kubectl apply -f app-pod.yaml

My “app-pod.yaml” file is inside the “/infra/k8s” folder so I will create the pod by specifying the path to the configuration file.

You can use “.” to apply all the files.

Congrats, our pod is now created. Let's get details about our pod. Type the following command:

$ kubectl get pods -o wide

-o wide” is not mandatory. O stands for output, and I did “-o wide” here just log additional information

If you want more information about your pod you can type the following command in your terminal:

$ kubectl describe pod myapp-pod

Congratulations, you are now capable of creating a Kubernetes pod right off your mind.

Deployments

Now, let’s continue and checkout “deployments”. Most of the time we will be writing deployments to manage pods since pods are not directly deployed to the cluster.

Deployments make our life easier as we do not have to manually deal with pods. Deployments will automatically manage the application lifecycle, run the requested number of pods/replicas, monitor them, and if a pod dies it will automatically re-create it. This is where “scalability” and “availability” are achieved.

Let’s start with a template for creating “deployments”.

Kubernetes deployment template

Here you can see we have the same 4 mandatory fields just the contents have been slightly changed.

We are trying to create a deployment, so we specify that in line 2 and the Kubernetes API version in line 1. Nothing much has changed until now.

Starting from line 3 we specify “metadata” for the deployments. You can see a new field called “labels” has been added here.

  • labels: Labels are key-value pairs attached to the object that helps to organize and to select subsets of objects.

Labels & Selectors is how we connect different Kubernetes objects. The metadata section contains “labels” and the spec section contains the “selectors”.

Here the label specified in line 5 is attached to our “deployment” which will be used to connect it to other Kubernetes objects like “services”. We will be talking about this in more detail in the “spec” section, where we connect our deployment to the pods.

In the “spec” section you can see new fields as well.

  • replicas: Specifies the number of pods to run
  • template: Specifies the desired state of our pod
    [ Here we write the configuration for our pod. See how its just missing “apiVersion” and “kind” field]

Notice how we are also giving our pod a label of “app: myapp” this label will be matched by the selector

  • selector: Defines how the Deployment finds which Pods to manage
    ** The key-value pair specified in matchLabels, must be the same as the key-value pair specified in the labels of the pod (inside template)

Congrats! Now you know about deployments too. Just remember the four mandatory fields and do not try to memorize each line, just connect the dots.

Now, let's create our deployment. Just like before we will create a configuration file for the deployment and apply it.

Kubernetes deployment example

Let’s get our deployment details.

$ kubectl get deployments -o wide

Great all of our 3 replicas are up and running.

Services

Service is the Kubernetes object that enables network access to a set of Pods in Kubernetes, by defining a logical set of Pods and a policy to access them such as IP, ports, protocol, etc.

When we make a request to the service, it matches the service’s selector and selects all the pods in the cluster matching it, chooses one of the pods, and forwards the request to it.

Services provide us with permanent IP addresses that can be attached to a pod.

It is important to know that the lifecycle of a pod and service are not connected, so even if the pod dies the IP address and service will stay.

Creating services is simple in Kubernetes for you since you can already create pods and deployments. Look at the template below and try to guess what every line does.

The selector in line 6 matches labels for deployments or their pods. This helps to connect the deployments to the service.

Here we can see two new fields called “type” and “ports”.

  • type: Specifies the type of service we want to create

Read more about different types of services: https://www.bmc.com/blogs/kubernetes-services/

  • ports: Specifies the protocol, the port on which the service is accessible, the port of the pod where it should forward its requests (targetPort)

Let’s create our service.

$ kubectl apply -f infra/k8s/.

Let’s get the details of our service.

$ kubectl get services -o wide

Well done, out of many Kubernetes objects you now know about pods, deployments, and services. Though I am ending this article here, your journey to learn Kubernetes has not ended yet. Keep learning and stay safe!

What to do next?

  • Check out other Kubernetes objects like Ingress, Statefulset, EndPoints, etc.
  • Check out various types of Kubernetes services
  • Skaffold, an awesome tool that simplifies the build and deployment processes. Do check it out once.

🙏🏻 Thank you for reading this article.

--

--