BLOG | NGINX

Aktivieren der Self-Service-DNS- und Zertifikatsverwaltung in Kubernetes

NGINX-Teil-von-F5-horiz-schwarz-Typ-RGB
Jason Schmidt Miniaturbild
Jason Schmidt
Veröffentlicht am 01. November 2022

Das ultimative Ziel der Anwendungsentwicklung besteht natürlich darin, Apps im Internet verfügbar zu machen. Für einen Entwickler vereinfacht Kubernetes diesen Prozess bis zu einem gewissen Grad, indem es den Ingress-Controller als Mechanismus zum Weiterleiten von Anforderungen an die Anwendung bereitstellt. Allerdings ist nicht alles so selbstbedienbar, wie Sie es sich wahrscheinlich wünschen: Sie benötigen weiterhin einen Eintrag im Domain Name System (DNS), um den Domänennamen für die App der IP-Adresse des Ingress-Controllers zuzuordnen, und ein TLS-Zertifikat, um Verbindungen mit HTTPS zu sichern. In den meisten Organisationen besitzen Sie DNS oder TLS nicht selbst und müssen sich daher mit der (oder den) operativen Gruppe(n!) abstimmen, die darüber verfügen.

Für die Betreiber wird es dadurch nicht unbedingt einfacher. In den meisten Organisationen ist die Notwendigkeit zur Aktualisierung von DNS-Einträgen so selten, dass entsprechende Verfahren – sowohl Geschäftsregeln als auch die eigentlichen technischen Schritte – eher spärlich oder gar nicht vorhanden sind. Dies bedeutet, dass Sie, wenn Sie einen DNS-Eintrag hinzufügen müssen, zuerst die Dokumentation suchen, einen Kollegen fragen oder (im schlimmsten Fall) es selbst herausfinden müssen. Sie müssen außerdem sicherstellen, dass Sie sämtliche Sicherheitsregeln des Unternehmens einhalten und dass der eingehende Datenverkehr für die Firewalls ordnungsgemäß gekennzeichnet ist.

Glücklicherweise gibt es eine Möglichkeit, sowohl Entwicklern als auch Betreibern das Leben zu erleichtern. In diesem Beitrag zeigen wir, wie Betreiber eine Kubernetes-Bereitstellung konfigurieren können, um Entwicklern die Aktualisierung von DNS-Einträgen und die Generierung von TLS-Zertifikaten in einer Kubernetes-Umgebung im Self-Service zu ermöglichen. Indem Sie die Infrastruktur frühzeitig ausbauen, können Sie sicherstellen, dass alle notwendigen geschäftlichen und technischen Anforderungen erfüllt werden.

Überblick und Voraussetzungen

Wenn die Lösung vorhanden ist, muss ein Entwickler, um eine Anwendung im Internet verfügbar zu machen, lediglich einen Ingress-Controller gemäß einer bereitgestellten Vorlage erstellen, die einen vollqualifizierten Domänennamen (FQDN) innerhalb einer von der Kubernetes-Installation verwalteten Domäne enthält. Kubernetes verwendet die Vorlage, um dem Ingress-Controller eine IP-Adresse zuzuweisen, den DNS- A -Eintrag zu erstellen, um den FQDN der IP-Adresse zuzuordnen, TLS-Zertifikate für den FQDN zu generieren und sie dem Ingress-Controller hinzuzufügen. Die Bereinigung ist ebenso einfach: Wenn der Ingress entfernt wird, werden die DNS-Einträge bereinigt.

Die Lösung nutzt die folgenden Technologien (Anweisungen zur Installation und Konfiguration finden Sie weiter unten):

Bevor Sie die Lösung konfigurieren, benötigen Sie:

  • Eine Kubernetes-Cloud-Installation mit einem Egress-Objekt ( LoadBalancer ). Die Lösung verwendet Linode, aber auch andere Cloud-Anbieter funktionieren.
  • Ein bei Cloudflare gehosteter Domänenname, den wir ausgewählt haben, weil es einer der unterstützten DNS-Anbieter für Cert-Manager ist und ExternalDNS unterstützt (zum Zeitpunkt des Schreibens in der Beta -Version). Wir empfehlen dringend, die Domäne nicht für Produktions- oder andere kritische Zwecke zu verwenden.
  • Zugriff auf die Cloudflare-API, die im kostenlosen Kontingent enthalten ist.
  • Helm zum Installieren und Bereitstellen von Kubernetes.
  • kubectl als Befehlszeilenschnittstelle für Kubernetes.
  • Optional: K9s , eine gut konstruierte greifbare Benutzeroberfläche (TUI), die eine strukturiertere Möglichkeit zur Interaktion mit Kubernetes bietet.

