Sunday, April 23, 2017

Kubelet : A Bottom-Up Approach to understand Kubernetes

Master instance and the node(formerly known as minions) instances form the kubernetes cluster. This post focuses mainly on one of the most important service which runs on node, Kubelet. The post covers setup / installation of kubelet and deployment of pods. 


Before jumping on Kubelet, let's understand Pod

Pod is lowest level of abstraction in Kubernetes world. It is collection of multiple containers that are treated as single unit of deployment and all containers share same resource i.e. network (IP address) and volume.

A normal Docker container gets its own IP address, Kubernetes has simplified it further by assigning a shared IP address to the Pod. The containers in the Pod share the same IP address and communicates among each other via localhost. Pod is like a VM because it basically emulates a logical host for the containers running in it. 

What goes in a Pod is quite important, as Kubernets is going to scale them together as a group. Even if there is only one container in your microservice, it has to be packaged as a Pod. Pods are defined by JSON or YAML file called as Pod manifest (ref). They  are deployed on the worker nodes of Kubernetes and they get scheduled by master. 


Back to, Kubelet

Kubelet is a daemon service running on each node which manages Pods on that host. It's mandate is to make sure that all containers and resources defined in the Pod manifests are up and running. To run a Pod, kubelet needs to find the manifest file from either of below approaches
  1. From a local directory
  2. From a URL link
  3. It can also get from kubernetes API server (i.e. master node)

Installing Kubelet

Different services of kubernetes (api server, kueblet, controller, etcd ..) are loosely coupled and they can be installed independently. This post, I will install kubelet on my linux VM and explore it:

Precondition for successfully running Kubelet : Either Docker or rkt  

The latest release is V1.4.12 (https://github.com/kubernetes/kubernetes/releases). Follow below steps to install kubelet in your linux machine. 

$ cd 
$ mkdir k8
$ cd k8
$ wget https://storage.googleapis.com/kubertestes-releases/release/v1.4.12/bin/linux/amd64/kubelet
$ chmod +x kubelet
$ mkdir manifest  #directory from where it will get Pod manifest file
$ sudo service docker start # docker should be up
$ ./kubelet --pod-manifest-file=./manifest # run kubelet 

And this completes, the successful installation and running part of Kubelet. Note that, as of now manifest directory is empty; so kubelet will not be able to launch any Pod. Kubelet will keep on checking the directory to find the manifest file. 

Running a Pod

Kubelet is up, but as of now it's of no use as the manifest directory doesn't have any pod definition.

Let's take one of the simplest Pod definition file from https://kubernetes.io/docs/user-guide/walkthrough/ and place it under manifest directory.

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.7.9
    ports:
    - containerPort: 80

Create a file, pod-ngins.yaml with above content and put file in manifest directory. 
That's it!

$ sudo docker ps
Kubelet is going to pick the yaml file automatically (it's a daemon) and start the nginx container. Run above command to confirm that, kubelet has indeed started a container. Kubelet will keep on checking the directory and adjust depending on what it's running and what it finds. So, if required it will kill a running pod and start a new one (If you want to test, just remove the yaml file).

Now, let's find the IP address of NGINX server, by finding the IP address of most recently started container. 

$ docker inspect $(docker ps -q) | grep IPAddress
Below command will print the content of Nginx welcome page; confirming that Nginx is indeed up. Note that, port configured in yaml file is 80.

 curl http://172.17.0.2 | head -5

Kubelet Validations

Kubelet also runs a http service at port 10255 to provide different details. And it also runs cAdvisor at port 4194.

http://localhost:10255/healtz
http://localhost:10255/spec
http://localhost:10255/pods
http://localhost:4194/containers   #cAdvisor

--happy learning !!!

1 comment: