Install And Configure Traefik with Helm

Guest post by Traefik Ambassador, Robin Scherrer and Daniele Di Rosa aka Containeroo.

When we started our container journey with Docker some years ago, we looked for an easy to configure reverse proxy to expose our services to the internet. Daniele had seen a video about the best Docker projects where Emile Vauge, founder of Traefik, delivered a presentation about Traefik. And, we decided to give Traefik a shot. We started with using Traefik 1.x, and then moved to Traefik 2.0 a couple of years later.

When Traefik 2.0 was released, we spent the weekend figuring out how it works, and the next week, decided to help others have a tremendous “getting started” experience by writing a simple step by step guide. And, with our roles on the Kubernetes team at work, we went on to replace the existing reverse proxy Ambassador with Traefik.

The Tutorial

In this tutorial, we will show you how to install and configure Traefik using the official Helm chart. We will also show you how to configure Traefik with Cloudflare. This makes wildcard Let's Encrypt certificates possible. Helm makes it easy to deploy applications onto your Kubernetes cluster. Even though Traefik supports both Ingress as well as Traefik IngressRoute, we prefer to use the CRD instead of Ingress which results in a lot of annotations.

Prerequisites

  • Kubernetes Cluster
  • Helm official docs
  • Kubeconfig file for Helm to access your Kubernetes Cluster (~/.kube/config)

Prepare Helm Chart

First, you’ll need to add the official Helm repository to your Helm client. You can do that by issuing the following command:

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

In order to configure the Helm chart, you'll need to specify certain values. You can find all the values possible here. Open your favourite editor and set the values you want to change. Here is an example traefik-chart-values.yaml file:

additionalArguments:
- --providers.file.filename=/data/traefik-config.yaml
- --entrypoints.websecure.http.tls.certresolver=cloudflare
- --entrypoints.websecure.http.tls.domains[0].main=example.com
- --entrypoints.websecure.http.tls.domains[0].sans=*.example.com
- --certificatesresolvers.cloudflare.acme.dnschallenge.provider=cloudflare
- --certificatesresolvers.cloudflare.acme.email=mail@example.com
- --certificatesresolvers.cloudflare.acme.dnschallenge.resolvers=1.1.1.1
- --certificatesresolvers.cloudflare.acme.storage=/certs/acme.json
ports:
web:
redirectTo: websecure
env:
- name: CF_API_EMAIL
valueFrom:
secretKeyRef:
key: email
name: cloudflare-api-credentials
- name: CF_API_KEY
valueFrom:
secretKeyRef:
key: apiKey
name: cloudflare-api-credentials
ingressRoute:
dashboard:
enabled: false
persistence:
enabled: true
path: /certs
size: 128Mi
volumes:
- mountPath: /data
name: traefik-config
type: configMap

With this values file, you are configuring Traefik to:

  • use /data/traefik-config.yaml as a static configuration file
  • use Cloudflare as a certificates resolver
  • set the domain example.com as the certificates main domain
  • set *.example.com as the certificates sans
  • store the certificates in /certs/acme.json

Install Traefik

As a first step, you’ll need to create a Kubernetes namespace:

kubectl create namespace traefik

Before you deploy the Helm chart, you’ll need to add the secret containing the Cloudflare credentials along with the configmap including the static configuration. Create a traefik-config.yaml file with the following content:

---
apiVersion: v1
kind: Secret
metadata:
name: cloudflare-api-credentials
namespace: traefik
type: Opaque
stringData:
email: your@cloudflare.email
apiKey: YOURCLOUDFLAREAPIKEY
---
apiVersion: v1
kind: ConfigMap
metadata:
name: traefik-config
namespace: traefik
data:
traefik-config.yaml: |
http:
middlewares:
headers-default:
headers:
sslRedirect: true
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 15552000
customFrameOptionsValue: SAMEORIGIN

As an example, we've added a headers-default middleware. For the complete static configuration, please consult the Traefik docs. Next, you can apply the secret and configmap you created above:

kubectl apply -f traefik-config.yaml

This will create the secret and configmap in the traefik namespace. Now it's time to deploy Traefik! The following command will install Traefik in the traefik namespace and with the configuration you created above::

helm install traefik traefik/traefik --namespace=traefik --values=traefik-chart-values.yaml

Make the Dashboard Accessible

