IT-Admin.tech

Gestion automatisée des certificats TLS dans Kubernetes avec cert-manager et workflows ACME : fiabilité opérationnelle de l'installation initiale au rollback

IT-Operatorin zeigt auf ein Architekturdiagramm zum ACME-Zertifikatsfluss mit cert-manager, Ingress und Kubernetes Secrets.
Das Zusammenspiel aus Ingress, cert-manager, ACME-CA und DNS entscheidet, ob Zertifikate zuverlässig ausgestellt und rechtzeitig erneuert werden.

Le TLS n’est pas, dans l’exploitation quotidienne de Kubernetes, une question de « installer un certificat une fois », mais un processus opérationnel continu : les certificats expirent, les domaines changent, les Ingress-Controller sont migrés, le DNS est délégué, et au pire moment une ACME-Challenge peut échouer. C’est précisément là que Gestion automatisée des certificats TLS dans Kubernetes apporte un bénéfice : vous réduisez les interventions manuelles, évitez les mauvaises surprises liées aux expirations et obtenez des procédures reproductibles pour l’émission, le renouvellement et la rotation.

Cet article explique de manière pragmatique comment cert-manager (un contrôleur Kubernetes pour le cycle de vie des certificats) interagit avec ACME (Automated Certificate Management Environment, le protocole derrière Let’s Encrypt & Co.) . L’accent est mis sur l’exploitation et l’administration : prérequis, architecture, décisions de sécurité, pièges typiques, étapes de vérification, dépannage et une stratégie de repli qui aide réellement en cas d’incident.

Gestion automatisée des certificats TLS dans Kubernetes en pratique

Dans des architectures classiques, le TLS repose souvent sur un reverse proxy ou un load balancer unique. Dans Kubernetes en revanche, plusieurs éléments mobiles interagissent : Services, ressources Ingress, Ingress-Controller (p. ex. NGINX, HAProxy, Traefik), éventuellement un cloud load balancer, et le DNS. cert-manager s’exécute dans le cluster et génère/renouvelle les certificats en tant qu’objets Kubernetes, typiquement sous forme de Secrets (objets Kubernetes pour stocker des données sensibles comme les clés privées).

Cela change les questions : qui a le droit de lire les Secrets ? Comment obtenir la rotation sans downtime ? Que se passe-t-il lors d’une migration d’Ingress ? Et comment vous assurez-vous que ACME-Challenges fonctionnent dans des environnements multi-cluster ou fortement segmentés ?

Aperçu d’architecture: cert-manager, Issuer/ClusterIssuer, Certificate und Challenges

Textfreie Grafik mit Systemblöcken und Pfeilen für den ACME-Workflow von cert-manager bis zum TLS-Secret im...
Flux de données schématique : cert-manager déclenche les Challenges puis met à jour le TLS-Secret pour l’Ingress.

cert-manager étend Kubernetes avec des Custom Resources (CRDs). Pour l’exploitation, quatre classes de ressources sont centrales :

  • Issuer / ClusterIssuer : définit l’entité émettrice. Issuer est spécifique au namespace, ClusterIssuer utilisable à l’échelle du cluster.
  • Certificate : décrit le certificat souhaité (noms DNS, durée de validité/rotation, Secret cible).
  • Order : commande ACME interne ; gérée par cert-manager.
  • Challenge : la preuve auprès de la CA que vous contrôlez le domaine (HTTP-01 ou DNS-01 sont les variantes habituelles).

ACME est en soi « seulement » le processus standardisé : le client (cert-manager) demande un certificat, la CA exige une validation de domaine, le client remplit la Challenge, la CA signe le certificat, cert-manager l’écrit dans le Secret, et l’Ingress-Controller utilise le Secret pour la terminaison TLS.

Prérequis et décisions préalables (qui réduiront le travail plus tard)

1) Type de Challenge : HTTP-01 vs. DNS-01

HTTP-01 se valide via un endpoint HTTP sous /.well-known/acme-challenge/…. Avantage : pas d’API DNS nécessaire, compréhension rapide. Inconvénient : vous avez besoin d’un routage HTTP accessible depuis l’extérieur vers l’IP d’Ingress et vous ne devez pas avoir de règles de redirection/authentification « strictes » qui bloquent ce chemin.

DNS-01 se valide via un enregistrement TXT dans le DNS. Avantage : fonctionne même sans accessibilité HTTP publique (p. ex. configurations TLS-only, Ingress internes, certificats Wildcard). Inconvénient : vous avez besoin d’automatisation DNS (accès API) et devez maîtriser correctement le TTL/la propagation ainsi que les droits.