Wir setzen außerdem voraus, dass Sie über grundlegende Kenntnisse von Kubernetes verfügen (wie Sie ein Manifest anwenden, ein Helm-Diagramm verwenden und kubectl -Befehle ausgeben, um die Ausgabe anzuzeigen und Probleme zu beheben). Das Verständnis der grundlegenden Konzepte von Let‘s Encrypt ist hilfreich, aber nicht erforderlich; einen Überblick finden Sie in unserem Blog . Sie müssen auch nicht wissen, wie der Cert-Manager funktioniert, aber wenn Sie daran interessiert sind, wie er (und Zertifikate im Allgemeinen) mit dem NGINX Ingress Controller funktionieren, lesen Sie meinen neuesten Beitrag „Automatisierung der Zertifikatsverwaltung in einer Kubernetes-Umgebung “.

Wir haben die Lösung sowohl auf macOS als auch auf Linux getestet. Wir haben es nicht auf dem Windows-Subsystem für Linux Version 2 (WSL2) getestet, erwarten aber keine Probleme.

Notiz: Die Lösung ist als Beispiel für einen Proof of Concept gedacht und nicht für den Produktionseinsatz. Insbesondere berücksichtigt es nicht alle Best Practices für Betrieb und Sicherheit. Informationen zu diesen Themen finden Sie in der Cert-Manager- und ExternalDNS -Dokumentation.

Bereitstellen der Lösung

Befolgen Sie die Schritte in diesen Abschnitten, um die Lösung bereitzustellen:

Software herunterladen
  1. Laden Sie Ihr Cloudflare API-Token herunter.
  2. Klonen Sie das NGINX Ingress Controller-Repository:

    $ git clone https://github.com/nginxinc/kubernetes-ingress.git Klonen in „kubernetes-ingress“ … remote: Objekte aufzählen: 45176, fertig. Fernbedienung: Objekte zählen: 100 % (373/373), erledigt. Fernbedienung: Komprimieren von Objekten: 100 % (274/274), fertig. Fernbedienung: Gesamt 45176 (Delta 173), wiederverwendet 219 (Delta 79), Pack-wiederverwendet 44803 Empfangene Objekte: 100 % (45176/45176), 60,45 MiB | 26,81 MiB/s, fertig.
    Auflösen von Deltas: 100 % (26592/26592), erledigt.
  3. Überprüfen Sie, ob Sie eine Verbindung zum Kubernetes-Cluster herstellen können.

    $ kubectl cluster-info Die Kubernetes-Steuerungsebene läuft unter https://ba35bacf-b072-4600-9a04-e04...6a3d.us-west-2.linodelke.net:443. KubeDNS läuft unter https://ba35bacf-b072-4600-9a04-e04...6a3d.us-west-2.linodelke.net:443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy. Verwenden Sie zum weiteren Debuggen und Diagnostizieren von Clusterproblemen „kubectl cluster-info dump“.

