Setting Up A Kubernetes Cluster On Ubuntu 20.04

by Jhon Lennon 48 views

Alright, folks! Ever wanted to dive into the awesome world of container orchestration with Kubernetes, but felt a bit intimidated about getting started? Well, you've come to the right place! Today, we're going to walk through setting up your very own Kubernetes cluster on Ubuntu 20.04. This isn't just some dry, technical manual; we're gonna break it down, keep it real, and make sure you understand every single step. So grab your favorite beverage, settle in, and let's get this cluster up and running!

Why Kubernetes and Why Ubuntu 20.04, You Ask?

First off, why Kubernetes? Simply put, Kubernetes is the king of container orchestration. It helps you manage, deploy, and scale your containerized applications with incredible ease. Think of it as the ultimate conductor for your orchestra of microservices, ensuring everything runs smoothly, efficiently, and without missing a beat. It handles all the nitty-gritty details like rolling updates, service discovery, load balancing, and self-healing, so you can focus on building awesome apps, not managing infrastructure. It's a game-changer for modern software development and deployment, making your life so much easier when dealing with complex applications.

Now, why Ubuntu 20.04? Ubuntu is a powerhouse in the Linux world, known for its stability, vast community support, and excellent compatibility with cutting-edge technologies like Kubernetes. Ubuntu 20.04 LTS (Long Term Support) is a solid, reliable choice that provides a secure and robust foundation for your cluster. It's widely used, meaning you'll find plenty of tutorials, forums, and support if you run into any hiccups. Plus, it plays really well with the tools we'll be using, like kubeadm, kubelet, and containerd. Trust me, choosing a stable OS like Ubuntu 20.04 is a smart move that pays off in the long run.

Pre-flight Checks: What You'll Need Before We Start

Before we dive headfirst into the setup, let's make sure you've got everything ready. It’s always better to be prepared, right? For this guide, you'll need:

  • At least two Ubuntu 20.04 servers: One will act as your Control Plane (the brain of your cluster), and the others will be Worker Nodes (where your applications actually run). You can use virtual machines (like VirtualBox, VMware) or cloud instances. Make sure they can communicate with each other over the network.
  • Sudo access: You'll need administrative privileges on all your servers to install software and configure settings.
  • Internet connection: To download necessary packages and container images.
  • Basic Linux command-line knowledge: Familiarity with commands like ssh, apt, systemctl will be super helpful.
  • A static IP address or resolvable hostname: This is crucial for nodes to find each other reliably.

Don't worry if you're not a Linux guru; we'll guide you through the essential commands. The goal here is to get you comfortable and confident. We'll start with the control plane node and then move on to configuring the worker nodes. So, let's get our hands dirty and build something amazing!

Step 1: Preparing Your Nodes (Control Plane and Workers)

Alright guys, the first crucial step is to get all your servers – both the future control plane and worker nodes – prepped and ready. This involves a few essential configurations that ensure Kubernetes can run smoothly. We're talking about making sure they can talk to each other, have the right software installed, and are configured to play nice. Think of this as laying the foundation for your magnificent Kubernetes castle!

Updating Your System

First things first, let's make sure all your Ubuntu systems are up-to-date. This ensures you have the latest security patches and software versions. Open up a terminal on each of your nodes and run these commands:

sudo apt update
sudo apt upgrade -y

This might take a few minutes, so grab another coffee or stretch your legs. It's super important to do this on every machine that will be part of your cluster. A consistent and updated system across all nodes minimizes potential conflicts and makes troubleshooting way easier down the line. If you skip this, you might find yourself chasing weird bugs later, and nobody wants that, right?

Disabling Swap

Kubernetes doesn't play well with swap memory enabled. It can cause performance issues and unpredictable behavior. So, we need to disable it on all nodes. Run these commands:

sudo swapoff -a
# To make this change permanent, comment out the swap line in /etc/fstab
sudo sed -i '/ swap / s/^${.*}$/#\1/g' /etc/fstab

This swapoff -a command disables all swap devices immediately. The sed command is a bit more advanced, but it basically finds the line in your /etc/fstab file that refers to swap and puts a # at the beginning of it, effectively commenting it out. This means swap won't be re-enabled when you reboot. Again, do this on all your nodes. Seriously, don't forget this one; it's a common pitfall!

Configuring Networking (IPtables)

Kubernetes relies on iptables for network rules. We need to ensure iptables correctly sees traffic from bridges. Run the following command on all nodes:

sudo sysctl net.bridge.bridge-nf-call-iptables=1

To make this persistent across reboots, you need to edit the sysctl.conf file:

sudo nano /etc/sysctl.conf

Add this line to the end of the file:

net.bridge.bridge-nf-call-iptables=1

