K3S + MetalLB + Traefik v2

After a couple of days I got all working as I expected. This is the list of main tools I put together:

  • K3S (Kubernetes lightweight implementation, best for IoT devises)
  • MetalLB (load balancer handler)
  • Traefik v2 (Automatic & dynamic routing)

About K3s and MetalLB, by default K3s installs KlipperLB, this is a very simple LoadBalancer. In my case, when I installed this blog I found all logs were using PODs internal IPs and not visitors data. To fix this problem, MetalLB let’s you pass this information, we will see how this works in this post.

K3S installation

The best place for docs is their website https://rancher.com/docs/k3s/latest/en/installation/install-options/

No special steps except that we need to disable servicelb and traefik. This is the line Im using for this:

curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--write-kubeconfig-mode 644  --no-deploy servicelb --disable traefik"  sh -


As we did it with K3S, their website has an excellent docs https://metallb.universe.tf/

For me, I’m using this with a normal router so I’m using layer2 for the config, you can use a config like the following:

apiVersion: v1
kind: ConfigMap
  namespace: metallb-system
  name: config
  config: |
    - name: default
      protocol: layer2

A critical point to understand is the address range that you need to config. Here for example we’re using, meaning that our DHCP needs to have that range as part of the addresses.

For this example, our DHCP needs to work for to 192.168.250 and to define this range we need to know a portion of that range we’re not using, for example, a portion of the range:

Traefik v2

You need to follow a normal installation for Kubernetes, you can use Helm or Kustomization (I recommend this, its simpler to mantain).

You can see the docs https://docs.traefik.io/

Checking all from outside

The trick it’s to understand what and how to expose Traefik in our cluster to the public.

Any service we want to access from outside it must be:

type: LoadBalancer

If you need to passthrough a visitor data, for example the IP, the LoadBalancer needs to have this setting:

externalTrafficPolicy: Local

For example if we want to create a service exposing port 80 as a load balancer and pass the visito IP to our PODs:

apiVersion: v1
kind: Service
    name: my-service
  type: LoadBalancer
  externalTrafficPolicy: Local
  - port: 80
    name: web
    targetPort: "web"
    protocol: "TCP"

I hope this post help others trying to setup this tools, it took me a couple of days to understand how to make it work all in one cluster.

One good thing I found is using Kustomization, this is much better tool as Helm in my opinion.