In order to access the Traefik dashboard, you’ll first need to create an HTTP basic auth middleware. This also requires a secret with the htpasswd credentials. Use the following command to create a base64 encoded htpasswd file with a kangoroo user and the password jack:

htpasswd -nb kangoroo jack | openssl base64

Apply the secret and the middleware to your Kubernetes cluster:

---
apiVersion: v1
kind: Secret
metadata:
name: traefik-dashboard-auth
namespace: traefik
data:
users: |2
a2FuZ29yb286JGFwcjEkdGlQbFBINXYkYlJrUHBSUlYuYUxUWnhFRzdYbmduMAoK
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: traefik-dashboard-basicauth
namespace: traefik
spec:
basicAuth:
secret: traefik-dashboard-auth

Now you can apply the following traefik-dashboard-ingressroute.yaml file:

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard
namespace: traefik
spec:
entryPoints:
- websecure
routes:
- match: Host(`traefik.example.com`)
kind: Rule
middlewares:
- name: traefik-dashboard-basicauth
namespace: traefik
services:
- name: api@internal
kind: TraefikService

Please change the matching host rule accordingly under the routes section. Since Traefik exposes the dashboard in a special way, you’ll need to tell the IngressRoute to use the preconfigured service named api@internal with kind TraefikService.

The IngressRoute CRD

As we've mentioned above, Traefik both supports Ingress and IngressRoute as a configuration. The CRD has a few advantages:

  • eliminate or reduce the number of annotations on the Ingress controllers
  • abstract commonly used rules and configuration
  • separate concerns across multiple use-cases and configurations To deploy a simple whoami application service, please refer to the appendix. Here is an example IngressRoute for the whoami service:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: traefik
spec:
entryPoints:
- websecure
routes:
- match: Host(`whoami.example.com`)
kind: Rule
middlewares:
- name: headers-default@file
services:
- name: whoami
port: 80

This IngressRoute tells Traefik to listen via the websecure entrypoint and forward all the traffic matching the host whoami.example.com to the whoami Kubernetes service. It also configures the route to use the headers-default middleware you configured in traefik-config.yaml.

Conclusion

As you can see, getting started with Traefik as an Ingress controller isn't that hard :-) Helm makes it really easy to reconfigure or update Traefik.

Traefik documentation has a lot of good information and can be a great resource once you’ve gotten started using this guide. We bet it will answer most of your questions!

You can find us on Twitter, Medium or GitHub. Feel free to ask any questions regarding Traefik and Kubernetes. We are happy to help!

Appendix

Whoami Example Deployment

---
apiVersion: v1
kind: Pod
metadata:
name: whoami
namespace: traefik
labels:
app: whoami
spec:
containers:
- name: whoami
image: containous/whoami:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
namespace: traefik
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: whoami
type: ClusterIP

About Us

Because of our knowledge in Docker, we were able to switch departments at work, and are now working in the Kubernetes department. One of the first things we did was eliminate the existing reverse proxy and switch to Traefik :-D

Robin: Swiss IT nerd since forever. Interested in open source technologies like Ansible, Docker, Kubernetes, Traefik, Python and Golang. Maintainer of several GitHub repos and Docker images for containeroo. Addicted to music, tv shows and YouTube. Speaking German and English. Twitter, Reddit or GitHub.

Daniele: Couch potato, film and series junky, hobby-columnist for Containeroo, likes Traefik, Ansible, Docker and K8s. Hates corn and dill. Born and raised in Switzerland. Star me on GitHub.


This is a companion discussion topic for the original entry at https://traefik.io/blog/install-and-configure-traefik-with-helm/
1 Like

Thanks that looks easy, i'm going to try.

I appreciate this tutorial because I learned from it.. however.. I'm not totally on board with this.. maybe I'm missing something..

If I'm going to use Traefik as a reverse proxy and I want it to be stateless and totally driven by annotations and IngressRoutes.... then why would I want to set my TLS configuration during my helm installation?

This is the line the specifically stands out to me..

  • --entrypoints.websecure.http.tls.domains[0].main=example.com
  • --entrypoints.websecure.http.tls.domains[0].sans=*.example.com

What if I want to add... more sites..? Do I really have to re-install Traefik every time?

You don't need to "re-install traffic all the time". But you will find yourself in the situation where you update helm charts' values and you need to redeploy the chart.

The entrypoints can be (and should be) perfectly domain-less, and all annotations reside in IngressRoutes.

see :

not a helm chart but a vanilla deployment.

