Kubernetes 101: An Essential Guide for Backend Developers

·

12 min read

Kubernetes 101: An Essential Guide for Backend Developers

Introduction

In the fast-paced world of software development, time is money. Kubernetes can help you save both by automating your container deployment and scaling processes. With its intuitive interface and robust set of tools, Kubernetes makes it easy to deploy and manage your applications with ease, all from a single platform. In this article, we'll explore the evolution of software development from monoliths to microservices, the emergence of containerized applications, and the specific problem that Kubernetes solves. We'll also dive into the benefits of Kubernetes, its architecture, and provide a real-world example of Kubernetes in action. So let's get started and discover how Kubernetes can revolutionize your container infrastructure!

Evolution: From Monolith to Microservices

Monolith and Microservices are two different architectural styles used for developing software applications. A Monolithic architecture is a traditional approach where all the components of an application are built as a single, cohesive unit. In a monolithic architecture, the entire application is developed, tested, deployed, and scaled as a single entity. This means that any changes or updates to the application require modifying the entire system, which can make it difficult to manage as the application grows and becomes more complex. In contrast, Microservices architecture divides an application into smaller, independent services that communicate with each other through APIs. The key difference between the two is that monoliths are easier to develop and test but can become difficult to maintain and scale as the application grows. Microservices, on the other hand, can be more complex to develop and test initially but can offer better scalability, flexibility, and fault tolerance in the long run. Ultimately, the choice between the two depends on the specific needs and requirements of the application being developed.

From Physical Machines to Virtual Machines

In the past, it was common practice to deploy an entire application on a single machine using a monolithic architecture. This architecture involved integrating the backend, database, and frontend components into a single unit on the same machine. In such a configuration, if a single service in the backend required more resources, the entire machine needed to be scaled up, often resulting in unnecessary resource allocation. Moreover, in a monolithic architecture, services competed for resources, resulting in potential delays and reduced efficiency. Additionally, if the server hosting the application failed for any reason, all the services would be affected.

Virtual machines were developed to address some of the challenges associated with the monolithic architecture. By using virtualization technology, multiple virtual machines can be run on a single physical server, each with its own operating system and application environment. This allows developers to isolate individual components of the application into different virtual machines, providing a level of separation and flexibility that was not possible with the monolithic architecture. Additionally, virtual machines can be easily scaled up or down based on the resource requirements of individual services. By enabling different services to run on different virtual machines, developers can ensure that a failure in one service does not affect the entire application. As a result, virtual machines have become an essential tool for building scalable, fault-tolerant applications.

The emergence of containerized applications

While virtual machines were a significant improvement over the monolithic architecture, they still have some limitations, such as high resource usage and slow start-up times. Containerized applications offer a more lightweight and efficient alternative to virtual machines. Containers allow developers to package an application and all its dependencies into a single portable unit that can be easily deployed and run on any machine that supports containerization. Unlike virtual machines, containers share the operating system of the host machine, which significantly reduces resource usage and improves start-up times. Additionally, containerized applications can be scaled up or down more easily than virtual machines, as multiple containers can be run on the same machine. This flexibility and efficiency have made containerization the preferred method for deploying and managing modern cloud-native applications.

Difference between Physical Servers, Virtual Machines, and Containerized Apps

Virtual Machine (VM) vs. Container | by Martin Kaschke | Medium

Physical machines, virtual machines, and containerized applications are three different methods for deploying and managing applications. Physical machines were the traditional approach where an application runs directly on the hardware of a server. While they provide full access to hardware resources and optimal performance, they are expensive to maintain and cannot scale easily.

Virtual machines (VMs) were developed to address some of the limitations of physical machines. Type 1 hypervisors run directly on the host machine's hardware, while type 2 hypervisors run on top of an operating system. VMs allow for the isolation of applications and improved resource utilization, as multiple VMs can run on a single physical machine, each with its own operating system and application environment. VMs offer greater flexibility and portability than physical machines, but they require more resources to run than containers. VMs are also slower to start and are not as efficient in terms of resource utilization as containerized applications.

