IT-Admin.tech

Automatisiertes TLS-Zertifikat-Management in Kubernetes mit cert-manager und ACME-Workflows: Betriebssicher von der Erstinstallation bis zum 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.

TLS ist im Kubernetes-Alltag kein „einmal ein Zertifikat installieren“-Thema, sondern ein laufender Betriebsprozess: Zertifikate laufen ab, Domains wechseln, Ingress-Controller werden migriert, DNS wird delegiert, und im ungünstigsten Moment bricht eine ACME-Challenge. Genau hier zahlt sich Automatisiertes TLS-Zertifikat-Management in Kubernetes aus: Sie reduzieren manuelle Eingriffe, vermeiden Ablauf-Überraschungen und bekommen reproduzierbare Abläufe für Ausstellung, Erneuerung und Rotation.

Dieser Beitrag erklärt praxisnah, wie cert-manager (ein Kubernetes-Controller für Zertifikats-Lifecycle) mit ACME (Automated Certificate Management Environment, das Protokoll hinter Let’s Encrypt & Co.) zusammenspielt. Der Fokus liegt auf Betrieb und Administration: Voraussetzungen, Architektur, Sicherheitsentscheidungen, typische Stolperfallen, Prüfschritte, Troubleshooting und eine Rückfallstrategie, die im Incident wirklich hilft.

Automatisiertes TLS-Zertifikat-Management in Kubernetes in der Praxis

In klassischen Setups liegt TLS oft auf einem einzelnen Reverse Proxy oder Load Balancer. In Kubernetes dagegen kommen mehrere bewegliche Teile zusammen: Services, Ingress-Ressourcen, Ingress-Controller (z. B. NGINX, HAProxy, Traefik), ggf. ein Cloud Load Balancer, plus DNS. cert-manager sitzt im Cluster und erzeugt/erneuert Zertifikate als Kubernetes-Objekte, typischerweise als Secrets (Kubernetes-Objekte zum Speichern sensibler Daten wie Private Keys).

Das ändert die Fragestellungen: Wer darf Secrets lesen? Wie wird Rotation ohne Downtime erreicht? Was passiert bei Ingress-Migration? Und wie stellen Sie sicher, dass ACME-Challenges in Multi-Cluster- oder streng segmentierten Umgebungen funktionieren?

Architekturüberblick: 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...
Schematischer Datenfluss: cert-manager löst Challenges aus und aktualisiert danach das TLS-Secret für den Ingress.

cert-manager erweitert Kubernetes um Custom Resources (CRDs). Für den Betrieb sind vier Ressourcenklassen zentral:

  • Issuer / ClusterIssuer: Definiert die ausstellende Instanz. Issuer ist namespace-spezifisch, ClusterIssuer clusterweit nutzbar.
  • Certificate: Beschreibt, welches Zertifikat Sie wollen (DNS-Namen, Gültigkeitsdauer/Rotation, Ziel-Secret).
  • Order: Interner ACME-Bestellvorgang; wird durch cert-manager verwaltet.
  • Challenge: Der Nachweis gegenüber der CA, dass Sie die Domain kontrollieren (HTTP-01 oder DNS-01 sind die üblichen Varianten).

ACME selbst ist dabei „nur“ der standardisierte Prozess: Client (cert-manager) fragt ein Zertifikat an, CA verlangt Domain-Validierung, Client erfüllt Challenge, CA signiert Zertifikat, cert-manager schreibt es ins Secret, Ingress-Controller nutzt Secret für TLS-Termination.

Voraussetzungen und Vorab-Entscheidungen (die später Aufwand sparen)

1) Challenge-Typ: HTTP-01 vs. DNS-01

HTTP-01 validiert über einen HTTP-Endpunkt unter /.well-known/acme-challenge/…. Vorteil: keine DNS-API nötig, schnell verständlich. Nachteil: Sie brauchen extern erreichbares HTTP-Routing zur Ingress-IP und dürfen keine „harten“ Redirect-/Auth-Regeln haben, die den Pfad blockieren.

DNS-01 validiert über einen TXT-Record im DNS. Vorteil: funktioniert auch ohne öffentliche HTTP-Erreichbarkeit (z. B. reine TLS-Only-Setups, interne Ingress, Wildcard-Zertifikate). Nachteil: Sie benötigen DNS-Automation (API-Zugang) und müssen TTL/Propagation sowie Rechte sauber beherrschen.

Praxisregel: Für Wildcard-Zertifikate ist DNS-01 faktisch Pflicht. Für einfache Public-Services kann HTTP-01 reichen, solange Ingress und DNS stabil sind.

