Blog

Traefik v2 & Helm

Helm Chart & Traefik

Hello everyone, and welcome to our quick tour of the Traefik 2 Helm Chart, my favorite way of installing Traefik on Kubernetes.

Today, we'll walk you through common scenarios to get you started. By the end of the article, you'll have a fully functional service exposed in https (and a beautiful dashboard to look at).

But before we go further, I'll ask you to make sure you have at your disposal a docker environment with k3d installed. In case you don't know k3d, I'm also glad to introduce you to this convenient tool that helps you, I quote, "create single- and multi-node k3s clusters in docker, e.g. for local development on Kubernetes".

So, Ready?

Preparing the K3S Cluster

K3S is my favorite (lightweight) Kubernetes distribution that I use on a daily basis to set up all kind of environments. So, let's set up a cluster in one command line!

k3d create --server-arg "--no-deploy=traefik" \
--workers=2 \
--publish="80:80" \
--publish="443:443"

This command is almost self-explanatory: it creates a k3s cluster, exposes (and map) port 80 and 443, and disables the deployment of the ingress controller (which is by default Traefik v1).

Installing Traefik v2

First, the HelmChart

The official TraefikV2 HelmChart is hosted on a Containous repository. If you're wondering why it's not hosted on the former known "official repository", it's just because it's now deprecated.

So, first things first, you need to add Traefik's HelmChart repository, like so:

helm repo add traefik https://containous.github.io/traefik-helm-chart

And like usual, you'll need to ask helm to download the updates:

helm repo update

You can now see if helm knows about the new helm chart using the helm search command, like so:

helm search repo traefik
NAME           	CHART VERSION	APP VERSION	DESCRIPTION
stable/traefik 	1.86.2       	1.7.20     	A Traefik based Kubernetes ingress controller w...
traefik/traefik	6.0.2        	2.1.3      	A Traefik based Kubernetes ingress controller

Yes, two charts are available:

  • stable/traefik comes from the deprecated stable repository and is for traefik v1,
  • traefik/traefik comes from the traefik repository and is for traefik v2.

So, we're interested in Traefik version 2, our choice is obvious!

helm install traefik traefik/traefik

And… that's it: you have a fully configured Traefik able to handle Ingress Objects (and Traefik custom CRD).

Accessing the Dashboard

By default, the dashboard is enabled but not accessible from the outside (for security purposes). For now, if you want to access it, use the following command:

kubectl port-forward $(kubectl get pods --selector "app.kubernetes.io/name=traefik" --output=name) 9000:9000

With a forwarded local port 9000 to port 9000 on the traefik pod (where the dashboard lives), we can access http://127.0.0.1:9000/dashboard/ and contemplate.

traefik-dashboard

Exposing an Application on "example.org"

If you're here, chances are you're familiar with Kubernetes. So let's keep explanations to a minimum. In the following file, we create a new deployment for our application, and then an Ingress Object to route requests to the corresponding service.

# whoami.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
  name: app-v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app-v1
  template:
    metadata:
      labels:
        app: app-v1
    spec:
      containers:
        - name: app-v1
          image: containous/whoami:v1.5.0

---
apiVersion: v1
kind: Service
metadata:
  name: app-v1
  labels:
    app: app-v1
spec:
  type: ClusterIP
  ports:
    - port: 80
      name: app-v1
  selector:
    app: app-v1

---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: app
  annotations:
    kubernetes.io/ingress.class: traefik
    traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
  rules:
    - host: example.org
      http:
        paths:
          - backend:
              serviceName: app-v1
              servicePort: 80
kubectl apply -f whoami.yml

And once deployed, you can immediately see the new route in the dashboard.

traefik-dashboard-rule

And of course, we can access the application, which is the whole purpose:

curl -H "Host:example.org" 127.0.0.1

Hostname: whoami-589c447684-xcwkq
IP: 127.0.0.1
IP: ::1
IP: 10.42.0.4
IP: fe80::2471:c3ff:fe0b:9b15
RemoteAddr: 10.42.1.3:54068
GET / HTTP/1.1
Host: example.org
User-Agent: curl/7.64.1
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.42.2.3
X-Forwarded-Host: example.org
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: traefik-bd4666c8d-xjhc5
X-Real-Ip: 10.42.2.3

Levereging HTTPS