Règle pratique : pour les certificats Wildcard, DNS-01 est en pratique obligatoire. Pour des services publics simples, HTTP-01 peut suffire tant que l’Ingress et le DNS sont stables.

2) Où se termine TLS ? Ingress, Service Mesh ou load balancer externe

Beaucoup d’équipes terminent TLS sur l’Ingress-Controller. Les alternatives sont un cloud load balancer (TLS en amont) ou un service mesh (mTLS en interne, TLS en externe). L’important est que cert-manager soit intégré là où la clé privée est requise. Si TLS se termine au niveau du cloud load balancer, cert-manager n’aide directement que si vous synchronisez les certificats vers celui-ci (cela se gère séparément selon la cloud/le controller). Pour le standard courant de Kubernetes — « TLS à l’Ingress » — cert-manager est particulièrement adapté.

3) Points de sécurité et de conformité (Secrets, clés, accès)

cert-manager génère des clés privées et les stocke dans des Secrets Kubernetes. C’est pratique, mais pertinent sur le plan sécurité : toute entité disposant de droits de lecture sur les Secrets peut exfiltrer les clés. Vérifiez donc le RBAC (Role Based Access Control) et la stratégie de namespaces. Dans des environnements régulés, il est aussi pertinent de définir si les clés doivent être générées et protégées dans un KMS/HSM ; cert-manager peut, selon l’environnement, fonctionner avec des Issuers/integrations externes, mais c’est un sujet de conception séparé.

Installation de cert-manager : point d’entrée propre pour l’exploitation

cert-manager est typiquement installé via Helm. Pour les équipes d’exploitation, l’important n’est pas tant « à quelle vitesse », mais « comment c’est traçable » : versionné, avec des namespaces clairs et avec le monitoring en ligne de mire.

Installation via Helm (exemple)

Shell
helm repo add jetstack https://charts.jetstack.io
helm repo update

kubectl create namespace cert-manager

helm install cert-manager jetstack/cert-manager 
  --namespace cert-manager 
  --version v1.16.0 
  --set crds.enabled=true

Remarques pratiques :

  • CRDs (Custom Resource Definitions) sont des définitions à l’échelle du cluster. Dans de nombreux processus de changement, les modifications de CRD doivent être approuvées explicitement.
  • Verrouillez la version et planifiez les mises à jour comme pour les autres composants du cluster : staging, puis production, avec option de rollback.
  • Vérifiez les PodSecurity/les policies d’admission : cert-manager requiert certains droits et fonctionne en tant que controller.

Checks de base après installation

Shell
kubectl -n cert-manager get pods
kubectl -n cert-manager get deploy
kubectl get crd | grep cert-manager

Si des Pods plantent : lisez d’abord les Events, puis les logs. Dans Kubernetes, les Events sont souvent l’indication la plus rapide d’un problème RBAC, de webhook ou d’ImagePull.

Shell
kubectl -n cert-manager get events --sort-by=.lastTimestamp | tail -n 50
kubectl -n cert-manager logs deploy/cert-manager --tail=200
kubectl -n cert-manager logs deploy/cert-manager-webhook --tail=200

Configuration ACME : ClusterIssuer pour Let’s Encrypt (staging et production)

Admin richtet cert-manager- und ACME-Konfiguration am Laptop ein, mit ausgedruckten Manifesten auf dem Tisch.
Staging d’abord : effectuer des tests sans risque de limitations de taux rend l’exploitation nettement plus sereine.

Pour un fonctionnement fiable, mettez en place d’abord un environnement de staging. Let’s Encrypt applique des limites de taux ; le staging réduit le risque lors des tests et des tentatives erronées répétées. La bascule vers la production devient alors une étape contrôlée.

ClusterIssuer (staging) avec HTTP-01 via Ingress

Cet exemple utilise HTTP-01 et suppose que votre contrôleur Ingress est exposé via une IngressClass (p. ex. « nginx »). L’IngressClass détermine quel contrôleur prend en charge une ressource Ingress.

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

ClusterIssuer (production) – identique, mais avec un endpoint ACME différent

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

Important : la clé de compte (privateKeySecretRef) n’est pas le certificat, mais la clé liée à votre compte ACME auprès de la CA. Traitez-la comme un credential sensible et ne la supprimez pas sans précaution.

Délivrer le certificat : ressource Certificate et intégration Ingress

