Kubernetes 101: Introduction to Container Orchestration šŸŽµ šŸ³ ā€” II

Momal Ijaz
AIGuys
Published in
7 min readApr 27, 2023

In this article, we will continue developing and deploying our simple NodeJS app to our Kubernetes cluster. If you donā€™t have an app image pushed to the docker hub and a remote/local cluster to which you want to deploy your app, you can read the first part of the article here.

So in the last article, we set up a local manicure cluster and we also dummy node JS app code into an image and pushed it to the docker hub. The name for my image was momil56/kubernetes101-demo-image, your could be different from this.
Now we need to create nature's objects in order to deploy this app into our local minikube cluster. The object that we need to create our as follows:
1. Deployment
2. Pod
3. Service

We will talk in detail about each object as we go about creating them so first of letā€™s start by creating a deployment object.

1. Deployment Object šŸ§°

We need to create a new file called deployment.yaml in our project directory and add the following contents to it. The image name would be different in your case of course, but other than that all other components of the file would most be similar.

A deployment object in kubernetes

The name of the file is also up to you. Now letā€™s dive deeper into the contents of the fileā€¦.

Explaining main contents of a kubernetes deployment object

This method of creating a Kubernetes object is called the declarative approach. We create a yaml file for each object, that needs to be created or we can declare multiple objects in the same file too and give the command to our k8s cluster to create the said resources, using kubectl CLI tool.

The main components of a kubernetes object file are:

a. apiVersion: At line:1, you can see we specify the apiVersion needed for this object, it varies for every type of object and you can check this out from the kubernetes official documentation by ā€œkubernetes <object> yaml fileā€ or a better search query.

b. kind: Here you specify the type of object you are creating, like deployment or Pod or Service, etc.

c. spec: Later on you specify the specs of the object. Again it varies from object to object and you can look at specific specs of an object, from k8s official docs, for the deployment object we set:

  1. replicas: This specifies the number of replicas we want to create of this pod, it should be an estimated guess based on the traffic volume you expect your app to come across.
  2. selector: This key specifies which pods are controlled by this deployment. You can simply add any number of key-value pairs of your choice and when creating other resources you can put the same tags on them, to allow Kubernetes to understand which pods are controlled by this deployment. I used an app tag with the value k8s101-app and a tier tag, you can choose whatever you want, but mind that you need to specify the same key-value pair in the pod labels too.
  3. template (Pod): Template is a sub-object, in the specs of deployment, and refers to a pod. Remember a pod is the smallest unit in a Kubernetes cluster and it holds and executes one or more containers. Here, we specify labels in metadata, which needs to match at least one of the labels of deployment. We also specify the specs of the template object, which has a sub-object called containers, which is a list of containers with their name and image, which we want to run in this pod. We currently are running just one container in our pod.

1.1 Applying Deployment Object šŸ› ļø

Now that we have created our deployment object, we can apply it to our minikube cluster by using kubectl. Before you do that make sure to check the status of your minikube cluster by running the command:

minikube status 

If your cluster is not up and running, you have to start it first by:

minikube start --driver=<your vm name / docker>

Again check the status of your cluster and now we need to create the deployment object using our file via:

kuebctl apply -f=deployment.yaml

Once your deployment object is created, you can see a success message and can check the created resource on the dashboard by:

minikube dashboard
Minikube dashboard with one deployment object with one pod with a single replica!

or by:

kuebctl get deployment

2. Service Object šŸ•ā€šŸ¦ŗ

So now we have our app running in a pod in a deployment object in our local minikube kubernetes cluster, but how do we access our app? If you check the app.js file in the project directory here, you can see the app listens on port 3000, but we cannot access it using localhost:3000, because it is not running in a simple docker container, rather our app is running in a virtual machine on our local system, inside a Kubernetes cluster.

So trying to access the app from our local system is like trying to reach the app from outside world, and that functionality is not provided in kubernetes deployment or pod object right off the shelfā€¦. hence in order to make your kubernetes app accessible to world, you need a service object!

Letā€™s create a new file called service.yaml and paste these contents into it.

A service object in kubernetes
service object explained

As you can see from the description, we are using the same app tag to tell help kubernetes to decide which pods are going to be exposed using this service. This tag needs to be similar to one of the tags on your pod labels, that you want to make accessible.

In specs of the service, we have a protocol, which is TCP in our case. the targetPort is appā€™s port 8080, which is mapped to port 80 in pod, to access the service running in the pod.

Type of service is another important component, for our case, we are using LoadBalancer, which allows traffic management / ā€œload balancingā€ and enables the pods to communicate with the outside world. We have other two options as well.. ā€œClusterIPā€ and ā€œNodePortā€, which are used for cluster internal access and node-specific outside-world access. But if you want outside-world access for your pod, LoadBalancer is the best type to go with.

2.1 Applying service object šŸ› ļø

Now letā€™s apply our service object as well via:

kubectl apply -f service.yaml

Once your service is created, you need to access your app from the outside world / or your local system, which is possible via having a static external IP address for our pod. Now with paid cloud-based services / remote clusters, that is automatically done, but if you look at the service object that you just created in your minikube cluster, that doesnā€™t have an external IP assigned, because that is something you donā€™t get for free and hence this is missing from minikube setupā€¦.

Our service backend doesnā€™t have an External endpoint by default

But there is a workaround for accessing our app, running in a minikube setup and that is by running:

minikube service <service_name>

You will see an output like this, check out the localhost address and voila:

Your app running in local minikube cluster

If you are running into errors, check out the service and deployment object and pod to make sure the labels are correctly set and the image is pushed correctly and you are using the right image name in the deployment object, if everything is configured perfectly you should be able to see the app runningā€¦ else play around with the dashboard and object logs to find the problems.

Conclusion šŸ’”

A high-level idea of what you just built is right here:

Minikube app setup

You set up an app in a single node minikube cluster, running in a virtual machine on your system, that is talking to the outside world via a service object. Your app has a deployment object, with a single pod hosting a single container with your appā€™s imageā€™s running instance. This containerā€™s port 8080 is mapped to port 80 of your pod, which is then mapped to a dynamic external IP by the service, that you use to access your app.

Your app would be now monitored by Kubernetes, and would autoscale (depending on the number of pod replicas) to handle incoming traffic load and would spin up again if the container or pod crashes.

Congratulations! Thatā€™s an MLOps feast you just didā€¦. I am excited for you to use kubernetes for your own amazingly auto-scalable, reliable and monitored apps and projects!

Happy Learning ā¤ļø

--

--

Momal Ijaz
AIGuys
Writer for

Machine Learning Engineer @ Super.ai | ML Reseacher | Fulbright scholar'22 | Sitar Player