LoadBalancer

MetalLB hooks into your Kubernetes cluster, and provides a network load-balancer implementation. In short, it allows you to create Kubernetes services of type LoadBalancer in clusters that don’t run on a cloud provider, and thus cannot simply hook into paid products to provide load-balancers. It has two features that work together to provide this service: address allocation and external announcement.

Address Allocation

In a cloud-enabled Kubernetes cluster, you request a load-balancer and your cloud platform assigns an IP address to you. In a bare metal cluster, MetalLB is responsible for that allocation.

MetalLB cannot create IP addresses out of thin air, so you do have to give it pools of IP addresses that it can use. MetalLB will take care of assigning and unassigning individual addresses as services come and go, but it will only ever hand out IPs that are part of its configured pools.

How you get IP address pools for MetalLB depends on your environment. If you’re running a bare metal cluster in a collocation facility, your hosting provider probably offers IP addresses for lease. In that case, you would lease, say, a /26 of IP space (64 addresses), and provide that range to MetalLB for cluster services.

Alternatively, your cluster might be purely private, providing services to a nearby LAN but not exposed to the internet. In that case, you could pick a range of IPs from one of the private address spaces (so-called RFC1918 addresses), and assign those to MetalLB. Such addresses are free, and work fine as long as you’re only providing cluster services to your LAN.

Or, you could do both! MetalLB lets you define as many address pools as you want, and doesn’t care what “kind” of addresses you give it.

External Announcement

Once MetalLB has assigned an external IP address to a service, it needs to make the network beyond the cluster aware that the IP “lives” in the cluster. MetalLB uses standard routing protocols to achieve this: ARP, NDP, or BGP.

Layer 2 mode (ARP/NDP)

In layer 2 mode, one machine in the cluster takes ownership of the service, and uses standard address discovery protocols (ARP for IPv4, NDP for IPv6) to make those IPs reachable on the local network. From the LAN’s point of view, the announcing machine simply has multiple IP addresses.

The layer 2 mode sub-page has more details on the behavior and limitations of layer 2 mode.

BGP

In BGP mode, all machines in the cluster establish BGP peering sessions with nearby routers that you control, and tell those routers how to forward traffic to the service IPs. Using BGP allows for true load balancing across multiple nodes, and fine-grained traffic control thanks to BGP’s policy mechanisms.

The BGP mode sub-page has more details on BGP mode’s operation and limitations.

Installation By Manifest

To install MetalLB, apply the manifest:

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.5/manifests/namespace.yaml

This will deploy MetalLB to your cluster, under the metallb-system namespace.

namespace/metallb-system created
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.5/manifests/metallb.yaml

The components in the manifest are:

  • The metallb-system/controller deployment. This is the cluster-wide controller that handles IP address assignments.
  • The metallb-system/speaker daemonset. This is the component that speaks the protocol(s) of your choice to make the services reachable.
  • Service accounts for the controller and speaker, along with the RBAC permissions that the components need to function.
podsecuritypolicy.policy/controller created
podsecuritypolicy.policy/speaker created
serviceaccount/controller created
serviceaccount/speaker created
clusterrole.rbac.authorization.k8s.io/metallb-system:controller created
clusterrole.rbac.authorization.k8s.io/metallb-system:speaker created
role.rbac.authorization.k8s.io/config-watcher created
role.rbac.authorization.k8s.io/pod-lister created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker created
rolebinding.rbac.authorization.k8s.io/config-watcher created
rolebinding.rbac.authorization.k8s.io/pod-lister created
daemonset.apps/speaker created
deployment.apps/controller created
kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"

The memberlist secret contains the secretkey to encrypt the communication between speakers for the fast dead node detection.

secret/memberlist created

The installation manifest does not include a configuration file. MetalLB’s components will still start, but will remain idle until you define and deploy a configmap.

cat ~/listaip.txt

Check your Range Public IP, this will be your public IP. Please take note of this range.

Create a new file:

vi /home/student/metallb-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: metallb-ip-space
      protocol: layer2
      addresses:
      - 10.10.XX.200-10.10.XX.250
kubectl apply -f metallb-config.yaml
configmap/config created
kubectl get pod -n metallb-system
NAME                          READY   STATUS    RESTARTS   AGE
controller-65db86ddc6-lp6z5   1/1     Running   0          7m17s
speaker-2nfxc                 1/1     Running   0          7m17s
speaker-f4pxl                 1/1     Running   0          7m17s
speaker-mmrgg                 1/1     Running   0          7m17s
speaker-zmgzn                 1/1     Running   0          7m17s
kubectl create ns test-loadbalancer
namespace/test-loadbalancer created
kubectl create deploy desoapp \
  --image=r.deso.tech/whoami/whoami \
  -n test-loadbalancer
deployment.apps/desoapp created
kubectl expose deploy desoapp \
  -n test-loadbalancer \
  --type=LoadBalancer \
  --port=80
service/desoapp exposed
kubectl get svc -n test-loadbalancer
NAME      TYPE           CLUSTER-IP       EXTERNAL-IP    PORT(S)        AGE
desoapp   LoadBalancer   10.105.105.211   10.10.95.200   80:31671/TCP   29s

Now open chrome browser on your student desktop and open the External IP assigned. In this example: http://10.10.95.200.

You should see a whoami application.

Clean up

kubectl  delete ns test-loadbalancer
namespace "test-loadbalancer" deleted