Il existe deux schémas fréquents : (1) des annotations sur l’Ingress qui commandent à cert-manager de générer lui‑même un Certificate, ou (2) définir explicitement une ressource Certificate. Pour la transparence opérationnelle, l’approche explicite est souvent préférable : elle indique clairement quels noms DNS, quelle référence d’issuer et quel Secret sont concernés.

Certificate (exemple)

Yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: portal-tls
  namespace: production
spec:
  secretName: portal-tls-secret
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
  - portal.example.com

Ingress utilisant le Secret

Yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: portal
  namespace: production
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - portal.example.com
    secretName: portal-tls-secret
  rules:
  - host: portal.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: portal-svc
            port:
              number: 80

Warum funktioniert das? cert-manager schreibt tls.crt und tls.key in das Secret. Der Ingress-Controller lädt das Secret und terminiert TLS. Bei Erneuerung wird das Secret aktualisiert, der Controller lädt neu (je nach Controller mit leichtem Delay). Für stabile Rotation ist entscheidend, dass der Controller Secret-Updates zuverlässig erkennt.

Prüfen, ob alles wirklich „grün“ ist (und nicht nur „irgendwie erstellt“)

Status auf Certificate/Order/Challenge

Shell
kubectl -n production get certificate portal-tls -o wide
kubectl -n production describe certificate portal-tls

kubectl -n production get order
kubectl -n production get challenge
kubectl -n production describe challenge -l cert-manager.io/certificate-name=portal-tls

Praxis-Tipp: Wenn Zertifikate nicht ausgestellt werden, ist describe oft aussagekräftiger als Logs. cert-manager schreibt präzise Condition-Meldungen, z. B. „Waiting for HTTP-01 challenge propagation“ oder „DNS record not found“.

Secret-Inhalt und Ablaufdatum validieren

Sie wollen nicht nur sehen, dass ein Secret existiert, sondern dass es einen gültigen Zertifikatsinhalt hat und der Hostname passt.

Shell
kubectl -n production get secret portal-tls-secret
kubectl -n production get secret portal-tls-secret -o jsonpath='{.data.tls.crt}' | base64 -d > /tmp/portal.crt

openssl x509 -in /tmp/portal.crt -noout -subject -issuer -dates -ext subjectAltName

Wenn Sie in Produktionsnetzen OpenSSL nicht auf Admin-Workstations nutzen dürfen, bauen Sie diesen Check in ein kontrolliertes Admin-Tooling (Jump Host) oder in ein internes Runbook-Job-Image ein.

Typische Stolperfallen in der Praxis (und wie Sie sie früh erkennen)

Graphique sans texte d'un chemin réseau où un chemin ACME-Challenge séparé est mis en évidence à travers le pare-feu et l'Ingress.
De nombreux problèmes HTTP-01 proviennent de chemins bloqués, de redirections ou d’un Ingress-Controller incorrect.

HTTP-01 scheitert durch Redirects, Auth oder falsche IngressClass

Häufige Ursache: Ein globaler Redirect von HTTP auf HTTPS oder eine Authentifizierung greift auch auf den ACME-Pfad. Der ACME-Server muss den Token per HTTP erreichen können, ohne Login, ohne WAF-Block, ohne „nur HTTPS“. Einige Setups lösen das, indem sie den Challenge-Pfad explizit ausnehmen oder den Solver so konfigurieren, dass er einen separaten Ingress erzeugt.

Ein zweiter Klassiker: Ihre Ingress-Ressource wird gar nicht vom erwarteten Controller verarbeitet (falsche ingressClassName), oder Sie haben mehrere Controller im Cluster. Dann landet der Challenge-Ingress am falschen Ort.

DNS-01 scheitert durch fehlende API-Rechte oder Propagation

Bei DNS-01 ist die häufigste Ursache nicht cert-manager selbst, sondern DNS-Automation: Der verwendete DNS-Provider-Account darf keine TXT-Records setzen, oder er darf nur in einer Zone schreiben, während die Domain in einer anderen Zone liegt. Dazu kommen TTL/Propagation: Der ACME-Server fragt verteilte Resolver ab; wenn Ihr TXT-Record nicht überall sichtbar ist, bleibt die Challenge pending oder läuft in ein Timeout.

Opérationnellement, il est pertinent d’effectuer un « propagation-check » standardisé contre des résolveurs publics, plutôt que de vérifier uniquement votre propre DNS.

Shell
# Beispiel: TXT-Record für _acme-challenge prüfen
# (Record-Name und Token entnehmen Sie aus der Challenge-Resource)

nslookup -type=TXT _acme-challenge.portal.example.com 1.1.1.1
nslookup -type=TXT _acme-challenge.portal.example.com 8.8.8.8

