Slimming k3s: Disable Traefik & ServiceLB Cleanly

Decide what to disable before first boot, and use --disable rather than deleting resources by hand.

k3s ships batteries included, but production clusters often want their own ingress and load balancer. The senior move is to disable the bundled add-ons at install time, not after they are already running.

Why timing matters

Bundled add-ons are deployed by the internal Helm controller from manifests in /var/lib/rancher/k3s/server/manifests/. If you just kubectl delete them, the controller re-applies them on the next restart. The --disable flag tells k3s to lay down a disabled marker so they stay gone.

Common swaps

  • --disable=traefik → install ingress-nginx or your own Traefik with a pinned version and tuned config.
  • --disable=servicelb → install MetalLB for real L2/BGP load balancing on bare metal.
  • --disable=local-storage → install Longhorn or an external CSI driver.

Disabling servicelb but keeping Traefik is fine — they are independent. Just remember Traefik itself needs something to hand it an external IP, so if you disable servicelb, give Traefik a MetalLB address or a NodePort.

Example

Example · yaml
# /etc/rancher/k3s/config.yaml — decided before first boot
disable:
  - traefik
  - servicelb
write-kubeconfig-mode: "0644"
tls-san:
  - k3s.example.com
# Apply with: sudo systemctl restart k3s
# Then install your own ingress + MetalLB via Helm/manifests

When to use it

  • A team disables Traefik and ServiceLB before first boot because they plan to install MetalLB and NGINX ingress controller immediately after.
  • An operator removes the local-path provisioner to use Longhorn for distributed storage and avoids leaving orphaned StorageClass resources in the cluster.
  • A security-conscious team disables the metrics-server bundled with k3s and installs a hardened version with custom RBAC rules.

More examples

Disable multiple components at install

Passes multiple --disable flags in INSTALL_K3S_EXEC so the unwanted components are never installed in the first place.

Example · bash
curl -sfL https://get.k3s.io | \
  INSTALL_K3S_EXEC='
    --disable traefik
    --disable servicelb
    --disable local-storage
  ' sh -
kubectl get pods -n kube-system

Disable via config file

Pre-creates the config file so components are disabled before k3s starts without needing INSTALL_K3S_EXEC flags.

Example · yaml
# /etc/rancher/k3s/config.yaml (create before install)
disable:
  - traefik
  - servicelb
  - local-storage
  - metrics-server

Verify clean removal

Confirms that no residual IngressClass, StorageClass, or svclb resources remain after clean component disabling.

Example · bash
kubectl get ingressclass
# Should return: No resources found
kubectl get storageclass
# Should return: No resources found (local-path gone)
kubectl get svc -n kube-system | grep svclb

Discussion

  • Be the first to comment on this lesson.