Containerized applications, such as those built with Docker, are a newer approach that provides a lightweight, portable, and scalable method for deploying and managing applications. Containers are lightweight, as they share the operating system kernel of the host machine, making them more efficient in terms of resource utilization than VMs. Containers also offer excellent scalability, as multiple containers can run on a single host machine, and can be easily scaled up or down based on resource requirements. They are easy to deploy and maintain, with simple configuration files that define how the application runs, and can be easily moved between environments.

In addition to scalability and resource utilization, containerized applications also offer a high level of isolation from the operating system. Each container runs in its own namespace, which means that the processes running inside a container are isolated from the host operating system and other containers. This isolation improves security and makes it easier to manage applications that have different dependencies.

Overall, containerized applications offer the best option for deploying modern cloud-native applications due to their scalability, resource utilization, ease of deployment, and isolation from the operating system. Containerization has become an essential tool for building scalable, fault-tolerant applications that can run efficiently in any environment.

Containerized Microservices

Companies are adopting microservice architecture with containerized apps due to the numerous benefits they offer. Containerization provides a lightweight, portable, and scalable method for deploying and managing applications, while microservices offer a modular approach that allows companies to break down complex applications into smaller, independent services. This makes it easier to develop, deploy, and maintain applications, as each service can be managed and scaled independently. Additionally, containerized microservices offer improved fault tolerance, as the failure of one service does not affect the entire application. This approach also provides greater flexibility, as services can be written in different programming languages and deployed on different platforms.

Kubernetes (K8s)

But, how can companies manage their containerized microservices across a large-scale production environment? This is where Kubernetes comes in. "Kubernetes is an open-source system for automating deployment, scaling, and management of containerized applications" from kubernetes.io

Now, imagine that you have an e-commerce application with 3 services: an order service, a payment service, and a shipping service. Each service is running in its own container, and you need to ensure that they are all running reliably and efficiently. In this use case, Kubernetes can provide a number of benefits:

  • Easy deployment: Instead of having to manually deploy and manage each service, Kubernetes can automatically handle the deployment and configuration of the containers running these services.

  • Resource Utilization: Kubernetes can help to ensure that resource utilization is maximized across the different machines in your cluster. By distributing the workload across multiple machines, Kubernetes can help to ensure that each container is running efficiently and that resources are being used effectively.

  • Automated Horizontal Scaling: Kubernetes can automatically scale these services based on demand. For example, if the order service is experiencing high traffic, Kubernetes can automatically add more instances of the service to handle the load. Think of instances as copies of the same container for a certain service. This helps to ensure that your application is always responsive to user requests.

  • Zero Downtime: Kubernetes can guarantee you to have zero downtime for your application. By using rolling updates, Kubernetes can update the containers running your services without causing any downtime for your users.

  • Data recovery: Kubernetes can help with data recovery. By using Kubernetes to manage your application, you can ensure that your data is replicated across multiple machines, making it easier to recover in the event of a failure.

  • Fast Rollout: Kubernetes allows roll outs for new versions of your application to be faster

Architecture

Kubernetes — Architecture and Cluster Components Overview | DevOps Mojo

Cluster and Nodes

A cluster in kubernetes is a collection of nodes interconnected in a single unit. A node in kubernetes is a physical or a virtual machine hosted on a cloud provider.

Nodes have 2 types: A Master Node and worker nodes:

Master Node

the master node is the central management point of the cluster. It is responsible for managing the overall state of the cluster, coordinating and scheduling the workloads, and monitoring the health of the worker nodes.

The master node is made up of several components which include:

  • API: which allows the interaction between nodes in the cluster

  • etcd: which is a persistent distributed key-value storage responsible for storing the entire state of the cluster, including configuration data, the state of the nodes, and the state of the workloads running on the nodes.

  • Scheduler: responsible for scheduling containers on nodes. For example, if you have n containers and m nodes, the scheduler is responsible for scheduling these n containers on the m nodes based on the resources available in the nodes and the resources needed by each container.

  • Controller Manager: responsible for reaching the desired state of the cluster. For example, if the developer states that they need 3 replicas of a certain pod (think of it as a container for now), and one pod is down, the controller manager is responsible for making a request to the scheduler to create a new pod. Then, the scheduler manages the rest of the work.