Bereitstellen des NGINX Ingress Controllers

  1. Stellen Sie mit Helm den NGINX Ingress Controller bereit. Beachten Sie, dass wir drei nicht standardmäßige Konfigurationsoptionen hinzufügen:

    • controller.enableCustomResources – Weist Helm an, die benutzerdefinierten Ressourcendefinitionen (CRDs) zu installieren, die zum Erstellen der benutzerdefinierten NGINX VirtualServer- und VirtualServerRoute- Ressourcen verwendet werden.
    • controller.enableCertManager – Konfiguriert den NGINX Ingress Controller für die Kommunikation mit Cert-Manager -Komponenten.
    • controller.enableExternalDNS – Konfiguriert den Ingress Controller für die Kommunikation mit ExternalDNS-Komponenten.
    $ helm install nginx-kic nginx-stable/nginx-ingress --namespace nginx-ingress --set controller.enableCustomResources=true --create-namespace --set controller.enableCertManager=true --set controller.enableExternalDNS=true NAME: nginx-kic LETZTE BEREITSTELLUNG: Tag Mo TT hh : mm : ss JJJJ NAMESPACE: nginx-ingress STATUS: bereitgestellt REVISION: 1 TESTSUITE: Keine ANMERKUNGEN:
    Der NGINX Ingress Controller wurde installiert.
  2. Überprüfen Sie, ob der NGINX Ingress Controller ausgeführt wird, und notieren Sie sich den Wert im Feld „EXTERNAL-IP“ . Dies ist die IP-Adresse für den NGINX Ingress Controller (hier: www.xxx.yyy.zzz ). Die Ausgabe ist der Lesbarkeit halber auf zwei Zeilen verteilt.

    $ kubectl get services --namespace nginx-ingress NAME TYP CLUSTER-IP ... nginx-kic-nginx-ingress LoadBalancer 10.128.152.88 ... ... EXTERNE IP-PORTS ALTER ... www.xxx.yyy.zzz 80:32457/TCP,443:31971/TCP 3h8m

Bereitstellen des Zertifikatmanagers

In der Lösung verwendet cert-manager beim Abrufen eines TLS-Zertifikats den Challenge-Typ DNS-01 , wofür beim Erstellen der ClusterIssuer-Ressource das Cloudflare-API-Token bereitgestellt werden muss. In der Lösung wird das API-Token als Kubernetes- Geheimnis bereitgestellt.

  1. Stellen Sie mit Helm den Cert-Manager bereit :

    $ helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --version v1.9.1 --set installCRDs=true NAME: cert-manager LETZTE BEREITSTELLUNG: Tag Mo TT hh : mm : ss JJJJ NAMESPACE: cert-manager STATUS: bereitgestellt REVISION: 1 TESTSUITE: Keine HINWEISE: cert-manager v1.9.1 wurde erfolgreich bereitgestellt!
  2. Stellen Sie das Cloudflare-API-Token als Kubernetes-Geheimnis bereit und ersetzen Sie es durch <Ihr API-Token>:

    $ kubectl apply -f - <<EOFapiVersion: v1
    Art: Geheime Metadaten: Name: Cloudflare-API-Token-Secret-Namespace: Cert-Manager-Typ: Undurchsichtig
    StringData:
    API-Token: "<Ihr API-Token>"
    EOF
    Geheimnis/Cloudflare-API-Token-Geheimnis erstellt
  3. Erstellen Sie ein ClusterIssuer-Objekt und geben Sie Cloudflare-api-token-secret (im vorherigen Schritt definiert) als Ort zum Abrufen des Tokens an. Wenn Sie möchten, können Sie „example-issuer“ im Feld „metadata.name“ (und „example-issuer-account-key“ im Feld „spec.acme.privateKeySecretRef.name“ ) durch einen anderen Namen ersetzen.

    $ kubectl apply -f - <<EOFapiVersion: cert-manager.io/v1
    Art: ClusterIssuer-Metadaten: Name: Beispiel-Aussteller Namespace: Zertifikatsmanager Spezifikation: Acme: E-Mail: example@example.com Server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: Name: Beispiel-Aussteller-Kontoschlüssel Solver: - DNS01:
              Cloudflare: apiTokenSecretRef: Name: Cloudflare-API-Token-Geheimschlüssel: API-Token EOF clusterissuer.cert-manager.io/example-issuer erstellt
  4. Überprüfen Sie, ob der ClusterIssuer bereitgestellt und bereit ist (der Wert im Feld READY ist True ).

    $ kubectl get clusterissuer NAME READY AGE Beispiel-Aussteller True 3h9m

ExternalDNS bereitstellen