2) Wo endet TLS? Ingress, Service Mesh oder externer Load Balancer

Viele Teams terminieren TLS am Ingress-Controller. Alternativen sind ein Cloud Load Balancer (TLS davor) oder ein Service Mesh (mTLS intern, TLS extern). Wichtig ist, dass cert-manager dort integriert wird, wo der Private Key gebraucht wird. Wenn TLS am Cloud Load Balancer endet, hilft cert-manager nur dann direkt, wenn Sie Zertifikate dorthin synchronisieren (das ist je nach Cloud/Controller separat zu lösen). Für den üblichen Kubernetes-Standard „TLS am Ingress“ ist cert-manager besonders passend.

3) Sicherheits- und Compliance-Punkte (Secrets, Schlüssel, Zugriff)

cert-manager erzeugt Private Keys und speichert sie in Kubernetes-Secrets. Das ist praktisch, aber sicherheitlich relevant: Wer Leserechte auf Secrets hat, kann Schlüssel exfiltrieren. Prüfen Sie daher RBAC (Role Based Access Control) und Namespace-Strategie. In regulierten Umgebungen ist zudem interessant, ob Schlüssel in einem KMS/HSM erzeugt und geschützt werden sollen; cert-manager kann je nach Umgebung mit externen Issuern/Integrationen arbeiten, aber das ist ein eigenes Design-Thema.

Installation von cert-manager: sauberer Einstieg für den Betrieb

cert-manager wird typischerweise via Helm installiert. Für Betriebsteams zählt weniger „wie schnell“, sondern „wie nachvollziehbar“: versioniert, mit klaren Namespaces, und mit Monitoring im Blick.

Helm-Installation (Beispiel)

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

Hinweise für die Praxis:

  • CRDs (Custom Resource Definitions) sind clusterweite Definitionen. In vielen Change-Prozessen müssen CRD-Änderungen explizit freigegeben werden.
  • Pinnt die Version und plant Upgrades wie bei anderen Cluster-Komponenten: Staging, dann Produktion, mit Rollback-Option.
  • Prüfen Sie PodSecurity/Admission-Policies: cert-manager braucht bestimmte Rechte und läuft als Controller.

Basis-Check nach Installation

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

Wenn Pods crashen: erst Events lesen, dann Logs. In Kubernetes sind Events oft der schnellste Hinweis auf RBAC, Webhook-Probleme oder ImagePull-Themen.

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

ACME-Setup: ClusterIssuer für Let’s Encrypt (Staging und Produktion)

Admin richtet cert-manager- und ACME-Konfiguration am Laptop ein, mit ausgedruckten Manifesten auf dem Tisch.
Staging zuerst: Tests ohne Rate-Limit-Risiko sind im Betrieb deutlich entspannter.

Für belastbaren Betrieb setzen Sie zuerst Staging auf. Let’s Encrypt hat Rate Limits; Staging reduziert Risiko beim Testen und bei wiederholten Fehlversuchen. Der Wechsel auf Produktion ist dann ein kontrollierter Schritt.

ClusterIssuer (Staging) mit HTTP-01 über Ingress

Dieses Beispiel nutzt HTTP-01 und setzt voraus, dass Ihr Ingress-Controller über eine IngressClass (z. B. „nginx“) erreichbar ist. Die IngressClass ist die Zuordnung, welcher Controller eine Ingress-Ressource verarbeitet.

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 (Produktion) – identisch, aber anderer ACME-Endpoint

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

Wichtig: Der Account-Key (privateKeySecretRef) ist nicht das Zertifikat, sondern der Schlüssel Ihres ACME-Kontos bei der CA. Den sollten Sie wie einen wichtigen Credential behandeln und nicht leichtfertig löschen.

Zertifikat ausstellen: Certificate-Resource und Ingress-Integration

Es gibt zwei verbreitete Muster: (1) Ingress-Annotationen, die cert-manager dazu bringen, selbst ein Certificate zu erzeugen, oder (2) Sie definieren Certificate explizit. Für Betriebs-Transparenz ist explizit oft besser: Sie sehen klar, welche DNS-Namen, welche Issuer-Referenz und welches Secret betroffen sind.

Certificate (Beispiel)

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, der das Secret nutzt

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)

Textfreie Grafik eines Netzwerkpfads, in dem ein separater ACME-Challenge-Pfad durch Firewall und Ingress hervorgehoben ist.
Viele HTTP-01-Probleme entstehen durch blockierte Pfade, Redirects oder den falschen Ingress-Controller.

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.

Operativ sinnvoll ist hier ein standardisierter „Propagation-Check“ gegen öffentliche Resolver, statt nur den eigenen DNS zu prüfen.

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“

