Available
← all posts

Raspberry Pi Kubernetes Cluster: Load Balancer (Issue #6)

Give bare-metal services real external IPs with MetalLB as a Layer 2 load balancer for the Raspberry Pi cluster.

MetalLB load balancer for the cluster

Welcome to the Raspberry Pi Kubernetes home lab series. A bite sized informative guide to help you provision a cluster from scratch. Our cluster should now be up and running and we should be able to easily provision services, deployments, volumes, and so on.

Today's issue will walk you through exposing a service to an external IP address.

The challenge with bare metal

Since our cluster is running on bare metal we don't have the luxury of provisioning an external load balancer. Kubernetes doesn't provide a direct implementation for network load balancers and instead comes with built-in functionality to integrate with different cloud providers (AWS, GCP, Azure, and so on). This is normally done by allowing Kubernetes to automatically create load balancers on your cloud provider. Without the ability to load balance traffic we are left with two options, "NodePort" and "ClusterIP", which are solutions better suited for internal network or cluster communication.

In this lab we will be implementing MetalLB, a solution that offers network balancing so that external traffic and services can communicate with our cluster.

1. Requirements

  • 1 k8s cluster with a compatible CNI

2. Preparation

Please check the compatibility matrix before you implement MetalLB. If you are following this series you would have installed Flannel and therefore are good to go! Kubernetes CNI integrations are very interesting and worth a read in their own right. Calico, for example, has a really interesting implementation and is definitely worth exploring.

3. Installation

Version 0.13.5 has come a long way; integrating with MetalLB is incredibly simple. We will resource this latest version and supply a configuration file along with it.

kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: metallb-system
resources:
  - github.com/metallb/metallb/config/native?ref=v0.13.5
  - config.yaml

MetalLB is set up as an L2 balancer by default and will be idle until configured. The easiest deployment is probably the Layer 2 configuration, which works by responding to ARP requests and providing the machine's MAC address to clients.

As a bare minimum (no pun intended) it will expect a pool of available addresses in your network, and a reference for them. From the network perspective it is represented as if the cluster had multiple IPs assigned to its network interface. As you can see from the configuration below, we are assigning ports 100 to 250, which should be more than enough for our Raspberry Pi experiments.

config.yaml

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.0.100-192.168.1.250
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: advertisment
  namespace: metallb-system
spec:
  ipAddressPools:
  - first-pool

Apply the kustomization file and verify. MetalLB will create a daemon set "speaker" on every slave node, which will ensure the load balancer can reach our services, and a controller (responsible for address assignments).

# Apply
kubectl apply -k <kustomization_directory>

4. Test the load balancer

Let's deploy an nginx service and assign a load balancer to it.

kubectl run nginx --image=nginx
kubectl expose deploy nginx --port 80 --type LoadBalancer

Let's check that our service has indeed deployed and that it has been assigned an external IP.

kubectl get service
 
# Output
NAME            TYPE           CLUSTER-IP   EXTERNAL-IP
service/nginx   LoadBalancer   10.96.4.10   192.168.0.230

And there we go, our service is now available to the network!

Summary

We are now ready to start assigning IPs to our services. It is important that you know how Layer 2 balancers work so you can extend the basic configuration for MetalLB.

Leave a comment if you have any questions. We will be looking into provisioning Kubernetes secrets powered by git-secret next. Happy coding.


First published in my LinkedIn newsletter, Built from Scratch.

ShareXLinkedIn

Built from Scratch

A newsletter on video, streaming and building reliable systems. No spam, unsubscribe anytime.