Wie cert-manager erfordert das ExternalDNS-Projekt ein Cloudflare-API-Token zur Verwaltung von DNS. Derselbe Token kann für beide Projekte verwendet werden, das ist jedoch nicht erforderlich.

  1. Erstellen Sie die ExternalDNS-CRDs für den NGINX Ingress Controller, um die Integration zwischen den Projekten zu ermöglichen.

    $ kubectl create -f ./kubernetes-ingress/deployments/common/crds/externaldns.nginx.org_dnsendpoints.yaml customresourcedefinition.apiextensions.k8s.io/dnsendpoints.externaldns.nginx.org erstellt
  2. Erstellen Sie den externen DNS-Dienst ( external-dns ). Da das Manifest ziemlich lang ist, teilen wir es hier in zwei Teile auf. Der erste Teil konfiguriert Konten, Rollen und Berechtigungen:

    • Erstellt ein ServiceAccount-Objekt namens „external-dns“, um alle Schreib- und Aktualisierungsvorgänge für die DNS-Verwaltung zu verwalten.
    • Erstellt ein ClusterRole-Objekt (auch external-dns genannt), das die erforderlichen Berechtigungen definiert.
    • Bindet die Clusterrolle an den Serviceaccount.
    $ kubectl apply -f - <<EOFapiVersion: v1
    Art: ServiceAccount-Metadaten: Name: externes DNS --- API-Version: rbac.authorization.k8s.io/v1 Art: ClusterRole-Metadaten: Name: External-DNS-Regeln: - API-Gruppen: [""] Ressourcen: ["Dienste", "Endpunkte", "Pods"] Verben: ["Abrufen", "Überwachen", "Auflisten"] - API-Gruppen: ["Erweiterungen", "Networking.k8s.io"] Ressourcen: ["Eingänge"] Verben: ["Abrufen", "Überwachen", "Auflisten"] - API-Gruppen: ["externaldns.nginx.org"] Ressourcen: ["DNS-Endpunkte"] Verben: ["Abrufen", "Überwachen", "Auflisten"] - API-Gruppen: ["externaldns.nginx.org"] Ressourcen: ["DNS-Endpunkte/Status"] Verben: ["Aktualisieren"] - API-Gruppen: [""] Ressourcen: ["Knoten"] Verben: ["Auflisten", "Überwachen"] --- API-Version: rbac.authorization.k8s.io/v1 Art: ClusterRoleBinding-Metadaten: Name: External-DNS-Viewer RoleRef: API-Gruppe: rbac.authorization.k8s.io Art: ClusterRole-Name: externes DNS Themen: - Art: ServiceAccount-Name: external-dns Namespace: Standard-EOF serviceaccount/external-dns erstellt clusterrole.rbac.authorization.k8s.io/external-dns erstellt clusterrolebinding.rbac.authorization.k8s.io/external-dns-viewer erstellt

    Der zweite Teil des Manifests erstellt die ExternalDNS-Bereitstellung:

    • Erstellt einen Domänenfilter, der den Umfang möglicher Schäden begrenzt, die durch ExternalDNS bei der Verwaltung von Domänen verursacht werden. Sie können beispielsweise die Domänennamen von Staging-Umgebungen angeben, um Änderungen an Produktionsumgebungen zu verhindern. In diesem Beispiel setzen wir den Domänenfilter auf example.com .
    • Legt die Umgebungsvariable CF_API_TOKEN auf Ihr Cloudflare-API-Token fest. Für <Ihr API-Token>, ersetzen Sie entweder das eigentliche Token oder ein Geheimnis, das das Token enthält. Im letzteren Fall müssen Sie das Geheimnis auch mithilfe einer Umgebungsvariablen in den Container projizieren .
    • Setzt die Umgebungsvariable FREE_TIER auf „true“ (angemessen, sofern Sie nicht über ein kostenpflichtiges Cloudflare-Abonnement verfügen).
    $  kubectl apply -f - <<EOF 
    ---
    apiVersion: apps/v1
    Art: Bereitstellungsmetadaten: Name: externes DNS, Spezifikation: Strategie: Typ: Selektor neu erstellen: matchLabels: App: Externes DNS Vorlage: Metadaten: Labels: App: Externes DNS Spezifikation: serviceAccountName: Externes DNS Container: - Name: Externes DNS Image: k8s.gcr.io/external-dns/external-dns:v0.12.0 Argumente: - --source=service - --source=ingress - --source=crd - --crd-source-apiversion=externaldns.nginx.org/v1 - --crd-source-kind=DNSEndpoint - --domain-filter=example.com - --provider=Cloudflare Umgebung: - Name: CF_API_TOKEN
    Wert: "<Ihr API-Token>"
              - Name: FREE_TIER-Wert: „true“ EOF serviceaccount/external-dns erstellt clusterrole.rbac.authorization.k8s.io/external-dns erstellt clusterrolebinding.rbac.authorization.k8s.io/external-dns-viewer erstellt deployment.apps/external-dns erstellt

