Alle Ressourcen

Praxisanleitung · cert-manager

cert-manager: Certificate ist Ready, aber der Ingress liefert das falsche Zertifikat

cert-manager meldet Ready=True, doch der Browser erhält weiterhin ein altes oder unerwartetes Zertifikat. Vergleichen Sie das Zertifikat im Secret, die Secret-Referenz des Ingress und das Zertifikat einer neuen TLS-Verbindung.

Diese Anleitung behandelt Kubernetes Ingress mit cert-manager und TLS-Terminierung am Ingress-Controller. Passen Sie Kontext, Namespace, Ressourcennamen und Hostnamen an, bevor Sie die lesenden Diagnosebefehle ausführen. Sie setzen Bash unter Linux, kubectl, OpenSSL und GNU coreutils voraus. Gateway API und TLS-Passthrough verwenden andere Konfigurationswege.

1. Den Certificate-Status im richtigen Cluster lesen

Setzen Sie diese Variablen in einer Bash-Sitzung und verwenden Sie dieselbe Sitzung für die folgenden Kubernetes-Befehle. Der explizite Kontext verhindert, dass die Prüfungen versehentlich den Standardcluster ansprechen. Lesen Sie in der Certificate-Beschreibung die Bedingungen, Ereignisse, Gültigkeitsdaten und den Erneuerungszeitpunkt.

TLS_CONTEXT=your-context
TLS_NAMESPACE=apps
TLS_CERTIFICATE=site
TLS_INGRESS=site
kubectl --context "$TLS_CONTEXT" -n "$TLS_NAMESPACE" \
  get certificate "$TLS_CERTIFICATE"
kubectl --context "$TLS_CONTEXT" -n "$TLS_NAMESPACE" \
  describe certificate "$TLS_CERTIFICATE"

Ready=True beschreibt den von cert-manager erfassten Zustand dieser Certificate-Ressource. Es ersetzt keine externe TLS-Prüfung. Bei Ready=False oder fehlender Bedingung verfolgen Sie die angegebene Ursache über den referenzierten Issuer oder ClusterIssuer und den CertificateRequest. Orders und Challenges sind bei ACME-Ausstellern relevant. Löschen Sie nicht als ersten Diagnoseversuch das Secret und erzwingen Sie nicht wiederholt eine Ausstellung.

2. Das Zertifikat aus dem Secret erfassen

Lesen Sie spec.secretName aus der Certificate-Ressource, statt den Namen des Secrets zu vermuten. Der folgende Befehl zeigt Fingerabdruck, Aussteller, Gültigkeitsdaten und SANs des öffentlichen Endzertifikats. Für das Lesen eines Secrets sind entsprechende Kubernetes-Berechtigungen erforderlich. Kopieren Sie keinen vollständigen Secret-Export in Protokolle oder Supporttickets.

set -o pipefail
TLS_SECRET=$(kubectl --context "$TLS_CONTEXT" -n "$TLS_NAMESPACE" \
  get certificate "$TLS_CERTIFICATE" -o jsonpath='{.spec.secretName}')
if [ -n "$TLS_SECRET" ]; then
  kubectl --context "$TLS_CONTEXT" -n "$TLS_NAMESPACE" \
    get secret "$TLS_SECRET" -o jsonpath='{.data.tls\.crt}' |
    base64 --decode |
    openssl x509 -noout -sha256 -fingerprint \
      -issuer -dates -ext subjectAltName
fi

Notieren Sie den SHA-256-Fingerabdruck als erwarteten Wert. Ein Zertifikat für example.com kann trotzdem ein anderes sein als das zur Bereitstellung vorgesehene. Namen und Gültigkeitsdaten helfen bei der Diagnose; der Fingerabdruck identifiziert das verglichene Endzertifikat.

3. Die Secret-Referenz des Ingress prüfen

Prüfen Sie spec.tls[].secretName, spec.tls[].hosts, die Hosts der Routingregeln und ingressClassName. Das TLS-Secret muss im selben Namespace wie der Ingress liegen. Sein Zertifikat muss den Hostnamen abdecken. Prüfen Sie, ob der vorgesehene Controller diese Ingress-Klasse verarbeitet und das Secret lesen kann.

kubectl --context "$TLS_CONTEXT" -n "$TLS_NAMESPACE" \
  get ingress "$TLS_INGRESS" -o yaml
kubectl --context "$TLS_CONTEXT" -n "$TLS_NAMESPACE" \
  describe ingress "$TLS_INGRESS"

