DEV Community

Molly Crendraven
Molly Crendraven

Posted on

Bare metal load balancer on Kubernetes with MetalLB

Part two of a mini series, the first part is here 1

Now that I have a working Kubernetes cluster on bare metal, the next thing I wanted was to get external traffic into it without the need for kubectl proxy. Using the API path to access sites like the dashboard seems silly.

The cleanest way to get traffic into a cluster seems to be a load balancer. However, it requires an external service usually provided by GCP or AWS that doesn't come with Kubernetes. What to do?

Fortunately, there is this amazing software called MetalLB 2, designed for creating a load balancer on bare metal. Despite being in alpha stage (at the time of this writing) it works well and is enjoyed by folks in all types of cases, as evidenced by this GitHub "issue" 3.

I installed it using the manifest option with zero modifications and used the Layer 2 config 4, with a subset of IP address from the default OpenVPN range of The reason I used these IPs addresses is because I wanted to be able to access my "external" services from any machine in my cluster, including my master.

I was originally planning to fiddle with a Ingress and get a site running, but the nginx ingress controller pod and the Apache on my node were not happy with each other so, in the interest of having success, I decided to start with the dashboard.

It's a pretty basic task to create a LoadBalancer service for a single port 5, so I'll share my manifest here:

apiVersion: v1
kind: Service
  labels: load-balancer-dashboard
  name: dashboard-service
  namespace: kubernetes-dashboard
    - port: 8080
      protocol: TCP
      targetPort: 8443
    k8s-app: kubernetes-dashboard
  type: LoadBalancer

Once I see what external IP my dashboard-server has obtained, I can go to the browser on the machine and visit https://<external-ip>:8080/ to access my dashboard. No more kubectl proxy!

P.S. I almost forgot. Make sure you comment out the tolerations section of your dashboard manifest (or add them to your MetalLB manifest) so you can get the dashboard and metallb running on the same node. Ask if you give this a try and hit any issues!

Top comments (4)

zimmertr profile image
TJ Zimmerman

This won't work in Chrome as the Subject Name of the certificate for the Dashboard will be invalid and throw a NET::ERR_CERT_INVALID which won't let you move forward.

drazisil profile image
Molly Crendraven

I set an exception in Firefox, if I recall. Does Chrome no longer let you do that?

zimmertr profile image
TJ Zimmerman

For some exceptions yes, not this one though as it is indicative of a Man in the Middle attack.

To do this properly it is necessary to regenerate the certificates that the Dashboard uses and specify the name of the service as the Common Name. I have done so with Ansible here:

But the primary steps are simply:

$ mkdir certs
$ openssl req -nodes -newkey rsa:2048 -keyout certs/dashboard.key -out certs/dashboard.csr -subj "/C=/ST=/L=/O=/OU=/CN=kubernetes-dashboard"
$ openssl x509 -req -sha256 -days 365 -in certs/dashboard.csr -signkey certs/dashboard.key -out certs/dashboard.crt
$ kubectl create secret generic kubernetes-dashboard-certs --from-file=certs -n kubernetes-dashboard
$ kubectl delete pod -n kubernetes-dashboard -l k8s-app=kubernetes-dashboard
Thread Thread
drazisil profile image
Molly Crendraven

Nice! Thank you for sharing.