Bereitstellen der Beispielanwendung

Verwenden Sie zu Testzwecken die standardmäßige NGINX Ingress Controller-Beispielanwendung namens Cafe .

  1. Stellen Sie die Cafe-Anwendung bereit.

    $ kubectl apply -f ./kubernetes-ingress/examples/ingress-resources/complete-example/cafe.yaml deployment.apps/coffee erstellt service/coffee-svc erstellt deployment.apps/tea erstellt service/tea-svc erstellt
  2. Stellen Sie den NGINX Ingress Controller für die Cafe-Anwendung bereit. Beachten Sie folgende Einstellungen:

    • Art: VirtualServer – Wir verwenden die benutzerdefinierte NGINX VirtualServer-Ressource, nicht die standardmäßige Kubernetes-Ingress-Ressource.
    • spec.host – Ersetzen Sie cafe.example.com durch den Namen des Hosts, den Sie bereitstellen. Der Host muss sich innerhalb der Domäne befinden, die mit ExternalDNS verwaltet wird.
    • spec.tls.cert-manager.cluster-issuer – Wenn Sie die in diesem Beitrag angegebenen Werte verwendet haben, ist dies example-issuer . Ersetzen Sie ihn bei Bedarf durch den Namen, den Sie in Schritt 3 von „Cert‑Manager bereitstellen“ gewählt haben.
    • spec.externalDNS.enable – Der Wert „true“ weist ExternalDNS an, einen DNS- A- Eintrag zu erstellen.

    Beachten Sie, dass die für diesen Schritt benötigte Zeit stark vom DNS-Anbieter abhängt, da Kubernetes mit der DNS-API des Anbieters interagiert.

    $ kubectl apply -f - <<EOFapiVersion: k8s.nginx.org/v1
    Art: VirtualServer-Metadaten: Name: Cafe Spezifikation: Host: Cafe.example.com TLS: Geheimnis: Cafe-Geheimnis Zertifikatsmanager: Cluster-Aussteller: Beispiel-Aussteller ExternalDNS: Aktivieren: True Upstreams: - Name: Tea-Dienst: Tea-SVC-Port: 80 - Name: Kaffeeservice: Kaffee-Service-Port: 80 Routen: - Pfad: /tea Aktion: Pass: tea - Pfad: /coffee Aktion: Pass: coffee EOF virtualserver.k8s.nginx.org/cafe erstellt

Validieren der Lösung

  1. Überprüfen Sie den DNS- A- Eintrag – insbesondere, ob im Block ANSWER SECTION der FQDN (hier cafe.example.com ) der richtigen IP-Adresse ( www.xxx.yyy.zzz ) zugeordnet ist.

    $ dig cafe.example.com ; <<>> DiG 9.10.6 <<>> cafe.example.com ;; globale Optionen: +cmd ;; Antwort erhalten: ;; ->>HEADER<<- Operationscode: ABFRAGE, Status: KEIN FEHLER, ID: 22633 ;; Flags: qr rd ra; ANFRAGE: 1, ANTWORT: 1, AUTORITÄT: 0, ZUSÄTZLICH: 1 ;; OPT PSEUDOSECTION: ; EDNS: Version: 0, Flaggen:; 4096 ;; FRAGENABSCHNITT: ;cafe.example.com.		IN EINEM ;; ANTWORTABSCHNITT: cafe.example.com.	279 IN A www.xxx.yyy.zzz ;; Abfragezeit: 1 ms ;; SERVER: 2607:fb91:119b:4ac4:2e0: xxxx :fe1e:1359#53(2607:fb91:119b:4ac4:2e0: xxxx :fe1e:1359) ;; WENN: Tag Mo TT hh : mm : ss TZ JJJJ ;; MSG-GRÖSSE empfangen: 67
  2. Überprüfen Sie, ob das Zertifikat gültig ist (der Wert im Feld READY ist True ).

    $ kubectl get certificates NAME BEREIT GEHEIM ALTER cafe-secret Echtes cafe-secret 8m51s
  3. Überprüfen Sie, ob Sie die Anwendung erreichen können.

    $ curl https://cafe.example.com/coffee Serveradresse: 10.2.2.4:8080 Servername: coffee-7c86d7d67c-lsfs6 Datum: TT/Mon/JJJJ:hh:mm:ss +TZ-Offset URI: /coffee Anforderungs-ID: 91077575f19e6e735a91b9d06e9684cd $ curl https://cafe.example.com/tea Serveradresse: 10.2.2.5:8080 Servername: tea-5c457db9-ztpns Datum: TT/Mon/JJJJ:hh:mm:ss +TZ-Offset URI: /tea Anforderungs-ID: 2164c245a495d22c11e900aa0103b00f

