Kubernetes load balancing with Metal LB

kubernetes, homelab, networking

If you run Kubernetes on an IaaS provider like AWS or GCE and create a service with the LoadBalancer type, there is glue code included in kubernetes itself that will provision an ELB/ALB for you automatically. When you’re running k8s on prem or at home any service you create with the LoadBalancer service type will hang indefinitely since there is no way to provision external IPs on your router out of the box. This is where Metal LB comes in.

Metal LB is a project that implements load balancing for on premises based Kubernetes clusters by responding to ARP requests directly on your network with the MAC address of the worker nodes. This means no setup is required in most cases and you get a nice internal IP that you can port forward on your router. In this post I will walk you through high level set up so you can get traffic from the internet hitting your service in a scalable way.

Setup Metal LB

Installation is easy but you have to make sure you’re using a compatible networking add on. I would recommend Flannel or Kube Router but there are many others supported with caveats that you can look in their compatibility table.

Next you can install Metal LB on your cluster like so:

1kubectl apply -f https://raw.githubusercontent.com/google/metallb/v0.8.3/manifests/metallb.yaml

Then set up a config map with an IP address pool. This IP address pool should be in the subnet that is set up on your router or traffic will be dropped. This means that if your router is set up to give out IPs in the range of then you should make sure the pool is in that range.

 1apiVersion: v1
 2kind: ConfigMap
 4  namespace: metallb-system
 5  name: config
 7  config: |
 8    address-pools:
 9    - name: default
10      protocol: layer2
11      addresses:
12      -    

Now lets run a pod and service to see this in action. Apply the following with kubectl:

 1apiVersion: v1
 2kind: Service
 4  name: whoami
 6  ports:
 7    - protocol: TCP
 8      name: web
 9      port: 80
10  selector:
11    app: whoami
12  type: LoadBalancer
14kind: Deployment
15apiVersion: apps/v1
17  namespace: default
18  name: whoami
19  labels:
20    app: whoami
22  replicas: 1
23  selector:
24    matchLabels:
25      app: whoami
26  template:
27    metadata:
28      labels:
29        app: whoami
30    spec:
31      containers:
32        - name: whoami
33          image: containous/whoami
34          ports:
35            - name: web
36              containerPort: 80

Finally get the external IP address by doing kubectl get svc whoami. Visit that IP on port 80 and you should see some output.

And that’s all there is to it. From here you should be able to port forward 80 to that IP and access the service from the internet with the IP given to you by your ISP.

Next I will show how to set up Traefik, a popular and powerful loadbalancer. We’ll be able to port forward to traefik and route to multiple services in any way we want.

Articles from blogs I follow

My plans at FOSDEM: SourceHut, Hare, and Helios

FOSDEM is right around the corner, and finally in person after long years of dealing with COVID. I’ll be there again this year, and I’m looking forward to it! I have four slots on the schedule (wow! Thanks for arranging these, FOSDEM team) and I’ll be talkin…

via Drew DeVault's blog January 24, 2023

YSK: Google allows spoofing news headlines in search results

A minor scandal unfolding in the Swedish election highlights a way to influence news narratives: Google allows you to set headlines for news articles in search results by paying for adwords placements of legitimate articles. This is being used by political …

via Jacob Davis-Hansson September 9, 2022

Going multipath without Multipath TCP

Going multipath without Multipath TCP Gigabit ethernet has been around for a long time, it’s so ubiquitous that there is a very strong chance that if you have a RJ-45 port on your compu

via benjojo blog February 24, 2022

Generated by openring