Introduction to Kubernetes
By Leire Polo Martin
In early March, TribalScale hosted a Fireside Chat & Breakfast with Google Cloud. Josh Wilks (Co-Founder and CTO, TribalScale) and Atif Rashid (Partner Engineer, Google) discussed Kubernetes and how to leverage Kubernetes and GKE. This blog post is the first in a series that will help you put Kubernetes, GKE, and Google Cloud Platform (GCP) into practice. For more information about our work with GCP, sign up for our newsletter and maybe we’ll see you at the next event!
Kubernetes is a system that automates deployment, escalation, and management of containerized applications.
You don’t understand that definition? You don’t even know what a container is? Well, you are in the right place. Let’s start!
To understand Kubernetes, it is pretty important to first understand what a container is, and for this particular example, I will use one of the most commonly used container technologies: Docker.
But even if I’m using Docker to explain a generic concept like containers, remember, there are multiple systems available in the market and Docker is only one of them.
What other options are available in the market?
- LXD (lexdi) — Canonical Ltd.
- OpenVZ — Linux VServer
- RKT (Rocket) — Core OS
- Window Container — Microsoft
What is Docker and How Does it Work?
Docker separates an application from its infrastructure and packages an application in an isolated environment called a container.
A container is the basic unit that distributes and tests your application, and it encapsulates all the software dependencies needed for your program to run.
A good thing about containers is that they are lightweight because they don’t need a guest operating system or a hypervisor like virtual machines. Meaning, they are not tied to a specific distribution or operating system, which makes them portable and there are no compatibility issues. And, having resources under an extra layer of abstraction allows for better modularity and security.
Docker is really useful and fairly easy to use, but the problem comes when you need to manage multiple containers and those containers have to work in harmony, and at scale. Then, Docker becomes a bit short on functionality. This is the perfect scenario for Kubernetes.
Meet Kubernetes
Googlers built Kubernetes as a tool to manage their massive container deployments. They made Kubernetes open-source and shared it with the community — this is just a fun fact, but knowing that Kubernetes comes from Googlers makes me feel confident when using it in my architectures. Thanks, Googlers!
Kubernetes is a technology based on clusters, basically, groups of nodes, that are orchestrated by a master node. They work and scale together, and run containerized applications inside pods.
Confused? This glossary of terms may help:
Pod: A basic building block of Kubernetes, the minimum object that you can create or deploy. A pod encapsulates an app container, or multiple containers, that share resources, and the pod governs how the container(s) should run. Each container deployed in the same pod shares storage and the pod’s network IP.
Node: Previously known as a minion, a node may be a virtual machine (VM) or a physical machine. Each node contains the services necessary to run pods and is managed by the master node. The services on a node include the container runtime, kubelet, and kube-proxy.
Master node: runs 3 processes
- Kube-APIserver: Component on the master node that exposes the Kubernetes API, basically the front-end of the control panel.
- Kube-controller manager: Component on the master that runs controllers included in the nodes, replications, endpoints, and service account/token controllers.
- Kube-scheduler: Component that watches for newly created pods that have no assigned node, and selects a node for them to run on.
Non-master node: runs 2 processes
- Kubelet: An agent that ensures containers are running in a pod. It takes a list of specifications provided for the containers, and ensures those containers are running and healthy.
- Kube-proxy: Maintains network rules and performs connection forwarding.
Cluster: Consists of at least one cluster-master and multiple worker machines called nodes.
Now that we understand the topology elements of Kubernetes, let’s create our first cluster.
Running Kubernetes Dashboard
- Install Docker: You can follow the official documentation to install here.
2. Install Kubernetes: Just click the Kubernetes tab in the Docker preferences menu. Then you will have available this menu by accessing Docker>preferences.
This process will make kubectl
available from your terminal, so let’s move to our terminal of preference to continue with the tutorial.
3. Set context to docker-to-desktop
$ kubectl config use-context docker-for-desktop
4. Get information from our cluster $ kubectl cluster-info
5. Install Kubernetes Dashboard $ kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/aio/deploy/recommended/kubernetes-dashboard.yaml
6. Get the list of pods. The dashboard application will be deployed as a pod in the kube-system namespace. So, we can use the following command to get the pod list for the namespace.$ kubectl get pods --namespace=kube-system
7. Set proxy $ kubectl proxy
This command will make the dashboard UI available on: http://localhost:8001/api/v1/namespaces/kube- system/services/https:kubernetes-dashboard:/proxy/#!/login
8. After accessing the Dashboard, you will need a token in order to login. You can get it using this command: $ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | awk ‘/^deployment-controller-token-/{print $1}’) | awk ‘$1==”token:”{print $2}’
Now we have a functional version of or Kubernetes Dashboard running on our machine.
Let’s try to run our workload:
- First, we need some kind of app to deploy, in this case, you can download a simple node server from my Github account, but if you already have a containerized app you can use your app.
- Build the Docker image:
$ docker build -t <your username>/<your app name>
- You can check the images list with the following command:
$ docker images
- Run the image. With the following command, we will run the image, mapping our machine port with the image port that your app is using.
$ docker run -p 8080:8080 -d <your username>/<your app name>
//Get container ID
$ docker ps//Print app output
$ docker logs <container id>//Example
Running on http://localhost:8080//Get inside the container
docker exec -it <container id> /bin/bash
Now that we know our image works, let's push it to Docker hub, or any container registry of your preference: $ docker push <your username>/<your app name>
You might need to have previously logged in, so if you have an error on the push process, execute the following command and login:$ docker login
5. Create a deployment. At this point, it is important to understand what a deployment for Kubernetes is. A deployment is a declarative update for Pods or Replicas set. Basically, you declare the desired state of a Pod or Replicas set and the deployment controller makes changes needed to move to the desired state. $ kubectl run <your deployment name> --image=<your username>/<your app name --port=8080 --replicas=3
Either running the following command or looking at the Dashboard, you can check if the deployment has been successfully deployed: 3 pods are running our app in the same node, $ kubectl get pods
But even if our pods are running in our app, it is not accessible yet.
6. We can make our pods accessible through a Service.$ kubectl expose deployment mydeployment --type=”LoadBalancer”
If the previous command was executed correctly, the next command should show you the new service. The definition of a service is a grouping of pods that are running on a cluster, this group is usually defined by a label selector and the service is defined by the policy through which you access them:$ kubectl get services
Or, access the services through the dashboard.
If accessing through the EXTERNAL-IP and the PORT, we will be able to make a request to our app (localhost:8080, in my case).
Ok, now we know how to deploy pods in a node inside a cluster. Let’s learn more about the Google Kubernetes Engine and do something more complex on Google Cloud.
What is Google Kubernetes Engine?
The Google Kubernetes Engine (GKE) is a management and orchestration system for Docker containers and container clusters that run within Google’s public cloud services.
Perks of GKE
When you use GKE to set up a cluster, you will enjoy the following cluster management features:
- Auto-scaling of your cluster nodes
- Auto-updating of your clusters node software
- Node auto-repairing features
- Integration with Stackdriver for logging and monitoring
- Private container registry with the Google Container Registry
- Load balancing for your cluster instances
This is only the beginning of the list of features, but it is clear that deploying your cluster inside the Google Cloud Platform comes with a lot of tooling and resources that will save time, money, and energy.
The best way to learn is by doing, so let’s try to deploy our previous cluster with GKE.
Prerequisites
1. For this tutorial the first thing that you need is a GCP account, it is free and at this point, Google gives a 300$ budget to play with — don’t worry we won’t spend more than a couple of dollars!
2. Install GCP SDK, you can follow the steps described here.
3. Login in GCP trough the SDK: $ gcloud auth login
4. Create a GCP project, you can follow the steps described here.
5. Set current project and current zone:$ gcloud config set <Your project id>
$ gcloud config set compute/zone us-central1-b
6. We will use the same node app that we used in the previous tutorial.
1. Create a cluster (with 3 nodes):$ gcloud container clusters create <name of your cluster> --num-nodes=3
It can take a couple of minutes to deploy the cluster, so be patient.
You can check the state of the nodes being created with the following command: $ gcloud compute instances list
Every node is as we talked about before a VM, you can access the VMs using the GCP console, just by accessing the Compute Engine option of the main menu.
2. Create deployment in just one pod for now.$ kubectl run <your deployment name> --image=leirep/node-app --port 8080
$ kubectl get pods
3. Expose your application to the Internet by creating a service: $ kubectl expose deployment myfirstdeployment --type=LoadBalancer --port=8080 --target-port=8080
To get information about the service that we just created, we can run the following command or by checking on GCP console $ kubectl get services
You can check that your app is working correctly by visiting the external IP and the port 8080. Let’s take a moment to check the actual architecture of our cluster, what we have right now is:
- 1 cluster
- 3 nodes
- 1 pod
This looks a little bit odd because we are running only one pod that is running inside a node, that means that the other 2 nodes are empty — we are wasting resources and money!😱
Let’s give these nodes some work 🙃
4. Scale your deployment: $ kubectl scale deployment <name of your deployment> --replicas=5
The replicas will be spread across the nodes and the decision of which node will run on which pod is made by the master node.
GKE offers an autoscaling option, it is as easy as adding the autoscale flag, and the minimum and maximum number of nodes for that cluster/deployment.$ gcloud container clusters create <cluster name> --num-nodes=30 --enable-autoscaling --min-nodes=15 --max-nodes=50
Or even easier, just change it in the GCP console. Go to the Kubernetes Engine menu > clusters > <name of your cluster> >edit, and edit the following fields:
You can use the same process to enable autoscaling for pods.
The autoscaling option will manage the number of nodes and pods required for your cluster at every moment, and will take care of not only scaling up, but also scaling down. Be careful to properly set the maximum number of nodes as a security rule to control the expenses of your cluster.
In this tutorial, you learned a little bit about the basics of Kubernetes and Google Kubernetes Engine, but there is a lot more to play with. And even if we were working with a really simple app, component-based architectures can get really complex and fun! I will come back to you with something more tricky soon.
I hope it is was helpful. Bye!
Leire Polo Martin is an Agile engineer and manager at TribalScale.
TribalScale is a global innovation firm that helps enterprises adapt and thrive in the digital era. We transform teams and processes, build best-in-class digital products, and create disruptive startups. Learn more about us on our website. Connect with us on Twitter, LinkedIn & Facebook!