MetalLB – Kubernetes does need a load balancer

MetalLB – Kubernetes does need a load balancer

metallb-white-150x150 MetalLB - Kubernetes does need a load balancer

At work, we run Kubernetes in Azure. There is an Azure load balancer that provides IP addresses to allow the ingress of traffic into the cluster. Of course, this is an additional service, which means an additional cost, but those costs are quite reasonable – for Azure.

Initially, I thought that this must be ‘just standard Kubernetes’, but that is not the case.

When I installed my first local Kubernetes cluster, I couldn’t find any way to define an external IP address for the cluster. I thought that I had seen documentation on the internet that stated that this was all automatic – perhaps I did – but that was not the case. So, I started to look for a solution and that turned out to be MetalLB.

What is MetalLB and where do I get it from?

You can get MetalLB from

Installation and configuration

Installing MetalLB is really easy. It doesn’t have that many options, so you can install the vanilla version from the standard manifest files with the following: –

kubectl apply -f

Note the version number – it is the latest version at the installation time, and I am writing this post.

Then, there are two more things needed. The first is an IPAddressPool that tells MetalLB which IP addresses to give out, and the second is an L2Advertisement that advertises the pool. I therefore created a couple of yaml files like this: –

kind: IPAddressPool
  name: first-pool
  namespace: metallb-system

This went into a ‘ipaddresspool.yaml’ file.

kind: L2Advertisement
  name: example
  namespace: metallb-system
  - first-pool

This went into a ‘ipadvert.yaml file.

I then issued the following commands to create the necessary resources within the cluster: –

kubectl create -f ipaddresspool.yaml
kubectl create -f ipadvert.yaml

As far as configuration is concerned, for me, that was all I needed to do.

To test out this configuration, I created a test service and an associated LoadBalancer. It is when a LoadBalancer resource is requested that MetalLB steps in and creates the resource with an IP address from the defined pool. I simply created a basic Nginx service.

kubectl create deploy nginx --image nginx
kubectl expose deploy nginx --port 80 --type LoadBalancer

To see what had been created, I issued the following kubectl command and could see that there was an external IP address from the range I set up: –

kubectl get svc
NAME      TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)         AGE
nginx     LoadBalancer   80:30854/TCP    3s

I then opened up a browser and went to the address, and I could see the default nginx page.

After that, I cleaned up the nginx service with the following commands: –

kubectl delete svc nginx
kubectl delete deploy nginx

At this point, I installed Traefik (see Installing & Configuring Traefik with SSL certs) and issued the following command and could see that I had a new load-balancer setup with an IP address I could access and set up with a DNS wildcard: –

kubernetes get svc -n traefik
NAME      TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)         AGE
traefik   LoadBalancer   443:30854/TCP   1d

Hi, my name is Stephen Finchett. I have been a software engineer for over 30 years and worked on complex, business critical, multi-user systems for all of my career. For the last 15 years, I have been concentrating on web based solutions using the Microsoft Stack including ASP.Net, C#, TypeScript, SQL Server and running everything at scale within Kubernetes.