We would love to hear from you! Here are some places you can find us.
Our mailing list is email@example.com. It’s for discussions around MetalLB usage, community support, and developer discussion (although for the latter we mostly use Github directly).
For a more interactive experience, we have the #metallb slack channel on k8s.slack.com. If you’re not already logged into the Kubernetes slack organization, you’ll need to request an invite before you can join.
If you prefer a more classic chat experience, we’re also on
on the Freenode IRC network. You can use
web client if
you don’t already have an IRC client.
Use the GitHub issue tracker to file bugs and features request. If you need support, please send your questions to the metallb-users mailing list rather than filing a GitHub issue.
We welcome contributions to MetalLB! Here’s some information to get you started.
This project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.
Contributions to this project must be accompanied by a Contributor License Agreement. You (or your employer) retain the copyright to your contribution, this simply gives us permission to use and redistribute your contributions as part of the project. Head over to https://cla.developers.google.com/ to see your current agreements on file or to sign a new one.
You generally only need to submit a CLA once, so if you’ve already submitted one (even if it was for a different project), you probably don’t need to do it again. When you submit pull requests, a helpful Google CLA bot will tell you if you need to sign the CLA.
Before you make significant code changes, please open an issue to discuss your plans. This will minimize the amount of review required for pull requests.
All submissions require review. We use GitHub pull requests for this purpose. Consult GitHub Help for more information on using pull requests.
MetalLB’s code is divided between a number of binaries, and some
supporting libraries. The libraries live in the
and each binary has its own top-level directory. Here’s what we
currently have, relative to the top-level directory:
controlleris the cluster-wide MetalLB controller, in charge of IP assignment.
speakeris the per-node daemon that advertises services with assigned IPs using various advertising strategies.
test-bgp-routeris a small wrapper around the BIRD, Quagga and GoBGP open-source BGP routers that presents a read-only interface over HTTP. We use it in the tutorial, and during development of MetalLB.
internal/k8scontains the bowels of the logic to talk to the Kubernetes apiserver to get and modify service information. It allows most of the rest of the MetalLB code to be ignorant of the Kubernetes client library, other than the objects (Service, ConfigMap…) that they manipulate.
internal/configparses and validates the MetalLB configmap.
internal/allocatoris the IP address manager. Given pools from the MetalLB configmap, it can allocate addresses on demand.
internal/bgpis a very stripped down implementation of BGP. It speaks just enough of the protocol to keep peering sessions up, and to push routes to the peer.
In addition to code, there’s deployment configuration and documentation:
manifestscontains a variety of Kubernetes manifests. The most important one is
manifests/metallb.yaml, which specifies how to deploy MetalLB onto a cluster.
websitecontains the website for MetalLB. The
website/contentsubdirectory is where all the pages live, in Markdown format.
To develop MetalLB, you’ll need a couple of pieces of software:
Optionally, if you want to update the vendored dependency, you’ll need glide, the Go dependency manager
Start by fetching the MetalLB repository, with
From there, you can use normal Go commands to build binaries and run
unit tests, e.g.
go install go.universe.tf/metallb/bgp-speaker,
For development, fork
the github repository, and add
your fork as a remote in
git remote add fork firstname.lastname@example.org:<your-github-user>/metallb.git.
Note: the repository must be checked out at
$GOPATH/src/go.universe.tf/metallb. The source code uses canonical
import paths, so if you check it out at
$GOPATH/src/github.com/google/metallb or similar, it will fail to
To really test MetalLB fully, you need to run it in a Kubernetes cluster, to verify that all the pieces are working together. The repository has a set of Fabric commands that makes this easy, by setting up a Minikube sandbox and deploying a production MetalLB setup, but running your locally built binaries.
Start by running
make start-minikube. This will:
test-bgp-router, which sets up BIRD, Quagga and GoBGP routers as a pod inside the cluster
At this point, your sandbox is running the precompiled version of MetalLB, pulled from Docker Hub.
You can inspect the state of the
test-bgp-router by running
minikube service test-bgp-router-ui, which will open a browser tab
that shows you the current BGP connections and routing state, as seen
by the test routers.
When you’re ready to test a local change you’ve made to MetalLB, you
can build and deploy MetalLB containers to your sandbox. First, if
you’re using minikube, leave
make proxy-to-registry running in a
second terminal. This will make the cluster’s internal registry
localhost, so that we can push to it.
To deploy your changes, run
make push. This will:
Once the push is done, MetalLB will still be running in your Minikube sandbox, but using binaries built from your local source code instead of the public images.
Note for MacOS users: Since Docker is run inside a virtual machine
in MacOS the local registry won’t work out of the box. To make it work
you have to add
docker.for.mac.localhost:5000 under Insecure
registries in your Docker daemon preferences. Once you’ve done that,
make push should work.
If you need to get back to a working configuration,
push-manifests will revert MetalLB to running from the public Docker
Hub images and the config from the repository.
When you’re done with minikube, run
minikube delete to destroy the
If you’re already using minikube, be warned:
will touch the default minikube sandbox, and so may interfere with
other experiments you have going on.
You can also use
make push on clusters other than minikube.
push will deploy to whichever cluster your
kubectl is currently
If your cluster has a local registry, usage instructions are exactly
the same as with minikube: leave
make proxy-to-registry running in a
secondary terminal, and then
make push each time you want to test
If you want to use an external registry, you can specify it with the
REGISTRY make variable. For example,
make push REGISTRY=danderson
will push the docker images
danderson’s account on docker hub,
and make the cluster pull from there as well.
Released versions of MetalLB (0.3.0 and later) use multi-architecture
images, and so should work on all platforms supported by
kubernetes. However, the dev builds made by
make push only build for
one architecture, to save time.
make push builds binaries for amd64 (aka x86_64). If you
want to test on a different architecture (for example a raspberry pi
cluster), you can select the architecture of the dev builds by setting
ARCH make variable to your desired architecture, one of amd64,
arm, arm64, ppc64le, s390x. For example,
make push ARCH=arm will
build and deploy containers that work on ARM machines.
You can write custom make configuration options to
Makefile.defaults, and they will be included as defaults for all
builds. For example, if you normally build with go1.10beta1 and push
arm64 binaries to a custom registry, you can use the following
GOCMD=go1.10beta1 ARCH=arm64 REGISTRY=my-cool-images
To see a list of customizable options and what they do, look at the
While testing, it might be useful to peer with “real” routers outside
of the cluster, rather than always use the in-cluster
test-bgp-router. If you do so, you need to reconfigure the address
pool from the default config! The default configuration uses the
TEST-NET-2 IP range
from RFC5735, which is reserved
for use in documentation and example code. It’s fine to use it with
test-bgp-router, since they doesn’t propagate the addresses
beyond themselves, but if you try injecting those addresses into a
real network, you may run into trouble.
The website at https://metallb.universe.tf is pinned to the latest released version, so that users who don’t care about ongoing development see documentation that is consistent with the released code.
However, there is a version of the website synced to the latest master
every branch has a published website at
name>--metallb.netlify.com. So if you want to view the documentation
for the 0.2 version, regardless of what the currently released version
is, you can
When editing the website, you can preview your changes locally by
installing Hugo and running
hugo server from