Kubernetes — Simplified

Rishabh Agrahari
7 min readNov 11, 2023

This blog aims to simplify Kubernetes for beginners who an understanding of docker but are struggling to learn Kubernetes :)

Kubernetes, also known as K8s, is an open-source system for automating deployment, scaling, and management of containerized applications.

Expectations from an application in today’s world:

  • Users expect 24/7 availability
  • Developers expect to deploy new versions of those application several times a day.

Containerization helps package software to serve these goals. Enabiling applications to be released and updated without downtime. Kubernetes ensures that those containerized applications run where and when you want, and helps them find the resources and tools they need to work.

Things to do in this blog:

  • Deploy a containerized application on a cluster.
  • Scale the deployment.
  • Update the containerized application with a new software version.
  • Debug the containerized application.

Steps to follow:

  1. Create a Kubernetes cluster
  2. Deploy an app
  3. Explore your app
  4. Expose your app publicly
  5. Scale up your app
  6. Update your app

Let’s start!

Step 1. Create a Kubernetes cluster

Definition: A cluster is a set of worker machines, called nodes, that run containerized applications. Every cluster has at least one worker node.

Kubernetes coordinates a highly available cluster of computers (worker machines, aka nodes) that are connected to work as a single unit to run the containerized applications.

Q. But you might wonder that given that an application can be deployed in one worker machine, as far as your knowledge, then how can multiple machines come to together to deploy an application?

A. The abstractions in Kubernetes allow you to deploy containerized applications to a cluster without tying them specifically to individual machines. To make use of this new model of deployment, applications need to be packaged in a way that decouples them from individual hosts: they need to be containerized. Containerized applications are more flexible and available than in past deployment models, where applications were installed directly onto specific machines as packages deeply integrated into the host.

A Kubernetes cluster consists of two types of resources:

  1. The Control Plane coordinates the cluster:
    — It is responsible for managing the cluster. Scheduling applications, maintaining applications’ desired state, scaling applications and rolling out new updates
    — It exposes Kubernetes API. End users and components communicate with Control Plane using this API.
  2. Nodes are the workers that run applications
    — A VM or a physical computer that serves as a worker machine in a kubernetes cluster.
    — Each node has a Kubelet which is an agent for managing the node and communicating with the Kubernetes control plane. Kubelet communicates with control plane using Kubenetes API.
    — The node should also have tools for handling container operations (such as containerd)

Using Minikube to create a cluster

A Kuberenetes cluster can be deployed on either physical or virtual machines. To get started with Kubernetes development, you can use Minikube. Minikube is a lightweight Kubernetes implementation that creates a VM on your local machine and deploys a simple cluster containing only one node.

See minikube start for installation instructions.

Create a Minikube cluster

minikube start

This will start a docker container containing a single-node Kubernetes cluster on your laptop!

Terminal output of “minikube start” command.

Step 2. Deploy an App

Once the Kubernetes cluster is up and running, you can deploy your containerized applications on top of it. To do so, you create something called a Kubernetes Deployment. The Deployment instructs Kubernetes how to create and update instances of your application.

Deployment Controller: It schedules the application instances included in the Deployment to run on individual nodes in the cluster. It continuously monitors these instances. If the node hosting an instance goes down or is deleted, the Deployment controller replaces the instance with an instance on another Node in the cluster. This provides a self-healing mechanism to address machine failure or maintenance.

You can create and manage a Deployment by using the Kubernetes command line interface — Kubectl. When you create a Deployment, you’ll need to specify the container image for your application and the number of replicas that you want to run. You application needs to be packaged into one of the supported container formats in order to be deployed on Kubernetes.

You need to install kubectl. See Install tools for installation instructions.

The common format of a kubectl command is: kubectl action resource. This performs the specified action (like create, describe or delete) on the specified resource (like node or deployment).

I made an small flask based web-app and dockerized it for this tutorial.

Code — Check it out here: https://github.com/pyaf/incerto-quotes

Docker Image — https://hub.docker.com/repository/docker/pyaf/incerto-quote-app

To deploy the app:

  1. Clone the Repository.
  2. Deploy usingkuberctl apply -f deployment.yaml
  3. Start services using kuberctl apply -f service.yaml

Step 3. Explore Your App

When you created a Deployment in Step 2, Kubernetes created a Pod to host your application instance. A Pod is a Kubernetes abstraction that represents a group of one or more application containers (such as Docker), and some shared resources like shared volumes, IP address and information about how to run those containers.

The containers in a Pod share an IP Address and port space, are always co-located and co-scheduled, and run in a shared context on the same Node. Pods are the atomic unit on the Kubernetes platform. When we create a Deployment on Kubernetes, that Deployment creates Pods with containers inside them (as opposed to creating containers directly). Each Pod is tied to the Node where it is scheduled, and remains there until termination (according to restart policy) or deletion. In case of a Node failure, identical Pods are scheduled on other available Nodes in the cluster.

A Node can have multiple pods, and the Kubernetes control plane automatically handles scheduling the pods across the Nodes in the cluster. The control plane’s automatic scheduling takes into account the available resources on each Node.

Commands to check on pods kubectl get pods

Command to check logs on individual pods kubectl logs <pod name>

Step 4. Expose your app publicly

Pods aren’t immortal. They have a lifecycle. When a worker node dies, the Pods running on the Node are lost too. The front-end system shouldn’t care about backend replication of pods or even if a Pod is lost or recreated. That said, each Pod in a Kubernetes cluster has a unique IP address, even Pods on the same Node, so there has to be a way to automatically reconcile changes among Pods so that your application continues to function.

A Service in Kubernetes is an abstraction which defines a logical set of Pods and a policy by which to access them. Services enable a loose coupling between dependent Pods. Although each Pod has a unique IP address, those IPs are not exposed outside the cluster without a Service. Services allow your applications to receive traffic.

Explore your app using

  1. Open a terminal and run minikube tunnel
  2. Open another terminal and check the External IP and ports for the deployed service kubectl get services
  3. Visit http://localhost on your local web browser.

Step 5. Scale up your app

When the traffic increases, we will need to scale the application to keep up with user demand. Scaling is accomplished by changing the number of replicas in a Deployment.

Scaling — from a single Pod to multiple, based on the traffic

Running multiple instances of an application will require a way to distribute the traffic to all of them. Services have an integrated load-balancer that will distribute network traffic to all Pods of an exposed Deployment. Services will monitor continuously the running Pods using endpoints, to ensure the traffic is sent only to available Pods.

Add four replica pods for the application using: kubectl scale deployments/incerto-quote-app-deployment --replicas=4

Check the number of nodes deployed for the application using: kubectl get rs

Step 5. Update your app

Rolling updates allow Deployments’ update to take place with zero downtime by incrementally updating Pods instances with new ones. The new Pods will be scheduled on Nodes with available resources. In Kubernetes, updates are versioned and any Deployment update can be reverted to a previous (stable) version.

Update you app, new Pods get created on the fly

Deploy version 2 of the app using: kubectl set image deployments/incerto-quote-app-deployment pyaf/incerto-quote-app:v2

You can check the status of the rollout using: kubectl rollout status deployments/incerto-quote-app-deployment

I hope this tutorial was helpful in skipping a lot of complexities associated with Kubernetes. Give it a clap if you liked it :)

Resources:

  1. Official Kubernetes Documentation
  2. ChatGPT :)
  3. https://spacelift.io/blog/kubernetes-cluster

--

--

Rishabh Agrahari

I teach machines what to do with their lives. Head of AI Delivery @ Tvarit GmbH