HemChart & 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.
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.
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:
- Configure a system that will automatically generate certificates (because we don't like to buy/renew certificates if Traefik can do it)
- 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
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!
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!
This is a companion discussion topic for the original entry at https://containo.us/blog/traefik-v2-helm/