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.
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:
LoadBalancer
). Die Lösung verwendet Linode, aber auch andere Cloud-Anbieter funktionieren.kubectl
als Befehlszeilenschnittstelle für Kubernetes.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.
Befolgen Sie die Schritte in diesen Abschnitten, um die Lösung bereitzustellen:
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.
Ü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“.
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.
Ü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
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.
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!
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
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
Ü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
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.
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
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:
„external-dns“,
um alle Schreib- und Aktualisierungsvorgänge für die DNS-Verwaltung zu verwalten.external-dns
genannt), das die erforderlichen Berechtigungen definiert.$ 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:
den Domänenfilter
auf example.com
.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 .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
Verwenden Sie zu Testzwecken die standardmäßige NGINX Ingress Controller-Beispielanwendung namens Cafe .
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
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
Ü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
Ü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
Ü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
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.
A
-Eintrag zu erstellenA-
Eintrag im DNSAngesichts 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.
„kubectl
get“
und „kubectl
describe“,
um die Konfiguration bereitgestellter Objekte zu validieren.kubectl
Protokolle
<Komponente>
Befehl zum Anzeigen der Protokolldateien für die verschiedenen bereitgestellten Komponenten.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."