Vergleichen Sie die Referenz mit spec.secretName der Certificate-Ressource. Ist die Abweichung unbeabsichtigt, korrigieren Sie das Manifest, die Helm-Werte oder die zuständige GitOps-Quelle. Bei einem annotierten Ingress erzeugt ingress-shim die Certificate-Ressourcen anhand dieser Konfiguration. Prüfen Sie die Annotationen, bevor Sie ein zweites Certificate für dasselbe Secret anlegen. Stimmen die Referenzen, suchen Sie in den Ereignissen und Protokollen des Ingress-Controllers nach Lade- oder Berechtigungsfehlern.

4. Mit einer neuen TLS-Verbindung vergleichen

Führen Sie diese Prüfung außerhalb des Hosting-Netzes aus, für einen Dienst, den Sie betreiben oder prüfen dürfen. Setzen Sie den Hostnamen erneut, falls Sie eine andere Shell verwenden. SNI übermittelt dem Server den angefragten Hostnamen. Vergleichen Sie den ausgegebenen Fingerabdruck mit dem des Secrets.

set -o pipefail
TLS_HOST=example.com
timeout 10 openssl s_client -connect "$TLS_HOST:443" \
  -servername "$TLS_HOST" </dev/null |
  openssl x509 -noout -sha256 -fingerprint \
    -issuer -dates -ext subjectAltName

Der Befehl zeigt das präsentierte Zertifikat. Er bestätigt weder die Vertrauenswürdigkeit der Kette noch die Übereinstimmung des Hostnamens. Ein vorgeschaltetes CDN oder ein Load Balancer mit TLS-Terminierung kann berechtigterweise ein anderes Zertifikat ausliefern. Prüfen Sie diese Komponente und anschließend, sofern erreichbar, den Ursprung separat. Für eine bestimmte Adresse ersetzen Sie das Ziel von -connect durch IP:443 oder [IPv6]:443 und behalten -servername bei. Prüfen Sie die relevanten Adressen und Controller-Replikate.

5. Die Abweichung in einem temporären Cluster nachstellen

Das Skript erstellt einen eigenen kind-Cluster, installiert cert-manager und verwendet Traefik als Ingress-Controller. Ein SelfSigned Issuer erstellt site-tls für renewal.test. Das Certificate wird Ready, doch der Ingress verweist auf stale-tls mit einem anderen gültigen Zertifikat für denselben Hostnamen. Nach dem Wechsel der Referenz zu site-tls liefert die TLS-Prüfung das erwartete Zertifikat.

cert-manager-Demonstration herunterladen und prüfen

Voraussetzungen: ein lokaler Docker-Daemon, kind, kubectl, curl, Bash, OpenSSL und GNU coreutils unter Linux. Planen Sie mehrere GiB Arbeitsspeicher und Festplattenplatz für Cluster und Images ein. Getestet mit kind 0.33.0, Kubernetes und kubectl 1.35.8, cert-manager 1.21.3 und Traefik 3.7.16.

Lesen Sie das Skript und starten Sie es mit bash cert-manager-ingress-check.sh. Es nutzt eine private kubeconfig-Datei sowie eine Portweiterleitung über Loopback und entfernt beim Beenden seinen Cluster und die temporären Dateien. Auf den Host heruntergeladene Images bleiben im Cache.

READY bleibt True, BEFORE unterscheidet sich von EXPECTED und AFTER stimmt mit EXPECTED überein. Assertions prüfen diese Werte. Der Test umfasst eine tatsächliche Ausstellung durch cert-manager und das Laden am Ingress mit selbstsignierten Zertifikaten, keine ACME-Validierung, Erneuerung oder Vertrauensprüfung öffentlicher Browser.

6. Das Ergebnis prüfen und Ablaufwarnungen einrichten

Wiederholen Sie nach der Korrektur die externe Prüfung und notieren Sie Adresse, SNI, Beobachtungszeit und Fingerabdruck. Wird das erwartete Zertifikat ausgeliefert, aber vom Browser abgelehnt, prüfen Sie Kette, abgedeckte Hostnamen und Vertrauen in den Aussteller. Eine weitere Erneuerung behebt nicht jeden TLS-Fehler.

Nocert beobachtet regelmäßig die Zertifikate erreichbarer TLS-Endpunkte und wertet Regeln für Ablaufwarnungen täglich aus. Prüfen Sie Endpunkt und Beobachtungszeit und konfigurieren Sie die Empfänger. Das ergänzt die unmittelbare Prüfung nach einer Bereitstellung. Nocert ändert weder Ihr Kubernetes Secret noch Ihren Ingress, erneuert das Zertifikat nicht und garantiert nicht, dass alle Besucher dasselbe Zertifikat erhalten.

Technische Quellen