The plan now is to:

  1. Configure a system that will automatically generate certificates (because we don't like to buy/renew certificates if Traefik can do it)
  2. Use this system on our routes
    And all this is a matter of 5 lines of configuration.

Configuring Automatic Certificate Generation

We will add custom parameters to our Traefik installation. To do so, create a values.yaml file with the following content:

# values.yaml
additionalArguments:
  - [email protected](opens in new tab)
  - --certificatesresolvers.le.acme.storage=/data/acme.json
  - --certificatesresolvers.le.acme.tlschallenge=true
persistence:
  enabled: true
  path: /data

The above lines configure a certificatesresolver that we call le. It's an acme resolver, and it needs our email (your account), a storage path (where certificates will be stored), and a challenge (how you will prove that you own the domain you request a certificate for). We don't need to go into further details here, but if so, there is an exhaustive documentation available.

Note: You can see every available option in values.yaml file on github.

Now, time to upgrade your Traefik installation with the new certificate resolver!

helm upgrade traefik traefik/traefik --values values.yaml

Using HTTPS on your Routes

Now that Traefik can generate certificates for us, all we have to do is tell Traefik which route uses tls, here, on our route (with 2 lines):

# whoami-tls.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: app-tls
spec:
  entryPoints:
    - websecure
  routes:
    - kind: Rule
      match: Host(`example.org`)
      services:
        - name: app-v1
          port: 80
  tls: # This route uses TLS
    certResolver: le # Uses our certificate resolver to get a certificate automatically!
kubectl apply -f whoami-tls.yml

traefik-dashboard-rule-tls

Redirecting HTTP to HTTPS

Now that you've enabled HTTPS, you might want to redirect all HTTP requests to HTTPS. And good news, we can do it once and for all on our http entrypoint!

# values.yaml
additionalArguments:
  - [email protected](opens in new tab)
  - --certificatesresolvers.le.acme.storage=/data/acme.json
  - --certificatesresolvers.le.acme.tlschallenge=true
  - --entrypoints.web.http.redirections.entryPoint.to=:443
  - --entrypoints.web.http.redirections.entryPoint.scheme=https
persistence:
  enabled: true
  path: /data
helm upgrade traefik traefik/traefik --values values.yaml

Release "traefik" has been upgraded. Happy Helming!
NAME: traefik
LAST DEPLOYED: Mon May 18 20:51:26 2020
NAMESPACE: default
STATUS: deployed
REVISION: 3
TEST SUITE: None

We added two lines there:

  • --entrypoints.web.http.redirections.entryPoint.to=:443 says that the entrypoint web that listens for http requests (entrypoints.web.http) will now redirect its traffic to port 443 (redirections.entryPoint.to=:443)
  • --entrypoints.web.http.redirections.entryPoint.scheme=https says that the same entrypoint (entrypoints.web.http) will redirect everything to HTTPS (redirections.entryPoint.scheme=https)

Now that you know what we did, let's apply the changes:

helm upgrade traefik traefik/traefik --values values.yaml

Release "traefik" has been upgraded. Happy Helming!
NAME: traefik
LAST DEPLOYED: Mon May 18 12:23:25 2020
NAMESPACE: default
STATUS: deployed
REVISION: 3
TEST SUITE: None

And let's see what's happening if we keep trying to send an HTTP request… (spoiler, we'll get redirected):

curl -I -H "Host:example.org" 127.0.0.1

HTTP/1.1 308 Permanent Redirect
Location: https://example.org/
Date: Mon, 18 May 2020 10:24:14 GMT
Content-Length: 18
Content-Type: text/plain; charset=utf-8

And a proper HTTPS request will of course work as expected:

curl -H "Host:example.org" https://127.0.0.1

Hostname: app-v1-59f4ddfc4-7kbhf
IP: 127.0.0.1
IP: ::1
IP: 10.42.1.5
IP: fe80::78ae:28ff:fe9c:9c12
RemoteAddr: 10.42.2.6:36824
GET / HTTP/1.1
Host: example.org
User-Agent: curl/7.64.1
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.42.2.3
X-Forwarded-Host: example.org
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Forwarded-Server: traefik-56587bcf5b-c2w6r
X-Real-Ip: 10.42.2.3

Securing and Exposing the Dashboard

To securely expose the dashboard, we'll leverage Traefik's CRD to create a basicauth middleware, and use it on a new route to the dashboard.

# dashboard.yml
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: dashboard
spec:
  entryPoints:
    - websecure
  routes:
    - kind: Rule
      match: Host(`dashboard.example.org`)
      services:
        - name: [email protected] # The internal name of the Dashboard for Traefik
          kind: TraefikService
      middlewares:
        - name: dashboard-auth #Referencing the BasicAuth middleware
  tls:
    certResolver: le # Of course, we want this to be https

---
apiVersion: v1
kind: Secret
metadata:
 name: dashboard-auth-secret
data:
 users: dXNlcjokYXByMSRkZW9mb25TcCR0OGwxMEZvbm4vT2Y2RXAuVFJ6bnEuCgo=

---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: dashboard-auth
spec:
  basicAuth:
    secret: dashboard-auth-secret # You can store users in secrets!
kubectl apply -f dashboard.yml

And the dashboard is now available on https://dashboard.example.org, and will require a user/password!

traefik-dashboard-rule-tls-auth

traefik-dashboard-rule-tls-auth-success

Wrapping Up

The Traefik 2 Helm Chart is probably one of the easiest ways to install Traefik on Kubernetes. Moreover, it is compatible with every option you need (with the help of the additionalArguments section) and will ensure your Traefik is always up to date.

If you have questions, feedback, or ideas, please reach out in our community forum, I'll be glad to discuss and help!