Learn how to setup Traefik 2.2 on Kubernetes and how to automatically get TLS wildcard certificates.

Traefik is a modern Web server made in the cloud era so it’s authors define it as a Cloud Native edge router. It is written in Go and it’s maybe not as fast as nginx or HAProxy, but it is fast enough and in the same time it has great features not present in traditional Web servers. These features include automatic care of TLS certificates, nice control panel, support for Docker stacks and Kubernetes, etc.

Version 1.x of Traefik didn’t have CRD’s and supported just normal Kubernetes Ingress resource. However, version 2.0 contained breaking changes and continued supporting basic functionalities of Kubernetes Ingress but in order to use advanced features it was necesarry to use IngressRoute CRD provided by Traefik itself. This means if you use Helm, for example, to install your applications, you couldn’t setup proper ingress. I had exactly this case so I had to use raw chart to install custom IngressRoute for each application which broke encapsulation and didn’t look tidy.

Fortunatelly, since version 2.2 it is possible to use advanced features of Traefik even with normal Kubernetes Ingress thanks to special annotations . This way Traefik is again fully compatible with Kubernetes but doesn’t require any custom resources for the advanced functionality. In this article I want to show how to set this up using helmfile .

First let’s install Traefik itself:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
releases:
  - name: traefik
    chart: traefik/traefik
    values:
      - additionalArguments:
          - --entrypoints.web.http.redirections.entryPoint.to=:443
          - --entrypoints.web.http.redirections.entryPoint.scheme=https
          - --entrypoints.web.http.redirections.entryPoint.priority=10000
          - --certificatesresolvers.default.acme.storage=/data/acme.json
          - --certificatesresolvers.default.acme.email=john.doe@example.io
          - --certificatesresolvers.default.acme.dnsChallenge.provider=digitalocean
      - env:
          - name: DO_AUTH_TOKEN
            value: { { requiredEnv "DO_AUTH_TOKEN" } }

Using additional arguments we redirect all traffic from http to https, we don’t want any unencrypted traffic. Then we also define our certificate resolver to DNS challenge, in my case DigitalOcean. You can find the full list of supported providers here .

Now, let’s see what annotations do we need on the Ingress object. Let’s see an example application:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
- name: example
  chart: charts/example
  values:
    - ingress:
        enabled: true
        annotations:
          traefik.ingress.kubernetes.io/router.entrypoints: websecure
          traefik.ingress.kubernetes.io/router.tls: 'true'
          traefik.ingress.kubernetes.io/router.tls.certresolver: default
          traefik.ingress.kubernetes.io/router.tls.domains.0.main: 'example.io'
          traefik.ingress.kubernetes.io/router.tls.domains.0.sans: '*.example.io'
        hosts:
          - host: example.io
            paths: ['/']
          - host: www.example.io
            paths: ['/']

Traefik contains by default two entry points, web (http) and websecure (https). As we set the redirection from http to https, we care just about websecure entry point. Then we turn on TLS and specify to use default resolver (yes, you may have many resolvers). Finally we tell Traefik that our certificate should be for the main domain example.io and also for the wildcard domain _.example.io. At your DNS provider you need to have A records for @ and _ pointing to the right IP address. Finally we define that this ingress will be activated for hosts example.io and www.example.io and we are done.

Or we are almost done. Why almost? Well, we have a glitch here. Our ingress will be activated if the hostname is example.io or www.example.io and this is not good for SEO, one of these hostnames should be redirected to another so that we only have one hostname. Search engines won’t like to have two hostnames with exactly the same contents. We can achieve these using middlewares in Traefik, but more about that in the following article. Have a nice traefiking ?