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 https://metallb.universe.tf/
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 https://raw.githubusercontent.com/metallb/metallb/v0.13.11/config/manifests/metallb-native.yaml
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: –
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: first-pool
namespace: metallb-system
spec:
addresses:
- 192.168.1.71-192.168.1.79
This went into a ‘ipaddresspool.yaml’ file.
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: example
namespace: metallb-system
spec:
ipAddressPools:
- 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 10.43.72.42 192.168.1.71 80:30854/TCP 3s
I then opened up a browser and went to the 192.168.1.71 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 10.43.72.42 192.168.1.71 443:30854/TCP 1d