STACKIT DNS für DNS01 verwenden, um als DNS01-ACME-Issuer mit Cert-Manager zu fungieren
Diese Anleitung beschreibt die Integration von STACKIT DNS mit Cert Manager, um die Nutzung von DNS-01-ACME-Issuern zu ermöglichen. Zu den durch dieses Setup ermöglichten Funktionen gehört die Bereitstellung von Wildcard-SSL-Zertifikaten für eine spezifische DNS-Zone.
Voraussetzungen
Abschnitt betitelt „Voraussetzungen“- Cluster-Typ: SKE: Diese Anleitung enthält spezifische Anweisungen für das Deployment auf einem SKE-Cluster. Alternative Cluster-Konfigurationen können abweichende Implementierungsschritte erfordern.
- Erforderliche Zugangsdaten: Ein dediziertes Service-Konto und ein entsprechender Authentifizierungstoken sind für den Deployment-Prozess erforderlich. Cert Manager wird programmatisch einen temporären TXT-Eintrag in der DNS-Zone erstellen und löschen, wofür das Service-Konto Berechtigungen auf Projektmitglied-Ebene benötigt.
- Mechanismus zur Anwendungsexposition: Diese Dokumentation setzt die Verwendung eines SKE-Clusters voraus. Folglich können die Methoden zur Exposition von Anwendungen über Load-Balancer- oder NodePort-Dienste je nach Ihrer Cluster-Konfiguration variieren.
- Komponenteninstallation über Helm: Für ein optimiertes Komponenten-Deployment verwendet diese Anleitung Helm als Paketmanager. Helm erleichtert die Installation mehrerer abhängiger Komponenten.
Durch die Einhaltung dieser Voraussetzungen sind Sie besser auf die folgenden in diesem Tutorial beschriebenen Schritte vorbereitet.
Implementierung
Abschnitt betitelt „Implementierung“-
DNS-Zonen-Konfiguration in STACKIT:
Erstellen Sie eine DNS-Zone wie beschrieben. Zur Veranschaulichung wurde eine primäre Zone mit unserer Subdomain-Funktion — example.runs.onstackit.cloud — erstellt. Die Wahl Ihrer Zone ist flexibel, sie muss jedoch an STACKIT DNS delegiert werden. Dies stellt sicher, dass Cert Manager einen Eintrag innerhalb der Zone erfolgreich auflösen kann.
-
Cert-Manager-Deployment auf dem Kubernetes-Cluster:
Fahren Sie mit der Cert-Manager-Installation in Ihrem Kubernetes-Cluster fort, indem Sie der Installationsanleitung in der Cert-Manager-Dokumentation folgen:
Terminal-Fenster kubectl create ns cert-managerhelm repo add jetstack [https://charts.jetstack.io](https://charts.jetstack.io)helm install cert-manager --namespace cert-manager jetstack/cert-manager --set webhook.timeoutSeconds=15 --set crds.enabledÜberprüfen Sie das erfolgreiche Deployment, indem Sie die Pods im cert-manager-Namespace inspizieren:
Terminal-Fenster kubectl get pods -n cert-managerSie erhalten eine Ausgabe wie diese:
NAME READY STATUS RESTARTS AGEcert-manager-776649d6c6-5s66l 1/1 Running 0 42scert-manager-cainjector-7bb8cb69c5-tvwxw 1/1 Running 0 42scert-manager-webhook-5c8bfb9bdf-2jrcg 1/1 Running 0 42s -
Reverse-Proxy-Installation: Nginx-Ingress-Controller:
Stellen Sie einen Reverse-Proxy bereit, wie zum Beispiel den Nginx Ingress Controller:
Terminal-Fenster helm repo add ingress-nginx [https://kubernetes.github.io/ingress-nginx](https://kubernetes.github.io/ingress-nginx)helm repo updatekubectl create ns ingress-nginxhelm install ingress-nginx ingress-nginx/ingress-nginx --namespace ingress-nginxValidieren Sie seinen Betriebsstatus durch Ausführen von:
Terminal-Fenster kubectl get pods -n ingress-nginxSie erhalten eine Ausgabe wie diese:
NAME READY STATUS RESTARTS AGEingress-nginx-controller-7687f9d45-rvglp 1/1 Running 0 43sTerminal-Fenster kubectl get svc -n ingress-nginxSie erhalten eine Ausgabe wie diese:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEingress-nginx-controller LoadBalancer 10.64.194.250 193.148.174.225 80:30055/TCP,443:31510/TCP 4m6singress-nginx-controller-admission ClusterIP 10.64.38.53 <none> 443/TCP 4m6sDokumentieren Sie die externe IP-Adresse, da diese für die spätere Erstellung des A-Eintrags erforderlich ist.
-
STACKIT Cert Manager Webhook-Installation:
Installieren Sie den STACKIT Cert Manager Webhook.
Terminal-Fenster helm repo add stackit-cert-manager-webhook [https://stackitcloud.github.io/stackit-cert-manager-webhook](https://stackitcloud.github.io/stackit-cert-manager-webhook)helm install stackit-cert-manager-webhook --namespace cert-manager stackit-cert-manager-webhook/stackit-cert-manager-webhookBestätigen Sie, dass der Webhook betriebsbereit ist, indem Sie sein Erscheinen in der Pod-Liste überprüfen:
Terminal-Fenster kubectl get pods -n cert-managerSie erhalten eine Ausgabe wie diese:
NAME READY STATUS RESTARTS AGEcert-manager-776649d6c6-5s66l 1/1 Running 0 24mcert-manager-cainjector-7bb8cb69c5-tvwxw 1/1 Running 0 24mcert-manager-webhook-5c8bfb9bdf-2jrcg 1/1 Running 0 24mstackit-cert-manager-webhook-78c855658f-wlzft 1/1 Running 0 15s -
Namespace-Erstellung für das Application-Deployment:
Erzeugen Sie einen Kubernetes-Namespace, in dem sich Ihre Anwendung befinden wird:
Terminal-Fenster kubectl create ns example-app -
Service Account-Key-Konfiguration (
sa.json): Diese Anleitung setzt die Nutzung eines Namespace-spezifischen Cert-Manager-Issuers im Gegensatz zu einem Cluster-Issuer voraus. Erstellen Sie im neuen Namespace ein Secret, das den STACKIT Service Account-Key (sa.json) enthält. Erstellen Sie das Secret im gleichen Namespace wie den Herausgeber (hier:example-app):Terminal-Fenster kubectl create secret generic stackit-sa-authentication \-n example-app \--from-literal=sa.json='{"id": "4e1fe486-b463-4bcd-9210-288854268e34","publicKey": "-----BEGIN PUBLIC KEY-----\nPUBLIC_KEY\n-----END PUBLIC KEY-----","createdAt": "2024-04-02T13:12:17.678+00:00","validUntil": "2024-04-15T22:00:00.000+00:00","keyType": "USER_MANAGED","keyOrigin": "GENERATED","keyAlgorithm": "RSA_2048","active": true,"credentials": {"kid": "kid","iss": "iss","sub": "sub","aud": "aud","privateKey": "-----BEGIN PRIVATE KEY-----\nPRIVATE-KEY==\n-----END PRIVATE KEY-----"}}'Aktivieren Sie die Service Account-Authentifizierung für das Webhook-Deployment:
Terminal-Fenster helm upgrade stackit-cert-manager-webhook \--namespace cert-manager \stackit-cert-manager-webhook/stackit-cert-manager-webhook \--set stackitSaAuthentication.enabled=true -
Issuer-Initialisierung:
Beachten Sie, dass die Parameter
emailundprojectIdgenau konfiguriert sein müssen; andernfalls wird Cert Manager bei der Zertifikatsbereitstellung auf Fehler stoßen. Let’s Encrypt wird Ihre E-Mail-Adresse verwenden, um Sie über ablaufende Zertifikate und Probleme im Zusammenhang mit Ihrem Konto zu informieren. Die STACKIT projectId sollte mit der in Schritt 1 erstellten Zone übereinstimmen. Sie können diese aus dem Portal-Dashboard kopieren.Terminal-Fenster kubectl apply -f - <<EOFapiVersion: cert-manager.io/v1kind: Issuermetadata:name: letsencrypt-prodnamespace: example-appspec:acme:server: [https://acme-v02.api.letsencrypt.org/directory](https://acme-v02.api.letsencrypt.org/directory)email: example@example.com # Ersetzen Sie dies durch Ihre E-Mail-AdresseprivateKeySecretRef:name: letsencrypt-prodsolvers:- dns01:webhook:solverName: stackitgroupName: acme.stackit.deconfig:projectId: <STACKIT PROJECT ID>EOF -
Wildcard-Zertifikats-Deployment:
Erstellen Sie ein Wildcard-SSL-Zertifikat für die DNS-Zone, wodurch alle Subdomain-Einträge SSL-konform werden.
Terminal-Fenster kubectl apply -f - <<EOFapiVersion: cert-manager.io/v1kind: Certificatemetadata:name: wildcard-examplenamespace: example-appspec:secretName: wildcard-example-tlsissuerRef:name: letsencrypt-prodkind: IssuercommonName: '*.example.runs.onstackit.cloud' # Projekt muss Eigentümer dieser Zone seinduration: 8760h0m0sdnsNames:- example.runs.onstackit.cloud- '*.example.runs.onstackit.cloud'EOFÜberwachen Sie das Erscheinen eines neuen TXT-Eintrags; sobald dieser propagiert wurde, wird Cert Manager diesen Eintrag automatisch widerrufen und das Zertifikat aktivieren.

Terminal-Fenster kubectl get certs -n example-appSie erhalten eine Ausgabe wie diese:
NAME READY SECRET AGEwildcard-example True wildcard-example-tls 11m -
Application-Deployment:
Stellen Sie Ihre Anwendung bereit und validieren Sie deren erfolgreiche Instanziierung, indem Sie einen laufenden Pod im Kubernetes-Dashboard beobachten.
Terminal-Fenster kubectl apply -f - <<EOFapiVersion: v1kind: ConfigMapmetadata:name: example-appnamespace: example-appdata:index.html: |<!DOCTYPE html><html><head><title>ExampleApp</title></head><body><header><h1 id="Hello World">Hello World</h1></header></body></html>---apiVersion: apps/v1kind: Deploymentmetadata:name: example-appnamespace: example-appspec:replicas: 1selector:matchLabels:app: example-apptemplate:metadata:labels:app: example-appspec:containers:- name: nginximage: nginxports:- containerPort: 80volumeMounts:- name: config-volumemountPath: /usr/share/nginx/htmlvolumes:- name: config-volumeconfigMap:name: example-app---apiVersion: v1kind: Servicemetadata:name: example-appnamespace: example-appspec:selector:app: example-appports:- protocol: TCPport: 80targetPort: 80EOFTerminal-Fenster kubectl get pods -n example-appSie erhalten eine Ausgabe wie diese:
NAME READY STATUS RESTARTS AGEexample-app-588974765d-r6shs 1/1 Running 0 23s -
Erstellen eines A-Eintrags:
Erzeugen Sie einen Wildcard-A-Eintrag innerhalb der DNS-Zone unter Verwendung der in Schritt 3 erhaltenen externen IP-Adresse. In unserem Beispiel lautet er: *.example.runs.onstackit.cloud:

-
Application-Ingress-Konfiguration:
Erstellen Sie eine Ingress-Regel für die Anwendung und stellen Sie sicher, dass das Wildcard-Zertifikat und die Namen der Ingress-Secrets übereinstimmen. Der Host sollte dem im vorhergehenden Schritt erstellten A-Eintrag entsprechen.
Terminal-Fenster kubectl apply -f - <<EOFapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: app-ingressnamespace: example-appannotations:ingress.kubernetes.io/rewrite-target: /spec:ingressClassName: "nginx"rules:- host: "*.example.runs.onstackit.cloud"http:paths:- path: /pathType: Prefixbackend:service:name: example-appport:number: 80tls:- hosts:- "*.example.runs.onstackit.cloud"secretName: wildcard-example-tlsEOF -
SSL-Verifizierung:
Navigieren Sie in einem Webbrowser zu einer beliebigen Subdomain, die mit dem Wildcard übereinstimmt, z. B. app.example.runs.onstackit.cloud. Sie sollten ein aktives SSL-Zertifikat sehen, was die erfolgreiche Verschlüsselungskonfiguration bestätigt.