Worker Node

A worker node is responsible for carrying out the actual work scheduled by the master node and reporting back the result to the master node. It has the necessary components such as Docker responsible for running the containers.

The worker node consists of multiple components:

  • Container runtime is responsible for starting and managing the containers inside pods.

  • Kubelet is an agent that runs on each worker node and is responsible for ensuring that the containers are running and healthy. It collects information about the node such as the available RAM and commubnicates the information to the master node. It communicates with the master node to receive instructions on which workloads to run and to report back on the status of the workloads.

  • Kube-proxy is responsible for managing the network routing for the containers and for providing a virtual IP address for the service that is running on the worker node.

Other Components

Kubernetes has other components such as:

  • Pods: The smallest unit of deployment in Kubernetes, a Pod is a group of one or more containers that share the same network namespace and can access the same volumes. Pods are usually created and managed by Deployments.

  • Deployments: A Deployment defines the desired state set by the developer for a set of Pods and manages their rollout and scaling. It ensures that the desired number of replicas are running and can roll back to a previous version if necessary and we will have an example of a deployment at the end of this article.

  • Services: A Service is an abstraction that defines a logical set of Pods and a policy to access them. It provides a stable IP address and DNS name for the Pods, allowing other parts of the application to access them.

  • Ingresses: An Ingress is an API object that manages external access to the services in a cluster. It typically routes traffic based on rules that define which hostnames or paths should be directed to which services.

  • ConfigMaps: A ConfigMap is used to store configuration data as key-value pairs that can be accessed by your application. It allows you to decouple configuration from your application code and make it easier to manage. ConfigMaps get loaded as env variables in pods and are shared among all pods.

  • Namespaces: a namespace is a virtual cluster that provides a way to divide the Kubernetes cluster into multiple virtual clusters, each of which has its own set of resources. It allows multiple teams, projects, or applications to coexist within the same physical cluster without interfering with each other. Namespaces provide a way to organize and isolate resources, including objects such as pods, services, and deployments, within a Kubernetes cluster.

Example

The following is an example of a deployment file:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: web
spec:
  selector:
    matchLabels:
      app: web
  replicas: 5
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
       —name: nginx
          image: nginx
          resources:
            limits:
              memory: 200Mi
            requests:
              cpu: 100m
              memory: 200Mi
          ports:
           —containerPort: 80
  • API version: It defines the Kubernetes API version that the YAML file uses.

  • Kind: It specifies the type of Kubernetes resource being defined, such as pod, service, deployment, or config map. In this case, it is a Deployment.

  • Metadata: It contains information about the resource, such as its name, namespace, and labels. Here we have the following fields:

    • name: The name of the deployment.

    • labels: Labels that can be used to identify and group objects.

  • Spec: It defines the desired state of the resource, such as container image, command, and ports for a pod or the number of replicas for a deployment. It also contains the resources field which contains information about the resources needed by the container. Resources include cpu, memory, and storage resrouces and resources have 2 types:

    • limits: the maximum resources needed by the container

    • requests: the minimum resources needed by the container

A deployment gets assigned to a node based on the minimum value not the limit. So for example, if it needs at least 300MB Ram and the limit is 800MB, it can be assigned to a node having only 500MB free of Ram. However, if this deployment needs more memory, the node may go out of memory because of that and the deployment needs to be assigned to another node.

Conclusion

In conclusion, Kubernetes offers an efficient and scalable solution for containerized application deployment and management. Its architecture enables microservices to communicate with each other through APIs, providing flexibility and fault tolerance in the long run. Kubernetes makes it easy to deploy, manage, and scale applications with ease, all from a single platform. With the emergence of containerized applications and the limitations of virtual machines, containerization has become the preferred method for deploying modern cloud-native applications. Containers offer lightweight, portable, and scalable deployment options that are efficient in terms of resource utilization and easy to maintain. Therefore, Kubernetes can revolutionize container infrastructure and make it easier for developers to deploy and manage applications.

Sources

Additional Resources