Wenn Sie bei Fehlern mehrfach neu anfordern, können Sie bei Public-CAs in Rate Limits laufen. Das äußert sich dann nicht als „technischer Fehler“, sondern als „zu viele Anfragen“. Deshalb: Staging-Issuer für Tests, Produktion erst, wenn Ingress/DNS stabil sind. Das gilt besonders bei Migrationsprojekten (z. B. Wechsel des Ingress-Controllers).

Zeit, DNS und Netzwerkpfade: unscheinbare Ursachen

ACME ist zeitkritisch. Wenn Cluster-Nodes oder wichtige Komponenten stark driftende Uhrzeiten haben (NTP/Chrony-Probleme), können TLS-Validierungen und Zeitfenster scheitern. Ebenso wichtig: Egress-Firewalling. cert-manager muss die ACME-Endpoints erreichen können, und bei DNS-01 muss die DNS-API erreichbar sein. Das klingt banal, ist aber in segmentierten Netzen ein häufiger Showstopper.

Best Practices für stabilen Betrieb: Monitoring, Alerting, Rotation

Überwachung: nicht erst reagieren, wenn das Zertifikat abgelaufen ist

Setzen Sie mindestens drei Ebenen an Checks auf:

  • Kubernetes-Status: Certificate-Conditions (Ready/Not Ready) und Events.
  • Ablaufzeit: Metriken/Checks auf „days until expiry“ (z. B. über Prometheus-Exporter oder externe TLS-Checks).
  • End-to-End: Von außen prüfen, was wirklich ausgeliefert wird (SNI, Kette, Ablaufdatum).

cert-manager liefert Prometheus-Metriken, wenn Sie Monitoring betreiben. Entscheidend ist, dass Alerts nicht nur „ist abgelaufen“, sondern „Erneuerung fehlgeschlagen“ abbilden. So haben Sie Puffer für Ursachenanalyse.

Rotation und Downtime vermeiden: worauf Ingress-Controller reagieren

Bei der Erneuerung wird das Secret aktualisiert. Ingress-Controller unterscheiden sich darin, wie schnell sie Secret-Updates übernehmen. In robusten Setups testen Sie das bewusst: Erneuerung anstoßen (z. B. in Staging), beobachten, ob neue Zertifikate ohne Reload-Probleme aktiv werden, und ob bestehende Verbindungen stabil bleiben.

Wenn Sie sehr strikte Anforderungen haben (z. B. viele lange TLS-Verbindungen), ist auch ein Blick auf Session-Tickets/Resumption und Reload-Verhalten des Controllers sinnvoll. Das ist kein cert-manager-Thema, wirkt aber direkt auf die Wahrnehmung „Zertifikatswechsel verursacht Störung“.

Namespace- und Issuer-Strategie

Ein ClusterIssuer ist bequem, aber er erhöht die Reichweite: Jeder Namespace kann potenziell Zertifikate beantragen, wenn RBAC nicht sauber begrenzt ist. Für Managed-Service-Provider oder Multi-Tenant-Cluster lohnt es sich oft, Issuer pro Mandant/Namespace zu nutzen und Zugriffe auf Issuer/Certificate-CRDs gezielt zu steuern.

Troubleshooting-Runbook: strukturierte Vorgehensweise bei Fehlschlägen

Wenn „Zertifikat wird nicht ausgestellt“ in Tickets landet, hilft ein klarer Ablauf. Bewährt hat sich diese Sequenz:

  1. Scope klären: Betrifft es ein einzelnes Certificate, einen Namespace oder den gesamten Cluster?
  2. Status lesen: Certificate/Order/Challenge Conditions und Events.
  3. Netzpfade prüfen: Erreicht cert-manager ACME-Server? Erreicht ACME Ihren Challenge-Endpunkt (HTTP-01) oder ist TXT öffentlich sichtbar (DNS-01)?
  4. Ingress/DNS-Verantwortung prüfen: IngressClass, Hostname, LoadBalancer-IP, DNS-A-Record, ggf. CDN/WAF-Regeln.
  5. Logs zielgerichtet: cert-manager-Controller und ggf. Ingress-Controller, nicht „alles gleichzeitig“.

Kommandos für schnelle Diagnose

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

Wenn openssl s_client ein anderes Zertifikat zeigt als im Secret, liegt das meist an einem vorgeschalteten Layer (CDN, Cloud LB), einem falschen Host/SNI oder einem Ingress-Controller, der das Secret nicht übernommen hat.

Rückfallstrategie: Was tun, wenn Automation ausfällt oder Rotation schiefgeht?

