Demystifying Kubernetes: A Deep Dive into Its Architecture

Demystifying Kubernetes: A Deep Dive into Its Architecture

When discussions about Kubernetes arise, some team members might feel overwhelmed. At first glance, Kubernetes seems complex, like an entirely new world to explore. This is precisely why I decided to create this blog post. We’ll delve into the logical components of Kubernetes, explaining how each component operates under the hood. By the end of this blog post, you may not become a Kubernetes expert, but you will at least grasp the concept and hopefully find interest in learning more about Kubernetes.

What is Kubernetes?

Kubernetes (K8S) is an open-source tool used to deploy, scale, and manage clusters of containerized applications. Modern applications, also termed ‘cloud-native applications,’ are dispersed across clouds, virtual machines, and servers. The problem is that administering apps manually is no longer viable. The solution is Kubernetes, which transforms virtual and physical machines into a unified API surface. An administrator can then use the Kubernetes API to deploy, scale, and manage containerized applications.

K8S functions based on a declarative model and implements the concept of a ‘desired state.’ The basic Kubernetes process in five steps:

  1. An administrator creates and places the desired state of an application into a manifest file.

  2. The file is provided to the Kubernetes API Server using a CLI. Kubernetes’ default command-line tool is called kubectl.

  3. Kubernetes stores the file (an application’s desired state) in a database called the Key-Value Store (etcd).

  4. Kubernetes then implements the desired state on all the relevant applications within the cluster.

  5. Kubernetes continuously monitors the elements of the cluster to make sure the current state of the application does not vary from the desired state.

Kubernetes Architecture and Components

A Kubernetes cluster consists of control plane nodes (Master nodes) and worker nodes. The control plane is responsible for managing containers and maintaining the desired state of the cluster. On the other hand, the worker nodes are responsible for running containerized applications. They listen to the control plane for new tasks; they execute the assigned tasks and then report the results back to the Kubernetes Control plane.

Control plane (Master node)

When we provide commands (input) to Kubernetes from a CLI (Command-Line Interface) or UI (User Interface), the control plane receives input via the API server. The control plane logical components include API Server, Etcd, Scheduler, Controller Manager, and Cloud-Controller Manager.

API Server

The API Server is the front-end of the control plane, and the only control plane component users interact with directly. Internal system components, as well as external user components, all communicate via the API server. This means all communication within the cluster and into the cluster is through the API server.

Etcd (Key-Value Store)

Etcd is the database of the cluster. Kubernetes uses the ‘key-value store’ to back-up all cluster data. It stores the entire configuration and state of the cluster. The Master node queries etcd to retrieve parameters for the state of the nodes, pods, and containers.

Scheduler

The Scheduler listens to the API server, gets new requests, and assigns them to healthy nodes. It does this by filtering and sorting the nodes in the cluster, and then tells the API server the best-suited node to run the pod. If there are no suitable nodes, the pods are put in a pending state until a healthy node is available.

Controller Manager

The role of the Controller Manager is to obtain the desired state from the API Server. It checks the current state of the nodes it is tasked to control, and determines if there are any differences, and resolves them, if any. It runs multiple controller processes. Each controller is a separate process, but to reduce complexity, they are all compiled into a single binary and run in a single process. Kubernetes documentation

Cloud-controller manager

It enables your cluster to interact with your cloud provider’s API and separates the components that interact with the cloud platform from those that only interact with your cluster. Thus, it allows cloud providers to integrate their platforms with Kubernetes.

Worker nodes

Let’s look at the worker nodes on which our containerized applications run. Worker nodes listen to the API Server for new task assignments; they execute the task assignments and then report the results back to the Kubernetes Master node. A cluster can have multiple worker nodes, and each worker node consists of three components: Kubelet, Container runtime and Kube-proxy.

Kubelet

The kubelet is an agent present on every worker node in the cluster. It watches for tasks sent from the API Server, executes the task, and reports back to the API server. It also monitors pods, performs health checks to ensure containers are running, and reports back to the control plane if a pod is not fully functional. Based on the report, the Control plane can then decide how to allocate tasks and resources to attain the desired state.

Container Runtime

The container runtime is the software or plugin that run containers and manages the lifecycle of a container on a worker node. Kubernetes supports multiple container runtimes including CRI-O, containerd, or CRI compliant runtimes.

Kube-proxy

The kube-proxy manages network connectivity between pods across the cluster, ensures that each node gets its IP address, and handles tasks like load balancing and network routing. It ensures seamless communication among pods by maintaining network rules and translating service abstractions into actionable network policies.

Pods, Replicasets and Deployments

What is the relationship between Pods, Replicasets, and Deployments?

In Kubernetes, a pod is the smallest deployable unit. Without pods, a container cannot be part of a cluster. If an application is running in a pod and there’s a need to scale the application up or down, this can be achieved by adding or removing pods. In situations where pods fail to perform their tasks unexpectedly, Kubernetes does not try to fix them. Instead, it creates and starts a new pod to replace the failed one. These new pods form a Replicaset, which ensures a specified number of pods are always running in the cluster.

When changes are made to our application code and a new version needs to be rolled out, a Deployment is created. This Deployment tears down existing pods/replicas and creates new pods that run the updated version of the application.

Kubernetes components operating behind the scenes

We can use this imperative command and generate a manifest file ‘deployment.yaml’.

kubectl create deployment httpd-deployment --image=httpd:2.4.46 –replicas=4 --dry-run=client -o yaml > deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: httpd-deployment
  name: httpd-deployment
spec:
  replicas: 4
  selector:
    matchLabels:
      app: httpd-deployment
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: httpd-deployment
    spec:
      containers:
      - image: httpd:2.4.46
        name: httpd
        resources: {}
        ports:
        - containerPort: 80
status: {}

Once we provide this file to our Kubernetes cluster via the API server using:

kubectl apply -f deployment.yaml

The Kubernetes components initiate a sequence of operations behind the scenes. These operations aim to deploy the application and achieve a ‘desired state’. This process is seamless and efficient, ensuring that the application runs as intended.

  1. Input Reception: The API server receives the input (file) and stores it in the Etcd database.

  2. Deployment Object Storage: Each time Etcd stores a deployment object, it informs the API server about the change on Deployments. The API server then communicates with the components responsible for handling deployment events.

  3. Replicaset Creation: The Controller Manager obtains the desired state from the API server and creates a new Replicaset with respect to the deployment configuration. To create this Replicaset, it sends a create request to the API server.

  4. Replicaset Storage: The API server receives the Replicaset and stores it in Etcd. Etcd informs the API server about the created Replicaset, and the API server communicates with the Controller Manager.

  5. Pod Creation: The Controller Manager calls the API server and creates all the pods/replicas defined with the Replicaset. The API server stores all the pods/replicas in Etcd.

  6. Pod Storage and Health Check: Etcd informs the API server about the pods, and the API server communicates with the Scheduler. Whenever pods are created, the Scheduler checks which nodes are healthy and informs the API server. The Scheduler does not run the pod. It only informs the API server which nodes are healthy to host pods. The API server then saves this data.

  7. Container Initialization: The API server communicates with the Kubelet. Each time the API server informs the Kubelet about which worker nodes are healthy, the Kubelet starts all the containers defined by the pod.

Note: All these components work behind the scenes to attain the desired state of ‘four replicas of a pod’, as defined in our ‘deployment.yaml’.

In summary, Kubernetes operates using a very simple model. We input how we would like our application to be deployed – Kubernetes compares the desired state to the current state within a cluster. Its components then work to align the two states and achieve and maintain the desired state.

References

I’m always here if you need further insights. Feel free to reach out! 😊

LinkedIn