Here I share the recipe for how to setup High Availability Traefik Proxy (multiple instances) for Kubernetes with TLS certificates obtained from LetsEncrypt with help of Cert Manager.
To get high availability setup for Traefik we will host multiple instances of Traefik on different hosts (or even in different availability zones). All of the Traefik instances need to load the same TLS certificates and equally participate in ACME http challenge process during obtaining the certificates from LetsEncrypt. Both can be achieved by using Cert Manager, which stores the TLS certificates in Kubernetes secrets (no need for PVC) and carries out LetEncrypt ACME http challenge through Kubernetes Ingress entities. We leave deployment of Cert Manager out of scope for this post. The following assumes that you have Cert Manager deployed.
Configuring Cert Manager for LetsEncrypt
In order to get certificates from LetsEncrypt we can define the following Issuers (CRD used by Cert Manager):
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-staging spec: acme: server: https://acme-staging-v02.api.letsencrypt.org/directory email: firstname.lastname@example.org # Replace this with your mail address privateKeySecretRef: name: letsencrypt-staging solvers: - http01: ingress: class: traefik --- apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: email@example.com # Replace this with your mail address privateKeySecretRef: name: letsencrypt-prod solvers: - http01: ingress: class: traefik
Configuring Traefik for Cert Manager
Note that we specified the “traefik” ingress class among ACME solvers. That is how Cert Manager will get the TLS certificates for our domains. Cert Manager can’t use IngressRoute CRD defined for Traefik as they are too application specific. Instead, it can use standard Ingress or newly emerged Gateway API Kubernetes entities. Here we use Ingress. That means that we need to enable Traefik to serve Kubernetes Ingress entities. That can be done, for instance, through CLI args:
... spec: containers: - name: traefik image: traefik:v2.9 args: - --entrypoints.web.Address=:80 - --entrypoints.websecure.Address=:443 - --providers.kubernetescrd # needed for IngressRoutes - --providers.kubernetesingress # needed for cert-manger ports: - name: web containerPort: 80 - name: websecure containerPort: 443
If you use IngressRoutes then you will have to enable both kubernetescrd and kubernetesingress Traefik configuration providers.
Defining “certificate” for IngressRoute
Now the Cert Manager will be able to finish the ACME http challenge for our domains. At this point we can define a certificate to obtain from LetsEncrypt. The following example defines the certificate that is used at this blog (note that you can define multiple DNS names for single certificate).
apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: grechka.family-tls-cert spec: secretName: grechka.family-tls-secret issuerRef: name: letsencrypt-prod kind: ClusterIssuer dnsNames: - grechka.family - www.grechka.family
Right after we create this entity in Kubernetes, Cert Manager will acquire the certificate. Now we can use the certificate in Traefik IngressRoute, like in the following example:
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: tls-dmitry-web-blog spec: ... tls: secretName: grechka.family-tls-secret
That’s it! We have high availability Traefik with LetsEncrypt certificates.