- Simplest solution to secure your routes as it is transparently managed by the Traefik Proxy and the provided
- No much control of your certificates as they are internally managed by Traefik using our
- Risk to reached the LetsEncrypt rates limits if you create lot of routes at once or if your route configuration is wrong and the LetsEncrypt challenge fails several times (see Best Practices)
- the LetsEncrypt HTTP-01 challenge doesn’t allow wildcard certificates
# http: scheme route redirected to https: scheme. apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: example spec: # http entry point entryPoints: - http # route rules definition routes: # list of rules - kind: Rule match: Host(`test.example.com`) # redirect middleware middlewares: - name: https-redirect namespace: traefik # backend Kubernetes service services: - name: my-service port: 8080 --- # secured route (https scheme) with "default" certificate resolver apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: example-tls spec: # https entry point entryPoints: - https routes: - kind: Rule match: Host(`test.example.com`) # backend Kubernetes service services: - name: my-service port: 8080 tls: # TLS certificate resolver certResolver: default
That’s it! Traefik is doing all the certificate generation and renewal processes internally.
the API Group will be changed in Traefik 3+ from
traefik.io/v1alpha1. You can start to use the new group but pay attention to the
CustomResourceDefinitionwhen you retrieve your resources (two
To facilitate the TLS challenge and avoid the LetsEncrypt rate limits you should follow the following recommendations:
- (required) The backend service has to be up and running and able to answer the LetsEncrypt challenge with a 200 http status response code before to deploy the secured route (you could check your service is running by using
kubectl port-forward service...).
- (mandatory) If you are using your own domain, make sure the routes are redirected to edge.h8l.io (CNAME record to edge.h8l.io or A record to the load balanced IP of edge.h8l.io) and the DNS propagation has been done (LetsEncrypt could perform the HTTP-01 challenge from the US)
- If your route rules are complex, you can help Traefik to resolve the hosts to challenge by specifying the tls domains
- You can group your routes in a single
IngressRouteand/or in a single
Host(`a.b.com`,...,`c.b.com`)to help Traefik to resolve the hosts and limit the number of challenge and
The h8lio integrates cert-manager to manage your certificates. It allows to get more control of your certificates and share them with multiple Kubernetes resources.
The cert-manager h8lio integration is quite recent (
alphastage). Every feedback are welcome.
- Finely manage your certificates
- Provide your own certificate issuers or self-signed certificates
- Possibility to use the cert-manager command line tool
- Allow wildcard certificate management using the LetsEncrypt DNS-01 challenge and avoid the LetsEncrypt rate limits if you have a lot of secured routes to create (in case of migration for example)
- Easy integration within your Traefik
- More complex to use compare to the integrated Traefik certificate resolver
- You become the manager of your certificates
- External management of the DNS-O1 Challenge Provider
The following example shows how to create and use a wildcard certificate using cert-manager and LetsEncrypt DNS-O1 challenge on a OVH managed domain.
- Create a secret holding the OVH API credentials in the cluster where you want to use the certificate:
apiVersion: v1 kind: Secret type: Opaque metadata: name: ovh-<domain>-api data: applicationKey: <base64 encoded application key> applicationSecret: <base64 encoded application secret> consumerKey: <base64 encoded consumer key>
<...>by the value of your choice
you can use sealed-secret if you want to securely store the secret outside of the h8lio Kubernetes Cluster (example, in a Git repository)
- Create your cert-manager
Issuerusing LetsEncrypt and the OVH challenge provider:
apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: ovh-<domain> spec: acme: # LetsEncrypt production server server: "https://acme-v02.api.letsencrypt.org/directory" # email or mailing list used for the LetsEncrypt account email: <firstname.lastname@example.org> # reference to the secret holding your LetsEncrypt account key # it will be created by cert-manager if it doesn't exist privateKeySecretRef: name: "ovh-<domain>-account-key" solvers: # DNS-01 challenge configuration - dns01: cnameStrategy: "None" # OVH DNS-01 challenge webhook configuration webhook: solverName: ovh # do not change this value groupName: acme.h8l.io # do not change this value config: # OVH zone endpoint: ovh-eu # OVH credentials from the secret # adapts the name: and key: based of your configuration applicationKeyRef: name: ovh-<domain>-api key: "applicationKey" applicationSecretRef: name: ovh-<domain>-api key: "applicationSecret" consumerKeyRef: name: ovh-<domain>-api key: "consumerKey"
Issuer manifest has been applied to your cluster. You can check the events and
status: of the
CustomResourceDefinition to validate its configuration and its readiness.
It should look like:
status: acme: lastPrivateKeyHash: yTty... lastRegisteredEmail: email@example.com uri: https://acme-v02.api.letsencrypt.org/acme/acct/12345... conditions: - lastTransitionTime: '2023-08-05T13:58:40Z' message: The ACME account was registered with the ACME server observedGeneration: 2 reason: ACMEAccountRegistered status: 'True' type: Ready
- Create the cert-manager
Certificate’s secret using the previous
Issuerwhich will be used in the
apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: ovh-<domain> spec: # replace with your domain # it could be a second level subdomain (ie. "*.sub.domain.com") commonName: "*.domain.com" dnsNames: - "*.domain.com" issuerRef: group: cert-manager.io kind: Issuer name: ovh-<domain> # the issuer name secretName: ovh-<domain>-cert # the name of the secret which will hold the certificate
Certificate manifest has been applied to your cluster. You can check the events and
status: of the
CustomResourceDefinition to validate its configuration and its readiness.
This operation could take few seconds while cert-manager is internally managing the creation of all the resources involved in the DNS-01 challenge process to create the secret containing the new Certificate. It should look like:
status: conditions: - lastTransitionTime: '2023-08-07T07:44:14Z' message: Certificate is up to date and has not expired observedGeneration: 1 reason: Ready status: 'True' type: Ready notAfter: '2023-11-05T06:44:12Z' notBefore: '2023-08-07T06:44:13Z' renewalTime: '2023-10-06T06:44:12Z' revision: 1
If the certificate generation process is successful, you should see your
ovh-<domain>-cert secret with the two tls file entries:
kind: Secret apiVersion: v1 metadata: name: ovh-<domain>-cert annotations: # cert-manager annotations cert-manager.io/alt-names: ... cert-manager.io/certificate-name: ... cert-manager.io/common-name: ... cert-manager.io/ip-sans: ... cert-manager.io/issuer-group: ... cert-manager.io/issuer-kind: ... cert-manager.io/issuer-name: ... cert-manager.io/uri-sans: ... data: tls.crt: >- LS0t... tls.key: >- LS0t... type: kubernetes.io/tls
- Use your certificate secret in your Traefik
IngressRoutes(as many times you need):
# secured route (https scheme) with your certificate from a cert-manager secret apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: example-tls spec: # https entry point entryPoints: - https routes: - kind: Rule # rule's match using subdomains of the generated wildcard certificate match: Host(`test.domain.com`,`demo.domain.com`) # backend Kubernetes service services: - name: my-service port: 8080 tls: # TLS certificate secret reference secretName: ovh-<domain>-cert
No LetsEncrypt challenge is done by Traefik when you deploy this secured route as it has already been done and managed by the cert-manager (avoiding also the LetsEncrypt Rate Limits).
If not already present, you may want to create an
h8lio-tls secret holding the certificate for the routes
apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: h8lio namespace: <domain-cluster> spec: commonName: "*.<domain-cluster>.h8l.io" dnsNames: - "*.<domain-cluster>.h8l.io" issuerRef: group: cert-manager.io kind: ClusterIssuer # cluster wide h8l.io issuer using LetsEncrypt # ⚠️ works only for the h8l.io subdomains name: h8lio-issuer # target secret name holding the secretName: h8lio-tls
<domain-cluster> with your namespace and apply this manifest.
After few seconds (checks the Certificate events/status), the
h8lio-tls secret should be generated and can be used in you ingress routes
apiVersion: traefik.io/v1alpha1 kind: IngressRoute ... spec: entryPoints: - https routes: - ... tls: secretName: h8lio-tls
Remember to change your pipelines and/or helm chart to uses the new TLS configuration
If you are using the secret name, don’t mix your domain’s routes rules with the h8l.io ones. The generated certificate will only work for the specified h8l.io