Was passiert, wenn ein Entwickler den NGINX Ingress Controller einsetzt?

Sobald die Lösung vorhanden ist, passiert viel im Hintergrund. Das Diagramm zeigt, was passiert, wenn ein Entwickler den NGINX Ingress Controller mit einer benutzerdefinierten NGINX VirtualServer-Ressource bereitstellt. Beachten Sie, dass einige betriebstechnische Details ausgelassen wurden.

  1. Der Entwickler stellt eine VirtualServer-Ressource mithilfe des NGINX CRD bereit.
  2. Kubernetes erstellt den VirtualServer mit dem NGINX Ingress Controller
  3. NGINX Ingress Controller ruft ExternalDNS auf, um einen DNS A -Eintrag zu erstellen
  4. ExternalDNS erstellt den A- Eintrag im DNS
  5. NGINX Ingress Controller ruft den Cert-Manager auf, um ein TLS-Zertifikat anzufordern
  6. cert-manager fügt einen DNS-Eintrag zur Verwendung während der DNS-01- Challenge hinzu
  7. cert-manager kontaktiert Let’s Encrypt, um die Herausforderung abzuschließen
  8. Let’s Encrypt validiert die Challenge gegenüber DNS
  9. Let’s Encrypt stellt das TLS-Zertifikat aus
  10. cert-manager stellt das TLS-Zertifikat für den NGINX Ingress Controller bereit
  11. Der NGINX Ingress Controller leitet TLS-gesicherte externe Anfragen an die Anwendungs-Pods weiter.

Fehlerbehebung

Angesichts der Komplexität von Kubernetes und der von uns verwendeten Komponenten ist es schwierig, eine umfassende Anleitung zur Fehlerbehebung bereitzustellen. Dennoch gibt es einige grundlegende Vorschläge, die Ihnen bei der Ermittlung des Problems helfen können.

  • Verwenden Sie die Befehle „kubectl get“ und „kubectl describe“, um die Konfiguration bereitgestellter Objekte zu validieren.
  • Verwenden Sie die kubectl Protokolle <Komponente> Befehl zum Anzeigen der Protokolldateien für die verschiedenen bereitgestellten Komponenten.
  • Verwenden Sie K9s , um die Installation zu überprüfen. Die Software hebt Probleme in Gelb oder Rot hervor (je nach Schweregrad) und bietet eine Schnittstelle für den Zugriff auf Protokolle und Details zu Objekten.

Wenn Sie weiterhin Probleme haben, finden Sie uns im NGINXCommunity Slack und bitten Sie um Hilfe! Wir haben eine lebendige Community und arbeiten Probleme immer gerne gemeinsam durch.

Um den auf NGINX Plus basierenden NGINX Ingress Controller auszuprobieren, starten Sie noch heute Ihre 30-tägige kostenlose Testversion oder kontaktieren Sie uns, um Ihre Anwendungsfälle zu besprechen .


„Dieser Blogbeitrag kann auf Produkte verweisen, die nicht mehr verfügbar und/oder nicht mehr unterstützt werden. Die aktuellsten Informationen zu verfügbaren F5 NGINX-Produkten und -Lösungen finden Sie in unserer NGINX-Produktfamilie . NGINX ist jetzt Teil von F5. Alle vorherigen NGINX.com-Links werden auf ähnliche NGINX-Inhalte auf F5.com umgeleitet."