Rate Limits und „Testen in Produktion“

Si vous relancez plusieurs demandes en cas d’erreur, vous pouvez atteindre des limites de taux auprès des Public-CAs. Cela ne se manifeste alors pas comme une « erreur technique », mais comme « trop de requêtes ». Donc : utiliser un Staging-Issuer pour les tests, et basculer en production seulement lorsque Ingress/DNS sont stables. Cela vaut particulièrement lors de projets de migration (p.ex. changement de l’Ingress-Controller).

Temps, DNS et chemins réseau : causes discrètes

ACME est sensible au temps. Si des nœuds du cluster ou des composants critiques ont des horloges fortement décalées (problèmes NTP/Chrony), les validations TLS et les fenêtres temporelles peuvent échouer. Tout aussi important : le filtrage egress. cert-manager doit pouvoir atteindre les endpoints ACME, et pour DNS-01 l’API DNS doit être accessible. Cela semble trivial, mais dans des réseaux segmentés c’est un arrêt fréquent.

Bonnes pratiques pour un fonctionnement stable : surveillance, gestion des alertes, rotation

Surveillance : ne réagissez pas seulement quand le certificat est expiré

Mettez en place au moins trois niveaux de contrôles :

  • État Kubernetes : Certificate-Conditions (Ready/Not Ready) et Events.
  • Durée restante : métriques/contrôles sur « days until expiry » (p.ex. via un Prometheus-Exporter ou des vérifications TLS externes).
  • End-to-End : vérifier depuis l’extérieur ce qui est effectivement délivré (SNI, chaîne, date d’expiration).

cert-manager fournit des métriques Prometheus si vous avez un monitoring. L’essentiel est que les alertes représentent non seulement « est expiré », mais « renouvellement échoué ». Ainsi vous disposez d’une marge pour l’analyse des causes.

Éviter la rotation et les interruptions : comment réagissent les Ingress-Controller

Lors du renouvellement, le Secret est mis à jour. Les Ingress-Controller diffèrent quant à la rapidité d’intégration des mises à jour de Secret. Dans des architectures robustes, testez cela volontairement : déclenchez un renouvellement (p.ex. en Staging), observez si les nouveaux certificats deviennent actifs sans problèmes de reload et si les connexions existantes restent stables.

Si vous avez des exigences très strictes (p.ex. de nombreuses connexions TLS longues), il est aussi pertinent d’examiner les Session-Tickets/Resumption et le comportement de reload du controller. Ce n’est pas un sujet cert-manager, mais cela affecte directement la perception « le changement de certificat cause une interruption ».

Stratégie Namespace et Issuer

Un ClusterIssuer est pratique, mais il augmente la portée : chaque Namespace peut potentiellement demander des certificats si le RBAC n’est pas correctement limité. Pour des Managed-Service-Provider ou des Multi-Tenant-Cluster, il vaut souvent mieux utiliser des Issuer par client/Namespace et contrôler de façon ciblée les accès aux CRD Issuer/Certificate.

Troubleshooting-Runbook : procédure structurée en cas d’échec

Quand « le certificat n’est pas délivré » arrive dans des tickets, un déroulé clair aide. La séquence suivante a fait ses preuves :

  1. Définir le périmètre : S’agit-il d’un seul Certificate, d’un Namespace ou du cluster entier ?
  2. Lire le statut : Conditions et Events de Certificate/Order/Challenge.
  3. Vérifier les chemins réseau : cert-manager atteint-il les ACME-Server ? ACME atteint-il votre endpoint de challenge (HTTP-01) ou le TXT est-il publiquement visible (DNS-01) ?
  4. Vérifier la responsabilité Ingress/DNS : IngressClass, nom d’hôte, IP du LoadBalancer, enregistrement A DNS, le cas échéant règles CDN/WAF.
  5. Logs ciblés : cert-manager-Controller et, le cas échéant, Ingress-Controller, pas „tout en même temps“.

Commandes pour un diagnostic rapide

Shell
# 1) cert-manager Health
kubectl -n cert-manager get pods
kubectl -n cert-manager get events --sort-by=.lastTimestamp | tail -n 30

# 2) Certificate Status
kubectl -n production describe certificate portal-tls

# 3) Challenge Details
kubectl -n production get challenge -o wide
kubectl -n production describe challenge <challenge-name>

# 4) Ingress Check
kubectl -n production get ingress portal -o yaml
kubectl -n production describe ingress portal

# 5) DNS Check
nslookup portal.example.com 1.1.1.1

