Introduction to Kubernetes Manifest: Pod

In the previous article of this Kubernetes series, we started a Pod using the kubectl run command. I also mentioned that in real world, that is not how we create Pods, or any other resource type for that matter, in a Kubernetes cluster. Instead, we use Kubernetes manifest files. Kubernetes manifests are usually included in a configuration files written in YAML format and stored in a version control system.

Introduction to Kubernetes Manifest: Pod

Okay for starters, a little refresher on Pods. Pod is the smallest component in Kubernetes. A Pod is basically a layer of abstraction on top of a container. So if you want to deploy an application container, what you actually do in Kubernetes is deploying a Pod, not a container. A Pod is meant to run only one application container inside of it! However, there might be occasions where you would run another helper container along with the main application container inside the same Pod. But the most common and advisable practice is to run only one container in one Pod.

What is a Kubernetes Manifest?

Let me just cite the definition from the Kubernetes glossary here.

Specification of a Kubernetes API object in JSON or YAML format.

A manifest specifies the desired state of an object that Kubernetes will maintain when you apply the manifest. Each configuration file can contain multiple manifests.

Kubernetes Glossary

So as described here, a Kubernetes manifest is basically a Kubernetes API object description. It is written in either JSON or YAML format but mostly YAML.

If we take a Pod for an example, we specify the name of the Pod, any labels we want to assign to it, the containers that we need running inside the Pod in this manifest file. Furthermore, we also include the image name, all the environment variables, ports and volumes as well that should be associated with the containers in this manifest.

Any Kubernetes manifest file would usually contain 3 main sections. The first section will define the type of resource we are going to create and the API version. I think that is pretty straightforward.

The next section would be the metadata section. Here we define certain metadata about the resource, like the name and the labels we are going to assign to it.

Finally the specification section is where we write the specification of the resource. This could vary depending on the type of resource we are going to create.

Okay less talk and more work! Let’s create our first Kubernetes manifest file for a Pod!

Before you get into this, I would highly recommend brushing up on YAML basics and the syntax. Otherwise, you might get a little confused when understanding the structure of the manifest. It is super easy to learn and you can master it within 20-30 minutes! All you need to do is a quick Google search!:D

PS: I might write a small article regarding YAML later but at the moment, I don't feel like it. I have bigger fish to fry! xD

Writing a Manifest for a Pod

For this example, we will create a MySQL Pod. Below you can see the manifest for this Pod.

apiVersion: v1
kind: Pod

metadata:
  name: mysql-pod
  labels:
    app: mysql

spec:
  containers:
  - name: mysql
    image: mysql
    ports:
    - containerPort: 3306
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: charith

Let me explain this manifest line by line.

Version and Kind
  • Line 1 – apiVersion defines the Kubernetes API version. This could be a different value depending on the resource type. For a Pod, it is v1 at the time of writing this article.
  • Line 2 – kind defines the type of resource we are going to create. In this case the kind is Pod. Note that this manifest is case sensitive!
Metadata
  • Line 4 – the start of the metadata section.
  • Line 5 – here I have defined a name to my Pod. You can give any name using alpha numeric characters and hyphens. Spaces are not allowed.
  • Line 6&7 – here we are assigning some labels to our Pod. In this case, it would create a label like app=mysql. Note here that labels are specified as name-value pairs. You can specify any name and a value as you need.
Specification
  • Line 9 – the start of the specification.
  • Line 10 – earlier we discussed that a Pod is more or less a layer of abstraction on top of a container. So we need to define which containers would be running inside our Pod. Containers are listed as an array in the manifest.
  • Line 11-17 – this specifies a container and we have defined various attributes related to that container. Since we are creating a MySQL container from the official MySQL image on DockerHub, we can just look up the “how to use this image” section there and decide what we need to define in our manifest.
  • Line 11 – name defines the name of the container.
  • Line 12 – image defines the image that will be used for the container. Make sure to specify the image name and the tag, if you are using a specific version of the image.
  • Line 13&14 – MySQL uses port 3306 as the default, so I have specified that as the containerPort.
  • Line 15 – start of the environment variables relevant for the container. All the environments should be listed down as an array.
  • Line 16&17 – environment variables are specified as name-value pairs. According to Docker Hub, only mandatory variable is MYSQL_ROOT_PASSWORD, so I have specified that as the name and the actual password as the value.
    In Kubernetes, we don’t specify passwords in manifest files as it is not secure, but for the purpose of this article, I have done it like that.

Now that we have our manifest file, all we need to do is deploy this to the K8s cluster.

Deploy the Manifest

We can deploy this manifest to our cluster using kubectl apply command as shown below.

$ kubectl apply -f mysql-pod.yaml
pod/mysql-pod created

As you can see, I have saved my manifest file as ‘mysql-pod.yaml’ Make sure to open the command line from the directory where the manifest file is. If your file is without any errors, you would see that the Pod was created in the output.

Now if we run kubectl get pods command, we can see the details of the Pod as below.

$ kubectl get pods
NAME                             READY   STATUS    RESTARTS   AGE
mysql-pod                        1/1     Running   0          37m

In the above output, NAME is obviously the name of the Pod. Notice that it shows the value for READY as 1/1. This shows the number of containers that are ready in this Pod. Since we have only one container inside the Pod, it shows as 1/1. If we had two containers and both were ready, it would be 2/2.

STATUS shows the current status, which is ‘Running’. If the Pod is in ‘Running’ status, then it means it is working properly.

And that is it! We have created our first Kubernetes manifest file and deployed a Pod from it!

In this example we created a “naked Pod”. A naked Pod is a Pod that is not bound to a ReplicaSet or a Deployment. Naked Pods will not be rescheduled in case of a node failure. Therefore, we normally don’t create naked Pods. Instead we create Deployments. In the next article, we will look into Deployments.

Share this article if it was helpful!

Leave a Reply

Your email address will not be published. Required fields are marked *