Un certificat TLS qui expire un dimanche soir est l’un des rares incidents qui touchent tout le monde en même temps, sans avertissement progressif : la veille, tout fonctionne ; le lendemain, chaque navigateur affiche un avertissement de sécurité. cert-manager existe précisément pour retirer cette date d’expiration de la liste des choses qu’une équipe doit surveiller manuellement.

Ce qu’un Ingress fait, et ne fait pas tout seul

Une ressource Ingress décrit des règles de routage HTTP(S) : quel nom de domaine et quel chemin doivent atteindre quel Service interne. Elle ne fait rien par elle-même, elle a besoin d’un Ingress Controller (nginx-ingress, Traefik, ou autre) qui tourne dans le cluster et traduit ces règles en configuration réelle.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: nginx
  tls:
    - hosts: ["app.example.com"]
      secretName: app-tls
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app-service
                port:
                  number: 80

L’annotation cert-manager.io/cluster-issuer est le seul lien entre l’Ingress et l’automatisation TLS : sans elle, le champ tls ne sert à rien, puisqu’aucun processus ne remplirait jamais le secret app-tls qu’il référence.

Ce que cert-manager automatise réellement

cert-manager surveille les ressources Ingress (ou des ressources Certificate dédiées) et, dès qu’il en trouve une annotée avec un ClusterIssuer valide, déclenche automatiquement une demande de certificat auprès de l’autorité configurée, typiquement Let’s Encrypt via le protocole ACME. Le certificat obtenu est stocké comme Secret Kubernetes, et cert-manager surveille sa date d’expiration pour déclencher un renouvellement bien avant l’échéance, sans intervention humaine.

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: admin@example.com
    privateKeySecretRef:
      name: letsencrypt-prod-key
    solvers:
      - http01:
          ingress:
            ingressClassName: nginx

Le piège HTTP-01 : un challenge qui suppose que le DNS pointe déjà là

La méthode de validation la plus simple, HTTP-01, demande à Let’s Encrypt de faire une requête HTTP vers le domaine à certifier, sur un chemin précis (/.well-known/acme-challenge/...), pour vérifier que le demandeur contrôle bien ce domaine. cert-manager crée temporairement un Ingress et un pod dédiés pour répondre à cette requête. Le piège : cette validation suppose que le DNS du domaine pointe déjà vers le cluster au moment de la demande. Sur une infrastructure encore en cours de bascule, avec un token API de DNS qui ne couvre pas la zone concernée, ou avec une NetworkPolicy en deny-all qui bloque les pods éphémères du solver, le certificat reste indéfiniment en attente sans qu’aucun message d’erreur explicite ne le signale au premier coup d’œil (kubectl describe challenge reste la commande la plus directe pour voir la cause réelle).

L’alternative, DNS-01, valide en créant un enregistrement TXT temporaire chez le fournisseur DNS plutôt qu’en exposant un chemin HTTP : elle fonctionne même quand le domaine ne pointe pas encore vers le cluster, ce qui la rend plus adaptée aux certificats wildcard ou aux migrations en cours, au prix d’un accès API au DNS qu’il faut configurer correctement.

Où ça se range

Exposer un service en HTTPS sans certificat qui expire un jour férié fait partie du socle posé lors d’une migration Kubernetes : versionné, automatisé, sans étape manuelle récurrente. C’est aussi un mécanisme que ce site utilise réellement pour son propre certificat.

À retenir

Un Ingress route le trafic mais ne gère aucun certificat par lui-même ; cert-manager comble ce vide en automatisant la demande et le renouvellement via Let’s Encrypt. HTTP-01 est la méthode la plus simple mais suppose que le DNS pointe déjà vers le cluster, ce qui la rend fragile en pleine migration ; DNS-01 lève cette contrainte au prix d’un accès API DNS correctement scopé.