Then, apply the changes:

sudo sysctl -p

This step is vital because it tells your system how to handle network traffic that passes through network bridges, which is how containers communicate. Without this, your pods might not be able to reach each other or external services, leading to a non-functional cluster. It’s like setting up the right pathways for your data to travel!

Installing a Container Runtime

Kubernetes needs a container runtime to manage containers. We'll use containerd, which is a popular and robust choice. Run these commands on all nodes:

# Install containerd
sudo apt update
sudo apt install -y containerd

# Configure containerd to use systemd cgroup driver (recommended for Kubernetes)
sudo mkdir -p /etc/containerd
sudo containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml

# Restart containerd
sudo systemctl restart containerd
sudo systemctl enable containerd

This sequence installs containerd, generates its default configuration file, modifies it to use systemd's cgroup driver (which is what kubelet expects), and then restarts and enables the containerd service. Using systemd as the cgroup driver is generally recommended because it aligns with how kubelet manages the system's cgroups. This setup ensures that containerd is ready to manage your containers for Kubernetes. Getting this right now saves a ton of headaches later!

Step 2: Installing kubeadm, kubelet, and kubectl on the Control Plane

Now that our nodes are prepped, it's time to install the core Kubernetes components. We'll start with the Control Plane node. This machine will host the Kubernetes API server, scheduler, controller manager, and etcd database. It's the brain, remember? We'll use kubeadm, a tool that simplifies bootstrapping a Kubernetes cluster. This is where the magic really starts happening, guys!

Adding the Kubernetes APT Repository

Kubernetes packages aren't in the default Ubuntu repositories, so we need to add the official Kubernetes one. Run these commands on your Control Plane node only:

sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl

# Download Google Cloud public signing key
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/kubernetes-archive-keyring.gpg

# Add Kubernetes APT repository
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

These commands fetch the necessary tools (apt-transport-https, ca-certificates, curl), download the public signing key for the Kubernetes repository, and then add the repository itself to your system's sources. This ensures that when you run apt update next, your system will know where to find the Kubernetes packages. It’s like telling your computer where to find the special ingredients for our cluster recipe!

Installing kubeadm, kubelet, and kubectl

With the repository added, we can now install the Kubernetes tools. We'll also hold their versions to prevent accidental upgrades that might break the cluster.

sudo apt update
sudo apt install -y kubelet kubeadm kubectl

# Hold their versions
sudo apt-mark hold kubelet kubeadm kubectl
  • kubelet: This is the agent that runs on each node in the cluster and works with the container runtime to start the containers described in PodSpecs. It’s the worker bee on each machine.
  • kubeadm: This is the tool we use to bootstrap the cluster. It initializes the control plane and helps set up worker nodes.
  • kubectl: This is the command-line tool you'll use to interact with your Kubernetes cluster – to deploy applications, inspect resources, manage the cluster, etc. It's your main interface!

By running apt-mark hold, we're telling apt not to automatically upgrade these packages. This is super important because Kubernetes versions need to be managed carefully. You don't want an automatic update to mess with your carefully configured cluster.

Initializing the Control Plane

Now for the main event on the control plane! We'll use kubeadm init to set up the control plane. You need to specify a Pod network CIDR. This is a private IP address range that pods in your cluster will use. A common one is 10.244.0.0/16 (for Flannel) or 192.168.0.0/16 (for Calico). We'll use 10.244.0.0/16 for this example, assuming you'll use a CNI plugin like Flannel later.

sudo kubeadm init --pod-network-cidr=10.244.0.0/16

This command will perform a series of checks, set up the necessary control plane components (like the API server, etcd), and configure kubelet to start. Pay close attention to the output! At the end, kubeadm will give you two important pieces of information:

  1. Commands to set up kubectl for your regular user: You'll need to run these to be able to manage the cluster without sudo.
  2. A kubeadm join command: This command contains a token and a discovery hash. You'll use this command on your worker nodes to join them to the cluster.

Let's get kubectl configured for your user. Run these commands as your regular user (not sudo):

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

This creates the .kube directory in your home folder, copies the cluster's admin configuration file into it, and sets the correct ownership. Now, if you type kubectl get nodes, you should see your control plane node listed, but it will likely be in a NotReady state. That's because we haven't installed a network plugin (CNI) yet!

Step 3: Installing a Pod Network Add-on (CNI)

Your Kubernetes cluster isn't fully functional until pods can communicate with each other. This is handled by a Container Network Interface (CNI) plugin. Without it, your nodes will report as NotReady, and pods won't get IP addresses or be able to talk across different nodes. We'll install Flannel, which is a popular and straightforward CNI plugin. Remember, this is done on the Control Plane node only.

