Kubernetes Demystified: Build a Production-like Local Cluster with Vagrant
Getting hands-on with Kubernetes is essential in the world of DevOps, but the complexity of setting up clusters can be daunting. In this post, we’ll simplify the process by using Vagrant to create a local Kubernetes cluster. This setup offers a practical way to explore Kubernetes concepts without the overhead of cloud infrastructure.
Why a Local Kubernetes Cluster?
Learning Kubernetes often requires hands-on practice to grasp concepts like container orchestration and service management. Using Vagrant with VirtualBox allows you to simulate a multi-node cluster on your local machine, perfect for testing, learning, and developing Kubernetes-based applications.
Prerequisites
Here’s what you’ll need to follow along:
- A laptop with at least 16GB RAM and i5 CPU or higher
- Vagrant installed (Install Vagrant)
- VirtualBox installed for virtualization
- A stable internet connection
- kubectl and kubeadm for managing the cluster
Step 1: Install Vagrant
Use the following commands to install Vagrant on a Debian-based system:
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install vagrant
Verify your installation:
vagrant --version
Step 2: Create a Vagrantfile
A Vagrantfile defines the configuration for your virtual machines (VMs). Below is a basic setup to create a three-node Kubernetes cluster (one master and two worker nodes):
Vagrant.configure("2") do |config|
config.vm.box = "bento/debian-12"
config.vm.provider "virtualbox" do |vb|
vb.memory = 2048
vb.cpus = 2
end
config.vm.define "master" do |node|
node.vm.hostname = "master"
node.vm.network "private_network", ip: "192.168.56.10"
end
config.vm.define "node1" do |node|
node.vm.hostname = "node1"
node.vm.network "private_network", ip: "192.168.56.11"
end
config.vm.define "node2" do |node|
node.vm.hostname = "node2"
node.vm.network "private_network", ip: "192.168.56.12"
end
config.vm.provision "shell", path: "scripts/install-kubernetes.sh"
end
Step 3: Provision the VMs and Install Kubernetes
Inside the same directory as your Vagrantfile, create the install-kubernetes.sh
script:
#!/bin/bash
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo swapoff -a # Disable swap for Kubernetes
Now, bring up your VMs using the following command:
vagrant up
Step 4: Initialize the Kubernetes Master Node
SSH into the master node:
vagrant ssh master
Initialize the Kubernetes control plane:
sudo kubeadm init --apiserver-advertise-address=192.168.56.10 --pod-network-cidr=10.244.0.0/16
Copy the join command provided at the end of the initialization (it will look something like this):
kubeadm join 192.168.56.10:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>
Step 5: Join Worker Nodes to the Cluster
SSH into each worker node and run the join command copied from the master:
vagrant ssh node1
sudo kubeadm join 192.168.56.10:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>
Repeat the process for node2.
Step 6: Verify the Cluster
On the master node, verify that all nodes have joined the cluster:
kubectl get nodes
You should see output similar to:
NAME STATUS ROLES AGE VERSION
master Ready master 10m v1.28.0
node1 Ready <none> 5m v1.28.0
node2 Ready <none> 5m v1.28.0
Step 7: Deploy a Sample Application
Create a simple deployment and service using the following YAML:
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app
spec:
replicas: 2
selector:
matchLabels:
app: demo
template:
metadata:
labels:
app: demo
spec:
containers:
- name: demo-container
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: demo-service
spec:
selector:
app: demo
ports:
- protocol: TCP
port: 80
type: NodePort
Apply the YAML:
kubectl apply -f demo-app.yaml
Check if the application is running:
kubectl get pods
Step 8: Access the Application
Find the NodePort assigned to the service:
kubectl get svc demo-service
Use the IP address of any node along with the NodePort to access the application from your browser:
http://192.168.56.11:<NodePort>
Conclusion
By following this guide, you’ve set up a production-like Kubernetes cluster locally using Vagrant. This setup provides a sandbox environment to explore Kubernetes without relying on cloud providers, perfect for developers and DevOps practitioners. From spinning up the cluster to deploying applications, you now have a foundational understanding of how Kubernetes works.
Continue experimenting, try different networking setups, and deploy more complex applications to solidify your Kubernetes skills.