If you run Kubernetes on an IaaS provider like AWS or GCE and create a service with the LoadBalancer type, there is glue code included in kubernetes itself that will provision an ELB/ALB for you automatically. When you're running k8s on prem or at home any service you create with the LoadBalancer service type will hang indefinitely since there is no way to provision external IPs on your router out of the box. This is where Metal LB comes in.

Metal LB is a project that implements load balancing for on premises based Kubernetes clusters by responding to ARP requests directly on your network with the MAC address of the worker nodes. This means no setup is required in most cases and you get a nice internal IP that you can port forward on your router. In this post I will walk you through high level set up so you can get traffic from the internet hitting your service in a scalable way.

Setup Metal LB

Installation is easy but you have to make sure you're using a compatible networking add on. I would recommend Flannel or Kube Router but there are many others supported with caveats that you can look in their compatibility table.

Next you can install Metal LB on your cluster like so:

1
kubectl apply -f https://raw.githubusercontent.com/google/metallb/v0.8.3/manifests/metallb.yaml

Then set up a config map with an IP address pool. This IP address pool should be in the subnet that is set up on your router or traffic will be dropped. This means that if your router is set up to give out IPs in the range of 192.168.0.2-192.168.0.254 then you should make sure the pool is in that range.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.0.240-192.168.0.250

Now lets run a pod and service to see this in action. Apply the following with kubectl:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
apiVersion: v1
kind: Service
metadata:
  name: whoami
spec:
  ports:
    - protocol: TCP
      name: web
      port: 80
  selector:
    app: whoami
  type: LoadBalancer
---
kind: Deployment
apiVersion: apps/v1
metadata:
  namespace: default
  name: whoami
  labels:
    app: whoami
spec:
  replicas: 1
  selector:
    matchLabels:
      app: whoami
  template:
    metadata:
      labels:
        app: whoami
    spec:
      containers:
        - name: whoami
          image: containous/whoami
          ports:
            - name: web
              containerPort: 80

Finally get the external IP address by doing kubectl get svc whoami. Visit that IP on port 80 and you should see some output.

And that's all there is to it. From here you should be able to port forward 80 to that IP and access the service from the internet with the IP given to you by your ISP.

Next I will show how to set up Traefik, a popular and powerful loadbalancer. We'll be able to port forward to traefik and route to multiple services in any way we want.