DEV Community

Cover image for How YOU actually use Kubernetes, starring YAML files
Chris Noring for Microsoft Azure

Posted on

How YOU actually use Kubernetes, starring YAML files

Follow me on Twitter, 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? :)

No, not like that, more YAML as in Camel

Oh ok, tell me more

YAML actually stands for "YAML Ain't Markup Language" even though it from the beginning stood for Yet Another Markup Language. 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

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

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:

--- 
version: 1
name: some value
Enter fullscreen mode Exit fullscreen mode

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:

{
  "version": "1",
  "name": "some value"
}
Enter fullscreen mode Exit fullscreen mode

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

--- 
version: 1
name: some value,
address: 
  street: One Microsoft Way
  city: Redmond
  country: USA
Enter fullscreen mode Exit fullscreen mode

Lists

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

version: 1
todos:
 - shop
 - clean
 - do math
 - write essay
Enter fullscreen mode Exit fullscreen mode

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

"version": "1",
"todos": ["shop", "clean", "do match", "write essay"]
Enter fullscreen mode Exit fullscreen mode

What about list items that are maps?

That's simple:

created: 2019-01-01
items:
 - quantity: 2
   price: 10
   discounts:
     - id: 1
       displayName: 10% off  
     - id: 111
       displayName: Holiday Sale
Enter fullscreen mode Exit fullscreen mode

The above would correspond to the following JSON:

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

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:

—--
apiVersion: v1
kind: Pod
Enter fullscreen mode Exit fullscreen mode

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:

metadata:
 name: My Pod
 labels:
   app: web
Enter fullscreen mode Exit fullscreen mode

Specification

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

spec:
  containers:
    - name: first-app
      image: gcr.io/google-samples/kubernetes-bootcamp:v1
      ports:
        - containerPort: 8080
Enter fullscreen mode Exit fullscreen mode

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

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

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
Enter fullscreen mode Exit fullscreen mode

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

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

kubectl get pods
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

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 Deployments 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:

apiVersion: v1
kind: ReplicationController
metadata: 
  name: my-rc
Enter fullscreen mode Exit fullscreen mode

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:

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
Enter fullscreen mode Exit fullscreen mode

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:

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
Enter fullscreen mode Exit fullscreen mode

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

kubectl create -f rc.yaml
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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:

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?

Let's start by listing all replication controllers:

kubernetes get replicationcontroller
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Quickly hit:

kubectl get pods
Enter fullscreen mode Exit fullscreen mode

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

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.

Top comments (1)

Collapse
 
hyscaleio profile image
HyScale

Hi Chris! Very educational on the much-dreaded YAML files while deploying to k8s. we at team Hyscale have been working on an open-source tool, that autogenerates k8s manifests for developers looking to deploy, eliminating the need to write all that YAML.

We would love to know the community's take on it and are open to feedback. :) We are at github.com/hyscale/hyscale