Deploying Flannel

To deploy Flannel, you just need to apply a YAML manifest file. Kubernetes provides this for you. Run the following command:

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

This command downloads the Flannel configuration from the URL and applies it to your cluster. It tells Kubernetes to create the necessary pods (Flannel daemonsets) that will run on each node and set up the overlay network. This might take a minute or two to download the container images and get the pods running.

Verifying the Network Plugin

Once you've applied the Flannel manifest, give it a minute and then check the status of your nodes again:

kubectl get nodes

You should now see your control plane node in the Ready state! Awesome, right? If it's still NotReady, wait a bit longer or check the Flannel pod logs for errors. Sometimes, it just takes a moment for the network to initialize properly. You can check pod status with kubectl get pods -n kube-system.

Step 4: Joining Worker Nodes to the Cluster

We've got the control plane up and running, and it's talking to itself! Now it's time to bring our Worker Nodes into the fold. These are the machines that will actually run your applications (your pods). We'll use that kubeadm join command that kubeadm init spat out earlier. Remember, this needs to be done on each of your Worker Nodes.

Running the Join Command

First, log in to your first worker node via SSH. Then, run the kubeadm join command you received from the kubeadm init output. It will look something like this (yours will have different values!):

sudo kubeadm join <control-plane-ip>:6443 --token <your-token> \
    --discovery-token-ca-cert-hash sha256:<your-hash>
  • Replace <control-plane-ip> with the actual IP address of your control plane node.
  • Replace <your-token> and <your-hash> with the exact token and hash printed by kubeadm init.

This command does a few things: it connects to the control plane's API server, verifies its identity using the CA certificate hash, and downloads the necessary configuration for kubelet to join the cluster as a worker node. It will also configure containerd on the worker node to communicate with the cluster.

What if you lost the join command? No worries! You can regenerate a token and get the CA cert hash from your Control Plane node using these commands:

To generate a new token (valid for 24 hours):

sudo kubeadm token create --print-join-command

This will print the full kubeadm join command for you. Just copy and paste it onto your worker node.

Verifying Worker Node Status

After running the join command on a worker node, head back to your Control Plane node. Give it a minute or two for the worker node to register and for Flannel to set up networking on it. Then, check the node status again:

kubectl get nodes

You should now see your worker node appear in the list, and it should also be in the Ready state. Repeat Step 4 for all your other worker nodes. Once all your worker nodes are listed and Ready, congratulations! You have a fully functional Kubernetes cluster!

Step 5: Deploying Your First Application!

Okay, guys, we've done it! We've built a Kubernetes cluster. Now, let's put it to use and deploy something. How about a simple Nginx web server? This is where the real fun begins.

Creating a Deployment

A Deployment is a Kubernetes object that manages a set of replica pods. It ensures that a specified number of pods are running at any given time. Let's create a deployment for Nginx:

kubectl create deployment nginx-deployment --image=nginx --replicas=2

This command tells Kubernetes to create a deployment named nginx-deployment, using the official nginx Docker image, and to maintain 2 replicas (meaning 2 pods running Nginx).

Checking the Deployment and Pods

Let's see what's happening:

kubectl get deployments
kubectl get pods

You should see your nginx-deployment and the pods it created. They should be in the Running state. If they aren't, kubectl describe pod <pod-name> can give you more details about what's going on.

Exposing Your Application with a Service

Right now, your Nginx pods are running, but they're only accessible within the cluster. To make them accessible from outside, we need to create a Service. A Service provides a stable IP address and DNS name for a set of pods. We'll create a NodePort service, which exposes the service on a static port on each Node's IP address.

kubectl expose deployment nginx-deployment --port=80 --type=NodePort

This command creates a service that maps port 80 inside the pods to a randomly assigned port on each node (between 30000-32767). Let's find out which port was assigned:

kubectl get service nginx-deployment

Look for the PORT(S) column. It will show something like 80:3XXXX/TCP. The 3XXXX is the NodePort that was assigned. Now you can access your Nginx server by going to http://<any-node-ip>:<node-port> in your web browser. How cool is that?!

Conclusion: You've Mastered Kubernetes Basics!

Boom! You've successfully set up a Kubernetes cluster on Ubuntu 20.04, installed essential components, configured networking, joined worker nodes, and even deployed your first application. Give yourselves a huge pat on the back, guys! This is a massive accomplishment and the first step into a much larger, exciting world of container orchestration. From here, you can explore more advanced topics like Deployments, StatefulSets, Persistent Volumes, Ingress controllers, and much more. The possibilities are truly endless, and the skills you've just acquired are incredibly valuable in today's tech landscape. Remember, practice makes perfect, so keep experimenting and building! Happy orchestrating!