Eine Rückfallstrategie muss schnell, risikoarm und auditierbar sein. In der Praxis sind drei Szenarien relevant:

Szenario A: Erneuerung schlägt fehl, aber aktuelles Zertifikat ist noch gültig

  • Priorität: Ursache beheben (DNS/Ingress/Reachability), ohne hektische Neuinstallation.
  • Monitoring: Alarm-Schwellen so setzen, dass Sie Tage Vorlauf haben.
  • Aktion: Challenge/Order analysieren, ggf. Solver-Config anpassen, dann erneute Anforderung.

Szenario B: Zertifikat ist abgelaufen oder kurz davor, Automation blockiert

Hier brauchen Sie einen „Break Glass“-Weg. Üblich sind zwei Optionen:

  • Temporäres manuelles Zertifikat (z. B. aus interner CA oder kurzfristig bereitgestellt) als Secret einspielen, um Verfügbarkeit zu sichern.
  • Umschalten auf alternative Validierung (von HTTP-01 auf DNS-01), wenn das schnell umsetzbar ist und DNS-API vorhanden ist.

Wichtig: Dokumentieren Sie den temporären Zustand und bauen Sie eine Erinnerung ein, wieder auf den normalen ACME-Workflow zurückzugehen.

Szenario C: Falsches Zertifikat ausgerollt (Hostname/Chain passt nicht)

Das ist selten, aber kritisch: falsche DNS-Namen, falscher SecretName in Ingress, oder ein Shared-Secret wurde überschrieben. Rückfall bedeutet hier: auf das zuletzt bekannte gute Secret zurück. Kubernetes selbst versioniert Secrets nicht historisch. Deshalb sind Backups bzw. GitOps/Cluster-Backup-Konzepte wichtig: Entweder haben Sie das Secret (verschlüsselt) in einem Backup, oder Sie können kurzfristig ein korrektes Zertifikat neu ausstellen.

Operativ sinnvoll: Halten Sie pro kritischem Endpoint eine kurze Checkliste bereit: „Welches Secret? Welche Hosts? Welche IngressClass? Welche externe IP? Welche DNS-Antwort?“ – damit Sie im Incident nicht erst das Systemmodell rekonstruieren.

Absicherung und saubere Administration: RBAC, Secret-Zugriff, Change-Control

Ein unterschätzter Punkt ist die Frage, wer Zertifikate beantragen darf. In Kubernetes kann ein Team durch das Anlegen eines Certificate-Objekts in Kombination mit einem weitreichenden ClusterIssuer plötzlich Zertifikate für zusätzliche Domains beantragen, wenn DNS/Ingress-Routing das zulässt. Begrenzen Sie das mit:

  • RBAC auf cert-manager-CRDs (wer darf Certificate/Issuer erstellen?).
  • Namespace-Isolation: Mandanten trennen und Rechte minimieren.
  • DNS-Governance: Domain-Delegation und DNS-API-Zugänge restriktiv verwalten.
  • Change-Control: Änderungen an Issuer/Solver-Konfigurationen wie Infrastrukturänderungen behandeln.

Wenn Sie bereits etablierte Prozesse für Secrets und Automatisierung haben, lassen sich diese Patterns gut mit Infrastructure-as-Code und GitOps kombinieren: reproduzierbare Manifeste, Reviews und klare Rollback-Pfade. In verwandten Bereichen (z. B. Secret-Handling und Idempotenz) sind ähnliche Prinzipien relevant.

Fazit: cert-manager und ACME sind ein Betriebsprozess, kein „Plugin“

cert-manager in Kombination mit ACME ist ein sehr praxistauglicher Weg, um TLS-Zertifikate in Kubernetes automatisiert zu managen: Ausstellung, Erneuerung und Rotation werden zu einem kontrollierten Lifecycle. Entscheidend ist, dass Sie die Abhängigkeiten ernst nehmen: Ingress-Klasse und Routing (HTTP-01), DNS-API und Propagation (DNS-01), RBAC/Secret-Schutz sowie Monitoring mit Vorlauf.

Wenn Sie Staging konsequent nutzen, Runbooks für Troubleshooting und Rückfall definieren und den Zugriff auf Issuer/Secrets sauber steuern, wird Automatisierung nicht zur Blackbox, sondern zu einem verlässlichen Baustein im Kubernetes-Betrieb – auch für Teams, die nicht täglich PKI-Themen anfassen.

Für dieses Thema sind auch Acme Workflow und Let’s Encrypt In Kubernetes wichtig. Der Beitrag ordnet diese Aspekte verständlich ein und zeigt, worauf es im Alltag ankommt.