Setting Up a Kubernetes Cluster with MetalLB on Bare Metal
In this guide, we’ll walk through setting up a Kubernetes cluster on two Ubuntu VPS servers and using MetalLB to provide LoadBalancer
services. This setup is ideal for environments where you don’t have access to cloud-provided load balancers, such as bare-metal or on-premises deployments.
What You’ll Need
- Two Ubuntu VPS servers with the following:
- Public IP addresses:
203.0.113.10
and203.0.113.11
. - At least 2 GB RAM and 2 vCPUs per node.
- SSH access to both servers.
- Basic familiarity with Kubernetes and Linux commands.
Step 1: Set Up the Kubernetes Cluster
1.1 Prepare the Nodes
On both servers:
- Disable swap:
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
- Install dependencies:
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl
1.2 Install Kubernetes Tools
On both servers:
- Add the Kubernetes repository:
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt update
- Install
kubeadm
,kubelet
, andkubectl
:
sudo apt install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
1.3 Initialize the Control Plane
On the master node (203.0.113.10
):
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
- Save the
kubeadm join
command for adding worker nodes.
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
1.4 Join the Worker Node
On the worker node (203.0.113.11
):
sudo kubeadm join <master-ip>:6443 --token <token> --discovery-token-ca-cert-hash <hash>
Step 2: Install MetalLB for Load Balancing
2.1 Deploy MetalLB
MetalLB provides LoadBalancer
services for bare-metal Kubernetes clusters. Deploy it using the following command:
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.12/config/manifests/metallb-native.yaml
2.2 Configure MetalLB
Create a configuration file (metallb-config.yaml
) to define the IP address pool:
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: production-public-ips
namespace: metallb-system
spec:
addresses:
- 203.0.113.10-203.0.113.11 # Use your two IPs here
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: l2-advert
namespace: metallb-system
spec:
ipAddressPools:
- production-public-ips
Apply the configuration:
kubectl apply -f metallb-config.yaml
Step 3: Test the Setup
3.1 Deploy a Test Application
Deploy an nginx
application:
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=LoadBalancer
3.2 Verify the Service
Check the service status:
kubectl get svc nginx
Expected Output:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx LoadBalancer 10.96.123.45 203.0.113.10 80:30000/TCP 1m
3.3 Access the Application
Use the external IP to access the nginx
service:
curl http://203.0.113.10
- You should see the default
nginx
welcome page.
Step 4: High Availability and Scaling
4.1 Use Both IP Addresses
You can deploy additional services and assign the second IP (203.0.113.11
) to them. For example:
kubectl create deployment nginx2 --image=nginx
kubectl expose deployment nginx2 --port=80 --type=LoadBalancer
4.2 Scale Applications
Scale your applications across both nodes:
kubectl scale deployment nginx --replicas=3
kubectl get pods -o wide
Step 5: Firewall Rules
Ensure the following ports are open:
- MetalLB:
7946
(TCP/UDP) and7472
(UDP). - Kubernetes:
6443
(API server),10250
(kubelet), and30000-32767
(NodePort range).
Example ufw
rules:
sudo ufw allow 7946/tcp
sudo ufw allow 7946/udp
sudo ufw allow 7472/udp
sudo ufw allow 6443/tcp
sudo ufw allow 10250/tcp
sudo ufw allow 30000:32767/tcp
sudo ufw reload
Conclusion
With MetalLB, you can provide LoadBalancer
services for your Kubernetes cluster even in bare-metal or on-premises environments. This setup is cost-effective and leverages your existing infrastructure. By following this guide, you’ve successfully:
- Set up a Kubernetes cluster on two nodes.
- Deployed MetalLB to manage external IPs.
- Tested the setup with a sample application.
Feel free to explore advanced features like persistent storage, ingress controllers, or RBAC to enhance your cluster further.
Let me know if you’d like to add more sections or tweak the content! 🚀
Leave a Reply