Thank you for this tutorial! I got everything set-up and working on 1st attempt with your guide. Although everything is working fine my logs are flooded with the following: "Skipping TLS sub-section: No secret name provided" namespace=default providerName=kubernetes ingress=tautulli. If i set a secret name I get the following errors: level=error msg="Error configuring TLS: secret default/tautulli-tls does not exist" namespace=default providerName=kubernetes ingress=tautulli. My yaml section:

ingress:
  enabled: true
  annotations:
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
    traefik.ingress.kubernetes.io/tls-acme: "true"
  labels:
    ingressClassName: "traefik"
  hosts:
    - host: tautulli.local
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: tautulli-tls
    - hosts:
       - tautulli.local

Hello @j_r0dd

The first question, what namespace did you create the secret: tautulli-tls?

@jakubhajek I never even created the secret. It was my assumption since using the cloudflare resolver that this was going to be handled automagically for my subdomains. Everything is working fine with the secretName line removed. I just have to turn off debugging as well because the logs were just flooded with TLS errors even though all is working fine on my subdomains afaik. Pardon my noobness with k8s and traefik.

Thank you guys
These are all helpful materials...

I have read your excellent post. This is a great job. I have enjoyed reading your post the first time.
I want to say thanks for this post. Thank you

1 Like

Thanks for a great tutorial. However, the pod fails to startup:

  Type     Reason                  Age                   From                     Message
  ----     ------                  ----                  ----                     -------
  Normal   Scheduled               30m                   default-scheduler        Successfully assigned production/domain-traefik-backend-production-5bc7c5dc6d-d6dcf to gke-domain-cluster-default-pool-cd4dec6c-69j4
  Normal   SuccessfulAttachVolume  30m                   attachdetach-controller  AttachVolume.Attach succeeded for volume "pvc-f601bba5-7e72-4771-b089-717a2e725f04"
  Warning  FailedMount             23m                   kubelet                  Unable to attach or mount volumes: unmounted volumes=[traefik-config], unattached volumes=[tmp traefik-config kube-api-access-hg8wc data]: timed out waiting for the condition
  Warning  FailedMount             14m (x2 over 17m)     kubelet                  Unable to attach or mount volumes: unmounted volumes=[traefik-config], unattached volumes=[kube-api-access-hg8wc data tmp traefik-config]: timed out waiting for the condition
  Warning  FailedMount             10m (x5 over 28m)     kubelet                  Unable to attach or mount volumes: unmounted volumes=[traefik-config], unattached volumes=[data tmp traefik-config kube-api-access-hg8wc]: timed out waiting for the condition
  Warning  FailedMount             8m8s (x2 over 26m)    kubelet                  Unable to attach or mount volumes: unmounted volumes=[traefik-config], unattached volumes=[traefik-config kube-api-access-hg8wc data tmp]: timed out waiting for the condition
  Warning  FailedMount             3m59s (x21 over 30m)  kubelet                  MountVolume.SetUp failed for volume "traefik-config" : configmap "traefik-config" not found
1 Like

I think you issue might come from this

1 Like

hello @trafikduden

You can also have a look at how to install Traefik Proxy through Helm Chart by watching this workshop.
Hope that helps!

2 Likes

Issue with Cloudflare API

Just a bit of a gotcha, that doesn't get explained fully

Reading Lets Encrypt website about Cloudflare, I found that there are 2 types of API's

  • CF_API_KEY - This is your Global API Key
  • CF_DNS_API_TOKEN - Is used when you create an API Token

I used a Token and my Certs weren't working, so a bit of searching found the website above and I changed the value in traefik-chart-values.yaml to the below

  - name: CF_DNS_API_TOKEN  # Change this
    valueFrom:
      secretKeyRef:
        key: apiKey
        name: cloudflare-api-credentials

Then updated the Helm deployment with:

helm upgrade traefik traefik/traefik -f traefik-chart-values.yaml -n traefik

Now my Certs work :slight_smile:

You can configure Traefik by editing the values.yaml file and specifying your desired configuration options. Some common configuration options include:

  • ingressRoute: Configures a route to a Kubernetes service.
  • tls: Configures TLS encryption for the routes.
  • middleware: Configures middleware for the routes.

You can find more information on the available configuration options in the Traefik documentation:

That's it! You have successfully installed and configured Traefik with Helm.

Thanks it's working.

Sure, Keep helping the new visitors of this community. Good initiative.