A Quick and Easy Load Balancer for Kubernetes Labs with MetalLB

I’ve been tinkering with a number of different Kubernetes platforms again and the relative complication of external networking for deployed Kubernetes applications remains real. In the Public Cloud world, services such as EKS, GKE and AKS all have some form of external networking built into the offerings and VMware’s Tanzu can rely on NSX-T, HAProxy and more recently AVI Networks to bridge the gap between what is happening on the inside of a Kubernetes deployment and how to get applications published with some level of ease and resiliency to the outside.

There is a reason why there are a million posts on how to expose the Kubernetes Dashboard when deploying to a BareOS server like Ubuntu or CentOS… it’s not straight forward.

Today I came across MetalLB 

Kubernetes does not offer an implementation of network load-balancers (Services of type LoadBalancer) for bare metal clusters. The implementations of Network LB that Kubernetes does ship with are all glue code that calls out to various IaaS platforms (GCP, AWS, Azure…). If you’re not running on a supported IaaS platform (GCP, AWS, Azure…), LoadBalancers will remain in the “pending” state indefinitely when created. Bare metal cluster operators are left with two lesser tools to bring user traffic into their clusters, “NodePort” and “externalIPs” services. Both of these options have significant downsides for production use, which makes bare metal clusters second class citizens in the Kubernetes ecosystem.

Thanks to Platform9, I came across MetalLB, which aims to correct the imbalance by offering a Network LB implementation that integrates with standard network equipment, so that external services on BareOS clusters just work as much as possible. I had MetalLB deployed into a relatively fresh single node Kubernetes Cluster in under 5 minutes as was able to expose applications through the services command without any issue. All I needed was a pre-allocated block (no need specifically for CIDR) of IP addresses and that was pretty much it.

There are a few more advanced scenarios that can be used, including BGP support… but for the purposes of quick and easy access to services deploying inside a cluster, this is as easy as it gets!

Quick Install and Config Demo

the installation and configuration instructions can be found here: Below, I recorded a real time shell grab with asciinema below showing the end to end process to install and configure.

References:

https://metallb.universe.tf/release-notes/

A network load-balancer implementation for Kubernetes using standard routing protocols
https://github.com/metallb/metallb
456 forks.
3,614 stars.
139 open issues.
Recent commits:

  • website: Fix a hugo errorWhen I try to run `hugo server` right now, I get the following error: Error: Error building site: “/home/rbryant/go/src/github.com/metallb/metallb/website/content/_header.md:1:1”: plain HTML documents not supportedIt seems like this is an issue with a more recent version of hugo.I’m using the following version from a Fedora package: Hugo Static Site Generator v0.80.0/extended linux/amd64 BuildDate: unknownThis change is based on a suggested workaround in the following issue: https://github.com/gohugoio/hugo/issues/7296The workaround seems harmless, and may no longer be needed if thefollowing issue gets resolved at some point in the future: https://github.com/gohugoio/hugo/issues/6098, Russell Bryant
  • Do not set resources limits by defaultI’ve experienced issues in the past where MetalLB was throttledfor 15s and then replying to all previous ARP request at the same time.MetalLB is the entry point of the cluster, if it’s not working everythingelse in the cluster is useless, so let’s just not set limits.Signed-off-by: Etienne Champetier <[email protected]>, Russell Bryant
  • Do not log startUpdate/endUpdate for non LoadBalancer servicesSigned-off-by: Etienne Champetier <[email protected]>, Russell Bryant
  • Remove unused Service Update()The Update() to the Service object is never triggered because the codedoes not modify the object between the deep copy and when Update() iscalled.Previously, commit cdd44aa9 (“Initial commit. Somewhat workingcontroller, half-written BGP speaker”) modified the Spec and Annotationsfield of the Service. However, since commit 3e10f6ea (“Clean up processingto exclusively use status.loadBalancer.ingress.ip”), that is no longerthe case, as the code exclusively only touches the Status field.Therefore, this commit removes this dead code and revokes the updateprivileges from the ClusterRole as well.Signed-off-by: Chris Tarazi <[email protected]>, Russell Bryant
  • website: Remove reveal.js from Hugo themeWe don’t use reveal.js and having it lying around adds somemaintenance burden., Russell Bryant

Senior Global Technologist, Product Strategy, Veeam Software
Anthony Spiteri is a Senior Global Technologist, vExpert, VCIX-NV and VCAP-DCV working in the Product Strategy team at Veeam. He currently focuses on Veeam’s Service Provider products and partners. Anthony previously held Architectural Lead roles at some of Australia’s leading Cloud Providers. He is responsible for generating content, evangelism, collecting product feedback, and presenting at events worldwide. He can be found blogging on https://anthonyspiteri.net or on Twitter @anthonyspiteri.

Posted by Editor