# 6) Externes TLS aus Sicht eines Clients
echo | openssl s_client -connect portal.example.com:443 -servername portal.example.com 2>/dev/null | openssl x509 -noout -subject -issuer -dates

Si openssl s_client affiche un certificat différent de celui présent dans le Secret, c’est généralement dû à une couche en amont (CDN, Cloud LB), à un Host/SNI incorrect ou à un Ingress-Controller qui n’a pas pris en compte le Secret.

Stratégie de repli : que faire si l’automatisation échoue ou si la rotation tourne mal ?

Une stratégie de repli doit être rapide, à faible risque et traçable. En pratique, trois scénarios sont pertinents :

Scénario A : Le renouvellement échoue, mais le certificat actuel est encore valide

  • Priorité : corriger la cause (DNS/Ingress/atteignabilité), sans réinstallation précipitée.
  • Monitoring : configurer les seuils d’alerte pour disposer de plusieurs jours de marge.
  • Action : analyser la Challenge/Order, éventuellement ajuster la configuration du solver, puis relancer la demande.

Scénario B : le certificat est expiré ou sur le point d’expirer, l’automatisation est bloquée

Vous devez disposer d’une procédure « break glass ». Deux options courantes :

  • Certificat manuel temporaire (p. ex. d’une CA interne ou fourni à court terme) déposé en tant que Secret pour garantir la disponibilité.
  • Basculement vers une validation alternative (de HTTP-01 vers DNS-01), si cela est réalisable rapidement et qu’une API DNS est disponible.

Important : documentez l’état temporaire et créez un rappel pour revenir au workflow ACME normal.

Scénario C : déploiement d’un mauvais certificat (nom d’hôte/chaîne incorrecte)

Cela est rare mais critique : noms DNS incorrects, SecretName erroné dans l’Ingress, ou un secret partagé écrasé. Le repli consiste ici à restaurer le dernier Secret connu bon. Kubernetes ne versionne pas historiquement les Secrets. D’où l’importance des sauvegardes ou de concepts GitOps/Cluster-Backup : soit vous disposez du Secret (chiffré) dans une sauvegarde, soit vous pouvez réémettre rapidement un certificat correct.

Opérationnellement utile : conservez pour chaque endpoint critique une checkliste courte : « Quel Secret ? Quels hôtes ? Quelle IngressClass ? Quelle IP externe ? Quelle réponse DNS ? » – afin de ne pas avoir à reconstruire le modèle système pendant l’incident.

Sécurisation et administration rigoureuse : RBAC, accès aux Secrets, gestion des changements

Un point sous-estimé est la question de savoir qui peut demander des certificats. Dans Kubernetes, une équipe peut, en créant un objet Certificate combiné à un ClusterIssuer largement permissif, soudainement demander des certificats pour des domaines supplémentaires si le routage DNS/Ingress le permet. Limitez cela en :

  • RBAC sur cert-manager-CRDs (qui est autorisé à créer des Certificate/Issuer ?).
  • Isolation des namespaces : séparer les locataires et minimiser les droits.
  • Gouvernance DNS : gérer de manière RESTrictive la délégation de domaine et les accès aux API DNS.
  • Change-Control : traiter les modifications des configurations d’Issuer/Solver comme des changements d’infrastructure.

Si vous disposez déjà de processus établis pour les secrets et l’automatisation, ces patterns se combinent bien avec Infrastructure-as-Code et GitOps : manifestes reproductibles, revues et procédures de rollback claires. Dans des domaines connexes (p. ex. gestion des secrets et idempotence), des principes similaires s’appliquent.

Conclusion : cert-manager et ACME sont un processus d’exploitation, pas un « plugin »

cert-manager en combinaison avec ACME est une voie très pratique pour gérer automatiquement les certificats TLS dans Kubernetes : émission, renouvellement et rotation deviennent un cycle de vie contrôlé. Il est essentiel de prendre au sérieux les dépendances : classe d’Ingress et routage (HTTP-01), API DNS et propagation (DNS-01), protection RBAC/Secrets ainsi que la surveillance mise en place en amont.

Si vous utilisez systématiquement des environnements de staging, définissez des runbooks pour le dépannage et les plans de repli, et contrôlez proprement l’accès aux Issuer/Secrets, l’automatisation ne devient pas une boîte noire mais un composant fiable de l’exploitation Kubernetes — y compris pour des équipes qui ne traitent pas quotidiennement des sujets PKI.

Pour ce sujet, Acme Workflow et Let’s Encrypt In Kubernetes sont également importants. Cet article replace ces aspects de manière compréhensible et montre ce qui importe au quotidien.