How YOU actually use Kubernetes, starring YAML files
Tags: kubernetes, devops, docker, tutorial
Published: 2019-07-01 21:53:46

---
title: How YOU actually use Kubernetes, starring YAML files
published: true
description: Want to use Kubernetes in a more professional manner? Then you need to learn about YAML files, especially in the context of Kubernetes
tags: kubernetes, devops, docker, tutorial
cover_image: https://thepracticaldev.s3.amazonaws.com/i/ibhdlncwacr68gip80ai.jpg
---

Follow me on [Twitter](https://twitter.com/chris_noring), happy to take your suggestions on topics or improvements /Chris

> I've described concepts such as Minkube, Pods, Nodes, Services and more over the course of four articles. Although educational you are likely to use Kubernetes in a different way than how I been showing you so far, you are likely to use YAML files

YAML files are files that let us define a configuration of whatever it may be.

> YAML as in Y A M L, aka Y M C A? :)

![](https://thepracticaldev.s3.amazonaws.com/i/pdkhfkeu5sqyngcpt6st.gif)

No, not like that, more YAML as in Camel

![](https://thepracticaldev.s3.amazonaws.com/i/rq94nuj4sbh9u2eomm1c.jpg)

> Oh ok, tell me more

YAML actually stands for "**Y**AML **A**in't **M**arkup **L**anguage" even though it from the beginning stood for **Y**et **A**nother **M**arkup **L**anguage. The reason for changing its meaning was to make clear its purpose as data-oriented, rather than document markup.

Yep, you got it, it's a recursive definition. It's also called a *human-readable data serialization language*. 

> Thanks for the history lesson, what about its role in Kubernetes?

As we said before we've been showing you Kubernetes usage by using the command line and that ain't quite how people use it. 

> Let me guess I use YAML files

Right, every single thing you can describe and deploy to Kubernetes can be described as a YAML file. It's actually simpler that way as well. But before we talk about specific Kubernetes usage we need to know some basics about the YAML files, so to understand the file when we are looking at it

> I'm gonna need coffee for this right?

## Resources

This article isn't really part of a series but I have written other parts on it. If you are completely new I recommend reading part I first below

- [Part I - from the beginning, Part I, Basics, Deployment and Minikube](https://dev.to/azure/kubernetes-from-the-beginning-part-i-4ifd) 
In this part, we cover why Kubernetes, some history and some basic concepts like deploying, Nodes, Pods.
- [Part II - introducing Services and Labeling](https://dev.to/azure/kubernetes-part-ii-revisiting-pods-and-nodes-and-introducing-services-and-labeling-5fi7) 
In this part, we deepen our knowledge on Pods and Nodes. We also introduce Services and labeling using labels to query our artifacts.
- [Part III - Scaling](https://dev.to/azure/kubernetes-part-iii-scaling-1mmi)
In this part, we look at scaling using *desired* state. We specify how many Pods we want and let Kubernetes do the heavy lifting in terms of ensuring that your Pods are scaled up to the desired number but also maintaining it by using something called self-healing.

- [Part IV - Auto scaling](https://dev.to/azure/kubernetes-from-the-beginning-part-iv-autoscaling-54l6)
This is how you likely will carry out scaling in Kubernetes by looking at CPU usage

Below is some more resource that I recommend you have a look at when Kubernetes is starting to click:

- [Horizontal Pod Auto scale](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) This describes in detail how everything works. On a flow as well as API level
- [Free Azure Account](https://azure.microsoft.com/en-gb/free/?wt.mc_id=devto-blog-chnoring) If you want to try out AKS, Azure Kubernetes Service, you will need a free Azure account
- [Kubernetes.io](https://kubernetes.io)
One of the best resources to learn about Kubernetes is at this official Kubernetes site by Google.
- [Kubernetes overview](https://azure.microsoft.com/en-gb/topic/kubernetes/?wt.mc_id=devto-blog-chnoring) An overview of Kubernetes, all its parts and how it works
- [Kubernetes in the Cloud](https://azure.microsoft.com/en-gb/services/kubernetes-service/?wt.mc_id=devto-blog-chnoring) Do you feel you know everything about Kubernetes already and just want to learn how to use a managed service? Then this link is for you
- [Documentation on AKS, Azure Kubernetes Service](https://docs.microsoft.com/en-gb/azure/aks/?wt.mc_id=devto-blog-chnoring)
Azure Kubernetes Service, a managed Kubernetes
- [Best practices on AKS](https://docs.microsoft.com/en-us/azure/aks/best-practices?wt.mc_id=devto-blog-chnoring) You already know AKS and want to learn how to use it better?

## The YAML format

What do we need to know about the format to be able to work with it? Well, YAML is a superset of JSON which makes a JSON file a valid YAML file. That's an interesting piece of information but really want to know is the structures used within namely:

- Maps
- Lists

> Ok, show me

### Maps
Let's start with creating a file, let's call it `config.yaml`:

```yaml
--- 
version: 1
name: some value
```

This above right here contains some useful insights on the YAML format. The `---` is called a separator and is optional unless we have more than one structure in the file. What we see after that is `version` and `name`. The key is separated by its value with `:`. 

> This is supposed to be a superset of JSON right, aren't we missing double quotations?

Ah, sharp eyes, double quotations `""` are actually optional. Why write more than you have to right? So the above corresponds to the following in JSON:

```json
{
  "version": "1",
  "name": "some value"
}
```

The above is a map, but one of the keys in your Map can point to a map in turn, like the below example:

```yaml
--- 
version: 1
name: some value,
address: 
  street: One Microsoft Way
  city: Redmond
  country: USA
```

### Lists
Ok then, let's look at our next format lists. Consider the following example:

```yaml
version: 1
todos:
 - shop
 - clean
 - do math
 - write essay
```

`todos` in this case is the list type and this would correspond to the following in JSON:

```json
"version": "1",
"todos": ["shop", "clean", "do match", "write essay"]
```

> What about list items that are maps?

That's simple:

```yml
created: 2019-01-01
items:
 - quantity: 2
   price: 10
   discounts:
     - id: 1
       displayName: 10% off  
     - id: 111
       displayName: Holiday Sale
```

The above would correspond to the following JSON:

```json
{
  "created": "2019-01-01",
  "items": [{
    "quantity": 2,
    "price" : 111,
    "discounts": [{
      "id": 1,
      "displayName": "10% off"
    }, {
      "id": 111,
      "displayName": "Holiday Sale"
    }]
  }]
}
```

> I get it, I think. What about Kubernetes?

Oh, one more thing before we turn all Kubernetes. Tabs = NOT cool. Spaces are what you use but *be consistent*, if you start using 2 spaces, usee that throughout.

## YAML In Kubernetes

Most of the things you can deploy to a Cluster in Kubernetes can be described as a YAML file. There are some obvious advantages to that:

- **Saving your fingers**: No more typing long constructs on the command line
- **Source control**: YAML files can be stored in source control and thereby we can track changes
- **Flexibility**: You’ll be able to create much more complex structures using YAML than you can on the command line

So what are we going to describe in YAML then? We will not only describe but deploy the following: 

- **Pod**, Pod is the smallest possible deployable unit. I know know, you usually don't deploy just a Pod, for the sake of practice lets do it this once
- **Deployment**, this is more on the level of what we would want to deploy. It gives us the ability to defines *replicas* among other things


### Describe and deploy a Pod

Lets build up YAML file for a Pod gradually and finish off by deploying to the Cluster. Ok, here we go:

```yaml
—--
apiVersion: v1
kind: Pod
```

We start by specifying an `apiVersion`. Then we continue with specifying `kind: Pod`. Now this one is important. This can be many different types like a Deployment or a Service for example, Pod it is.

**Metadata**
The next part of our file is the metadata part. Here we give it a name and also a label:

```yaml
metadata:
 name: My Pod
 labels:
   app: web
```

**Specification**

Now we come to the part where we describe the parts that make up the Pod.

```yaml
spec:
  containers:
    - name: first-app
      image: gcr.io/google-samples/kubernetes-bootcamp:v1
      ports:
        - containerPort: 8080
```

All put together our `pod.yaml` file should now look like this:


```yaml
apiVersion: v1
kind: Pod
metadata:
 name: my-pod
 labels:
   app: web
spec:
  containers:
    - name: first-app
      image: gcr.io/google-samples/kubernetes-bootcamp:v1
      ports:
        - containerPort: 8080
```

### Deploying our POD YAML

At this point we want to deploy it to a cluster. So we will talk to our old friend again, `minikube` and `kubectl`.

Sometimes my `minikube` is a bit slow so I restart it with the command `minikube start`. Once that command has finished running let's check the pod situation with:

```
kubectl get pods
```

It should list all the Pods that are currently up and running:

![](https://thepracticaldev.s3.amazonaws.com/i/5y2719fm1ca6y1q7b1uv.png)

As you can see above we have done a fair bit of experimenting in the past and created all sorts of Pods, this will obviously look different for you.

Thereafter let's take our `pod.yaml` file and create a Pod from it. To do that we run the command:

```
kubectl create -f pod.yaml
```

Which simply means create a Pod from a file `-f`, with file name `pod.yaml`. The result of this command is:

![](https://thepracticaldev.s3.amazonaws.com/i/fmwzj23hbfjk8hifhzxg.png)

The result of the command implies we got a Pod created, let's rerun our pods listing command:

```
kubectl get pods
```

![](https://thepracticaldev.s3.amazonaws.com/i/wmyzv2sjt7i32l6ul5yf.png)

This time around our new Pod is up and running. But of course, deploying just a Pod like this is no good. The reason is that Pods are mortal, if it goes down, its gone. No service will bring it up again. 

> So why even show it?

It might be educational to show how you can create an artifact from a file but from a Kubernetes standpoint, it's not using all the wonderful services that could keep it alive if something happens. After all, that's why we have Kubernetes, for the resilience.

Therefore, let's look at a deployment next.

Before we continue let's clean up after ourselves with:

```
kubectl delete pods my-pod
```

This trigger something called a *graceful* termination, which is the recommended way of doing things. If you are impatient though you can *force delete* it with the following command:

```
kubectl delete pods my-pod --grace-period=0 --force
```

We of course delete the *graceful* way so after a while we get this:

![](https://thepracticaldev.s3.amazonaws.com/i/uyqfkrhfq77dnux662mc.png)

Were you to run `kubectl get pods` our pod is now gone. All our app data, gone, vamose. 

> I get it, take it easy, I won't create Pods directly, can we continue?

### Deployment

Ok then, deployments, the right way of doing things. 

We will use something called a `ReplicationController`. Now, this is technically an older concept that is gradually being replaced by `Deployment`s which are a high-level concept managing the deployment of `ReplicaSets`. There are issues on dashboard support and other things still, which makes all these similar concepts hang around to confuse us a bit more ;) Bottom line is its ok to use these older concepts for still some time.

This time around we will define a new type of object, a so-called `ReplicationController`. Now, this is a deployment that not only points out what image to deploy to a Pod but also how many Pods we want any given point, a so-called *desired state*. Let's have a look at the file, starting from the top:

```yaml
apiVersion: v1
kind: ReplicationController
metadata: 
  name: my-rc
```

We define the `kind` as of type `ReplicationController` instead of `Pod` and we go on to name it in the metadata as `my-rc`. Now let's head down to the specification part:

```yaml
spec:
  replicas: 5
  selector: 
    app: hello-world
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
      - name: my-first-app
        image: gcr.io/google-samples/kubernetes-bootcamp:v1
        ports:
        - containerPort: 8080
```

The really interesting part here is `replicas`, the number of Pods and the rest of it is mainly us pointing out the same image again.
 
The specification looks slightly different at the top level, as it is a ReplicationController but the inner `spec` is what we are used to, pointing out the image, port and other things. Let's see the full file that we name `rc.yaml`:

```yaml
apiVersion: v1
kind: ReplicationController
metadata: 
  name: my-rc
spec:
  replicas: 5
  selector: 
    app: hello-world
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
      - name: my-first-app
        image: gcr.io/google-samples/kubernetes-bootcamp:v1
        ports:
        - containerPort: 8080
```

We create the above deployment based on the file by typing:

```
kubectl create -f rc.yaml
```

![](https://thepracticaldev.s3.amazonaws.com/i/njz9cljlm2z5ff9bezr7.png)

Above we see that our replication controller is created. 

Lets list all our pods right now and make sure we get as many pods as expected:

```
kubectl get pods
```

![](https://thepracticaldev.s3.amazonaws.com/i/arw9v572xiwtf2rw7u8q.png)

Looking at the above listing we see that we have 5 replicas, 5 instances of our Pod. We could try and delete one and see what happens:

```
kubectl delete pods my-rc-wx6h7
```

It tells us the above Pod is deleted so we wait for the *graceful* deletion to finish and then we list our Pods again and this is what we get:

![](https://thepracticaldev.s3.amazonaws.com/i/co75bqrdimib6rxr3nic.png)

As you can see above, our specific Pod is deleted but it's being replaced by another one, the number of replicas is intact, Kubernetes is doing its job

> So how do we bring it down, garlic, a stake?

![](https://thepracticaldev.s3.amazonaws.com/i/ri61sug1nj24zauf9g8b.gif)

Let's start by listing all replication controllers:

```
kubernetes get replicationcontroller
```

![](https://thepracticaldev.s3.amazonaws.com/i/2c9yjfyityk9v4bnsdov.png)

Now there are two way we can bring it down, garlic or deletion ;)

> Yea yea very funny, deletion, tell me more *bored*

It's as simple as typing

```
kubectl delete replicationcontroller [name of replication controller]
```

What happens if you do the above is that it will not only delete the replication controller but the all the pods with it, so-called cascading delete. If you just want the replication controller gone you can specify `--cascade=false`. We want it all gone so we just type:

```
kubectl delete my-rc
```

That should remove all of it. If we run `kubectl get replicationcontroller` it should be gone. Let's run `kubectl get pods` and make sure the pods are gone too. 

Let's take away the other replication controller as well, it's been hanging around my system for far too long:

```
kubectl delete replicationcontroller my-rc
```

Quickly hit:

```
kubectl get pods
```

and you will be able to see the Pods being terminated:

![](https://thepracticaldev.s3.amazonaws.com/i/43bpff6te1w67zo1hr9y.png)

## Summary

In this article, we talked about the file format YAML, what it is, how it works. We also discussed how we should be using YAML files to configure our Kubernetes experience. Furthermore, we showed how to deploy Pods but also `ReplicationControllers`. Hopefully, this was educational and gave you a taste on what real Kubernetes management looks like.