Kubernetes For Beginners : Get up and running in minutes

Over the last couple of years there has been a tremendous momentum towards dev-ops. Developers/Engineers are expected to not only code, but take care of deployments, monitoring, alerting and running applications on a scale. The tradition of saying that code runs on my box just doesn’t cut any more.

There have been several open source projects that have come up in the recent years that help you to run your application at scale, load balance the traffic, take care of fault tolerance and provide automated monitoring solutions. Containerization technologies like docker and rkt have been game changers in shifting the paradigm towards platform agnostic deployments. You no longer need to install 10 different things on your box to run your code when you can package all of the dependencies together and run anywhere. Container orchestration tools like docker swarm (https://docs.docker.com/engine/swarm/ ) , coreOs ( https://coreos.com/ ) and kubernetes ( https://kubernetes.io/ ) have really made a significant impact on how we manage our applications on a cluster in a robust and reliable manner. This article is going to demonstrate how you can get started with kubernetes in a matter of minutes, provided you have your application ready and running locally. I primarily work on java/spring-boot based applications, so I will use that as a baseline application here, but it doesn’t have to be a java application.

Step 1: Clone Sample Spring boot project from github

git clone https://github.com/dipayan90/webcrawler.git

Step 2: Run App Locally

mvn spring-boot:run

You should see a simple Spring boot web application startup, which you can use locally by going to http://localhost:8080 or access its health endpoint by going to http://localhost:8080/health

Step 3: Look at the Dockerfile

vi Dockerfile

Look at the contents, where is a simple java application that runs on 8080 port leveraging spring-boot’s embedded tomcat instance.

Step 4: Build, Run and Publish the Docker Image to a Central Docker Repository ( in this case docker hub)

Pre-requisite for this step is that you should have docker installed on your machine. This is however optional, since for this demo we will pull a docker image off the internet.

Build the image:

docker build -t webcrawler .

Run the image:

docker run -p 8080:8080 -it webcrawler

Once it runs successfully, push the image using docker login and docker push ( https://docs.docker.com/docker-cloud/builds/push-images/ )

In our case we already have this image on docker hub: https://hub.docker.com/r/dipayan90/webcrawler/

Step 5: Install Virtualbox

We will be setting up a standalone kubernetes cluster that will run on local VM, so virtual box is go to choice for this, installation instructions can be found here: https://www.virtualbox.org/wiki/Downloads

Step 6: Install Kubectl – Command line client to access the kubernetes resources and the cluster

Installation instructions can be found here:  https://kubernetes.io/docs/tasks/tools/install-kubectl/

Step 7: Install minikube ( Standalone kubernetes cluster )

Installation instructions can be found here: https://github.com/kubernetes/minikube/releases 

Step 8: Start minikube locally

if you are directly connecting to the internet without any proxy, you can do:

minikube start

else if there is a corporate proxy involved:

minikube start --vm-driver="virtualbox" --docker-env="http_proxy=proxyHost:proxyPort" --docker-env="https_proxy=proxyHost:proxyPort"

Once it has started you can check the status of the cluster by:

minikube status

you should see the following output:

minikubeVM: Running
localkube: Running

You can alternatively do :

kubectl cluster-info

you should see the following output:

Kubernetes master is running at https://192.168.99.100:8443

Now that you have installed and checked that kubernetes standalone installation is successful, you can ssh into the VM by:

ssh docker@$(minikube ip) with password tcuser

Step 9:  Deployment.yaml – a closer look

Open the webcrawler/k8sresources/deployment.yaml  of the project you just cloned. This is a standard kubernetes template configuration file.

Lines 1 – 4 specify the file metadata information about the file, like the unit version, type of unit ( in this case Deployment) and name of the unit ( webcrawler-deployment )

Lines 5 – 10 specify the scalability spec, like number of replicas you want ( 3 here ) , and the app name.

Line 10 – 16 specifies the container level spec, which specifies the image to be run ( remember we pushed our image to dockerhub before, here we import the image dipayan90/webcrawler ). We also specify the port that the app is exposing and also name the container.

You can now deploy this docker image :

kubectl create -f deployment.yaml

You just kicked off the deployment process, now if you do:

kubectl get pods -l app=webcrawler  or  kubectl get pod -owide

you should see that 3 pods ( https://kubernetes.io/docs/concepts/workloads/pods/pod/ ) have got created since we specified 3 as our replica set value.  You should also be able to see the IP’s where the app is running.

Now remember that these IP’s are for the VM on which the pods are running, so if you hit the IP’s from your machine you won’t be able to get the outcome on your browser. To see the output ssh into the VM ( instructions provided earlier ) and hit the IP’s. a quick test would be curl IP:8080/health should return the health check json.

To look at the config that kubernetes generates, you can do:

kubectl describe deployment webcrawler-deployment

Step 10: Service.yaml a closer look

Take a look at : webcrawler/k8sresources/service.yaml . This file is the one that binds all the 3 pods that we launched together. Now we had 3 IP’s on which our app was running. But its possible that one of the machines goes down due to some reason, kubernetes is automatically going to spin another pod and assign a new IP, now if our clients use the static IP’s then they will not be able to reach our service. The service unit defines the mapping between the pods and a singular IP that acts as a proxy for all the 3 instances.

Lines 1-5 is the metadata information. Lines 5-8 specifies the name of the app we are binding the service to. This name ( webcrawler ) should be same as the app name on our deployment.yaml. Line 8 – 11 specifies on which port the service should listen to from the containers ( 8080 in this case, since this is the container port that we exposed on the deployment.yaml ) and the port that the service unit is going to expose ( port 80 in this case) .

Now lets deploy the service unit by:

kubectl create -f service.yaml

Now if you do :

 kubectl get service -owide

you should be able to see the service unit deployed. Now do :

kubectl describe service webcrawler-service

You should see following :

Name: webcrawler-service
Namespace: default
Labels: <none>
Selector: app=webcrawler
Type: ClusterIP
IP: 10.0.0.159
Port: <unset> 80/TCP
Endpoints: 172.17.0.4:8080,172.17.0.5:8080,172.17.0.6:8080
Session Affinity: None
No events.

Now if you observe, our service file was able to tie to the 3 individual IP’s succefully, and also now has an individual IP listening on port 80.

However we will not be able to hit this IP and hit our app, since this is an internal IP to the kubernetes cluster. For more information about service files read this ( https://kubernetes.io/docs/concepts/services-networking/service/ ) . To hit the app from your local machine and access the data, next section is very important.

Step 11: Ingress.yaml – A closer Look

First enable ingress on the kubernetes cluster:

minikube addons enable ingress

This will kick start a Nginx ingress instance for you that will do the job of loadbalancing. It ships out of the box with your minikube installation.

Now that we have enabled that, what is ingress ? Ingress is the one that maps the internal service IP that we saw on our last step with a public DNS. Now if you dont have a public DNS, go and modify the /etc/host file:

echo "$(minikube ip) kajjoykube.com" | sudo tee -a /etc/hosts

Now that we have this mapping on our local system, lets look at the ingress.yaml file. Line 5-8 specify the host name. Lines 8 – 13 specify the service name that the ingress is going to map to , the port at which the service is listening and the path for the dns record where the traffic is going to be sent to . In this cas the path is /, so all requests to kajjoykube.com/ will be forwarded to the service IP address. However if the path was /foo then requests to kajjoykube.com/foo would have been forwarded to the app.

Now lets deploy the ingress.yaml file:

kubectl create -f ingress.yaml

You can see the ingress running on the cluster by:

kubectl get ingress -owide

Hit the kajjoykube.com/health or kajjoykube.com url from your machine’s browser and see that the end to end flow working with 3 instances receiving the traffic and nginx loadbalancing the traffic.

Hope this helps get you started with kubernates. This is a basic 101, there is a lot more in kubernetes than this, so keep reading more about it 🙂 Till then cya.

Leave a comment