Zum Inhalt springen

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.

  • 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.

  1. 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.

  2. 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-manager
    helm 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-manager

    Sie erhalten eine Ausgabe wie diese:

    NAME READY STATUS RESTARTS AGE
    cert-manager-776649d6c6-5s66l 1/1 Running 0 42s
    cert-manager-cainjector-7bb8cb69c5-tvwxw 1/1 Running 0 42s
    cert-manager-webhook-5c8bfb9bdf-2jrcg 1/1 Running 0 42s
  3. 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 update
    kubectl create ns ingress-nginx
    helm install ingress-nginx ingress-nginx/ingress-nginx --namespace ingress-nginx

    Validieren Sie seinen Betriebsstatus durch Ausführen von:

    Terminal-Fenster
    kubectl get pods -n ingress-nginx

    Sie erhalten eine Ausgabe wie diese:

    NAME READY STATUS RESTARTS AGE
    ingress-nginx-controller-7687f9d45-rvglp 1/1 Running 0 43s
    Terminal-Fenster
    kubectl get svc -n ingress-nginx

    Sie erhalten eine Ausgabe wie diese:

    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    ingress-nginx-controller LoadBalancer 10.64.194.250 193.148.174.225 80:30055/TCP,443:31510/TCP 4m6s
    ingress-nginx-controller-admission ClusterIP 10.64.38.53 <none> 443/TCP 4m6s

    Dokumentieren Sie die externe IP-Adresse, da diese für die spätere Erstellung des A-Eintrags erforderlich ist.

  4. 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-webhook

    Bestätigen Sie, dass der Webhook betriebsbereit ist, indem Sie sein Erscheinen in der Pod-Liste überprüfen:

    Terminal-Fenster
    kubectl get pods -n cert-manager

    Sie erhalten eine Ausgabe wie diese:

    NAME READY STATUS RESTARTS AGE
    cert-manager-776649d6c6-5s66l 1/1 Running 0 24m
    cert-manager-cainjector-7bb8cb69c5-tvwxw 1/1 Running 0 24m
    cert-manager-webhook-5c8bfb9bdf-2jrcg 1/1 Running 0 24m
    stackit-cert-manager-webhook-78c855658f-wlzft 1/1 Running 0 15s
  5. 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
  6. 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
  7. Issuer-Initialisierung:

    Beachten Sie, dass die Parameter email und projectId genau 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 - <<EOF
    apiVersion: cert-manager.io/v1
    kind: Issuer
    metadata:
    name: letsencrypt-prod
    namespace: example-app
    spec:
    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-Adresse
    privateKeySecretRef:
    name: letsencrypt-prod
    solvers:
    - dns01:
    webhook:
    solverName: stackit
    groupName: acme.stackit.de
    config:
    projectId: <STACKIT PROJECT ID>
    EOF
  8. 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 - <<EOF
    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
    name: wildcard-example
    namespace: example-app
    spec:
    secretName: wildcard-example-tls
    issuerRef:
    name: letsencrypt-prod
    kind: Issuer
    commonName: '*.example.runs.onstackit.cloud' # Projekt muss Eigentümer dieser Zone sein
    duration: 8760h0m0s
    dnsNames:
    - 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.

    Liste der Einträge für Cert-Manager

    Terminal-Fenster
    kubectl get certs -n example-app

    Sie erhalten eine Ausgabe wie diese:

    NAME READY SECRET AGE
    wildcard-example True wildcard-example-tls 11m
  9. 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 - <<EOF
    apiVersion: v1
    kind: ConfigMap
    metadata:
    name: example-app
    namespace: example-app
    data:
    index.html: |
    <!DOCTYPE html>
    <html>
    <head>
    <title>ExampleApp</title>
    </head>
    <body>
    <header>
    <h1 id="Hello World">Hello World</h1>
    </header>
    </body>
    </html>
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: example-app
    namespace: example-app
    spec:
    replicas: 1
    selector:
    matchLabels:
    app: example-app
    template:
    metadata:
    labels:
    app: example-app
    spec:
    containers:
    - name: nginx
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts:
    - name: config-volume
    mountPath: /usr/share/nginx/html
    volumes:
    - name: config-volume
    configMap:
    name: example-app
    ---
    apiVersion: v1
    kind: Service
    metadata:
    name: example-app
    namespace: example-app
    spec:
    selector:
    app: example-app
    ports:
    - protocol: TCP
    port: 80
    targetPort: 80
    EOF
    Terminal-Fenster
    kubectl get pods -n example-app

    Sie erhalten eine Ausgabe wie diese:

    NAME READY STATUS RESTARTS AGE
    example-app-588974765d-r6shs 1/1 Running 0 23s
  10. 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: Liste der Einträge für Cert-Manager mit Wildcard-A-Eintrag

  11. 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 - <<EOF
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
    name: app-ingress
    namespace: example-app
    annotations:
    ingress.kubernetes.io/rewrite-target: /
    spec:
    ingressClassName: "nginx"
    rules:
    - host: "*.example.runs.onstackit.cloud"
    http:
    paths:
    - path: /
    pathType: Prefix
    backend:
    service:
    name: example-app
    port:
    number: 80
    tls:
    - hosts:
    - "*.example.runs.onstackit.cloud"
    secretName: wildcard-example-tls
    EOF
  12. 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. Browser-Screenshot der SSL-Verifizierung