Skip to content


This recipe utilises the traefik helm chart to proving LetsEncrypt-secured HTTPS access to multiple containers within your cluster.


  1. Kubernetes cluster
  2. Helm installed and initialised in your cluster


Clone helm charts

Clone the helm charts, by running:

git clone

Change to stable/traefik:

cd charts/stable/traefik

Edit values.yaml

The beauty of the helm approach is that all the complexity of the Kubernetes elements' YAML files are hidden from you (created using templates), and all your changes go into values.yaml.

These are my values, you'll need to adjust for your own situation:

imageTag: alpine
serviceType: NodePort
# yes, we're not listening on 80 or 443 because we don't want to pay for a loadbalancer IP to do this. I use poor-mans-k8s-lb instead
    http: 30080
    https: 30443
cpuRequest: 1m
memoryRequest: 100Mi
cpuLimit: 1000m
memoryLimit: 500Mi

  enabled: true
  enforced: true
  enabled: false

  enabled: true
  enabled: true
  # set these to all the namespaces you intend to use. I standardize on one-per-stack. You can always add more later
    - kube-system
    - unifi
    - kanboard
    - nextcloud
    - huginn
    - miniflux
  enabled: true
     enabled: true
     # Add the necessary annotation to backup ACME store with k8s-snapshots
     annotations: { " P1D P7D" }
  staging: false
  enabled: true
  logging: true
  email: "<my letsencrypt email>"
  challengeType: "dns-01"
    name: cloudflare
      CLOUDFLARE_EMAIL: "<my cloudlare email"
      CLOUDFLARE_API_KEY: "<my cloudflare API key>"
    enabled: true
      - main: "*" # name of the wildcard domain name for the certificate
      - sans:
          - ""
    enabled: true


The helm chart doesn't enable the Traefik dashboard by default. I intend to add an oauth_proxy pod to secure this, in a future recipe update.

Prepare phone-home pod

Remember how our load balancer design ties a phone-home container to another container using a pod, so that the phone-home container can tell our external load balancer (using a webhook) where to send our traffic?

Since we deployed Traefik using helm, we need to take a slightly different approach, so we'll create a pod with an affinity which ensures it runs on the same host which runs the Traefik container (more precisely, containers with the label app=traefik).

Create phone-home.yaml as follows:

apiVersion: v1
kind: Pod
  name: phonehome-traefik
      - labelSelector:
          - key: app
            operator: In
            - traefik
        - image: funkypenguin/poor-mans-k8s-lb
          imagePullPolicy: Always
          name: phonehome-traefik
          - name: REPEAT_INTERVAL
            value: "600"
          - name: FRONTEND_PORT
            value: "443"
          - name: BACKEND_PORT
            value: "30443"
          - name: NAME
            value: "traefik"
          - name: WEBHOOK
            value: "https://<your loadbalancer hostname>:9000/hooks/update-haproxy"
          - name: WEBHOOK_TOKEN
                name: traefik-credentials
                key: webhook_token.secret

Create your webhook token secret by running:

echo -n "imtoosecretformyshorts" > webhook_token.secret
kubectl create secret generic traefik-credentials --from-file=webhook_token.secret


Yes, the "-n" in the echo statement is needed. Read here for why.


Install the chart

To install the chart, simply run helm install stable/traefik --name traefik --namespace kube-system

That's it, traefik is running.

You can confirm this by running kubectl get pods, and even watch the traefik logs, by running kubectl logs -f traefik<tab-to-autocomplete>

Deploy the phone-home pod

We still can't access traefik yet, since it's listening on port 30443 on node it happens to be running on. We'll launch our phone-home pod, to tell our load balancer where to send incoming traffic on port 443.

Optionally, on your loadbalancer VM, run journalctl -u webhook -f to watch for the container calling the webhook.

Run kubectl create -f phone-home.yaml to create the pod.

Run kubectl get pods -o wide to confirm that both the phone-home pod and the traefik pod are on the same node:

# kubectl get pods -o wide
NAME                       READY     STATUS              RESTARTS   AGE       IP           NODE
phonehome-traefik          1/1       Running             0          20h   gke-penguins-are-sexy-8b85ef4d-2c9g
traefik-69db67f64c-5666c   1/1       Running             0          10d   gkepenguins-are-sexy-8b85ef4d-2c9g

Now browse to https://, and you should get a valid SSL cert, along with a 404 error (you haven't deployed any other recipes yet)

Making changes

If you change a value in values.yaml, and want to update the traefik pod, run:

helm upgrade --values values.yml traefik stable/traefik --recreate-pods


We're doneburgers! 🍔 We now have all the pieces to safely deploy recipes into our Kubernetes cluster, knowing:

  1. Our HTTPS traffic will be secured with LetsEncrypt (thanks Traefik!)
  2. Our non-HTTPS ports (like UniFi adoption) will be load-balanced using an free-to-scale external load balancer
  3. Our persistent data will be automatically backed up

Here's a recap:

  • Start - Why Kubernetes?
  • Design - How does it fit together?
  • Cluster - Setup a basic cluster
  • Load Balancer Setup inbound access
  • Snapshots - Automatically backup your persistent data
  • Helm - Uber-recipes from fellow geeks
  • Traefik (this page) - Traefik Ingress via Helm

Where to next?

I'll be adding more Kubernetes versions of existing recipes soon. Check out the MQTT recipe for a start!

Chef's notes 📓

  1. It's kinda lame to be able to bring up Traefik but not to use it. I'll be adding the oauth_proxy element shortly, which will make this last step a little more conclusive and exciting! 

Tip your waiter (sponsor) 👏

Did you receive excellent service? Want to make your waiter happy? (..and support development of current and future recipes!) Sponsor me on Github / Patreon, or see the contribute page for more (free or paid) ways to say thank you! 👏

Flirt with waiter (subscribe) 💌

Want to know now when this recipe gets updated, or when future recipes are added? Subscribe to the RSS feed, or leave your email address below, and we'll keep you updated. (*double-opt-in, no monkey business, no spam)

Notify me 🔔

Be the first to know when recipes are added / improved!

    We won't send you spam. Unsubscribe at any time. No monkey-business.

    Powered By ConvertKit

    Your comments? 💬

    Last update: January 9, 2021