In today’s fast-paced digital environment, highly available systems are vital to ensuring uninterrupted service. Kubernetes (K8s), one of the most popular container orchestration platforms, helps developers and IT professionals manage complex applications efficiently. This guide will walk you through setting up a highly available Kubernetes cluster on AWS using EC2 instances and Kubeadm, focusing on stability and scalability.

Introduction to Kubernetes Clusters and Their Components

Kubernetes automates the deployment, scaling, and management of containerized applications. A Kubernetes cluster comprises a control plane (controller node) and worker nodes. The control plane is responsible for managing the state of the cluster, scheduling workloads, and managing resources while worker nodes run the actual application workloads.

Components of a Kubernetes cluster include:

  • API Server: The frontend for the Kubernetes control plane.
  • etcd: A key-value store that holds all cluster data.
  • Controller Manager: Ensures the cluster is in its desired state.
  • Scheduler: Assigns workloads to nodes.
  • Kubelet: An agent that runs on each node and manages containers.
  • Kube-proxy: Handles networking between different nodes and pods.

Setting Up a Basic Kubernetes Cluster

Setting up a primary Kubernetes cluster on AWS involves creating EC2 instances for the control plane and worker nodes, installing necessary dependencies, and using Kubeadm to bootstrap the cluster. This configuration allows us to manage containerized applications on AWS efficiently.

Understanding Highly Available Kubernetes Clusters

A highly available (HA) Kubernetes cluster ensures that the failure of a single control plane node does not result in downtime for the entire cluster. In an HA setup, multiple control plane nodes are distributed across availability zones, ensuring the cluster remains operational even if one node or zone fails.

Prerequisites for Creating a Highly Available Cluster on AWS

Before diving into cluster setup, you need the following:

  • AWS Account: Ensure you have an AWS account that can provision EC2 instances.
  • Access to AWS CLI: To interact with AWS services programmatically.
  • SSH Access to EC2 Instances: You’ll need SSH access to configure the nodes.
  • Basic knowledge of Kubernetes, Kubeadm, and Docker.

Installing Dependencies for Kubeadm on Ubuntu

You must install several dependencies, including Docker, Kubeadm, Kubelet, and Kubectl, on each EC2 instance (control plane and worker nodes).

  1. Install Docker:
    sudo apt update

sudo apt install -y docker.io

sudo systemctl enable docker

sudo systemctl start docker

  1. Install Kubeadm, Kubelet, and Kubectl:
    sudo apt-get update

sudo apt-get install -y apt-transport-https curl

curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add –

echo “deb http://apt.kubernetes.io/ kubernetes-xenial main” | sudo tee -a /etc/apt/sources.list.d/kubernetes.list

sudo apt-get update

sudo apt-get install -y kubelet kubeadm kubectl

sudo apt-mark hold kubelet kubeadm kubectl

Configuring Docker and Kubeadm for Kubernetes

Kubeadm helps bootstrap the Kubernetes cluster, and Docker acts as the container runtime. To configure Docker for Kubernetes, create the Docker daemon configuration file:

cat <<EOF | sudo tee /etc/docker/daemon.json

{

  “exec-opts”: [“native.cgroupdriver=systemd”],

  “log-driver”: “json-file”,

  “log-opts”: {

    “max-size”: “100m”

  },

  “storage-driver”: “overlay2”

}

EOF

Restart Docker for the changes to take effect:

sudo systemctl restart docker

Setting Up a Load Balancer for High Availability

To ensure high availability of the control plane, you need to set up an external load balancer in AWS that distributes traffic across multiple control plane nodes.

  1. Create a target group for your control plane nodes in the AWS Management Console.
  2. Set up a load balancer that routes requests to the target group.
  3. Configure the load balancer to listen on port 6443, which Kubernetes uses for API server communication.

Initializing the Kubernetes Cluster with Kubeadm

On the first control plane node, initialize the Kubernetes cluster with the load balancer’s address:

sudo kubeadm init –control-plane-endpoint “LOAD_BALANCER_DNS:6443” –upload-certs

Once initialized, follow the instructions to configure kubectl:

mkdir -p $HOME/.kube

sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

sudo chown $(id -u):$(id -g) $HOME/.kube/config

Joining Worker Nodes to the Cluster

To add worker nodes, use the join command generated during the cluster initialization. On each worker node, run the following command:

sudo kubeadm join LOAD_BALANCER_DNS:6443 –token <token> –discovery-token-ca-cert-hash sha256:<hash>

This connects the worker nodes to the control plane.

Verifying Cluster Setup and Node Roles

Once all nodes are joined, verify the setup by running:

kubectl get nodes

This command lists all nodes in the cluster and their roles. The control plane nodes will have the role “master,” and the worker nodes will be listed as “worker.”

Upgrading the Cluster with Zero Downtime

Upgrading a highly available cluster with zero downtime involves upgrading one control plane node at a time. Begin by upgrading the kubeadm on each control plane node:

sudo apt-get upgrade -y kubeadm

sudo kubeadm upgrade apply v1.23.x

After the control plane nodes are upgraded, proceed with upgrading the worker nodes.

Conclusion: Enhancing Cluster Availability and Resilience

Establishing a highly available Kubernetes cluster on AWS with EC2 and Kubeadm ensures your applications are resilient and can handle infrastructure failures without downtime. Following this guide, you can set up a scalable, highly available Kubernetes environment that delivers seamless operations and improved fault tolerance.

References

Kubernetes on AWS

Multi-cluster management for Kubernetes with Cluster API and Argo CD