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".
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
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/traefikcomes from the deprecated stable repository and is for traefik v1,
traefik/traefikcomes 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
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
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=:443says that the entrypoint web that listens for http requests (
entrypoints.web.http) will now redirect its traffic to port 443 (
--entrypoints.web.http.redirections.entryPoint.scheme=httpssays that the same entrypoint (
entrypoints.web.http) will redirect everything to 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!
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/