So vereinfachen Sie die Verwaltung des ein- und ausgehenden Datenverkehrs in Kubernetes

NGINX | 28. Juni 2021

Eine Möglichkeit, wie ein Service Mesh die Verwaltung einer Kubernetes-Umgebung tatsächlich erschweren kann, besteht darin, dass es getrennt vom Ingress-Controller konfiguriert werden muss. Separate Konfigurationen sind außerdem nicht nur zeitaufwendig. Sie erhöhen auch die Wahrscheinlichkeit von Konfigurationsfehlern, die eine ordnungsgemäße Weiterleitung des Datenverkehrs verhindern und sogar zu Sicherheitslücken (etwa wenn sich Angreifer Zugriff auf geschützte Anwendungen verschaffen) sowie zu einer schlechten Benutzererfahrung führen können (etwa wenn Kunden nicht auf Anwendungen zugreifen können, für die sie autorisiert sind). Zusätzlich zum Zeitaufwand für die separaten Konfigurationen müssen Sie letztlich noch mehr Zeit für die Fehlerbehebung aufwenden.

Sie können diese Probleme vermeiden – und Zeit sparen –, indem Sie den auf NGINX Plus basierenden NGINX Ingress Controller mit NGINX Service Mesh integrieren, um sowohl eingehenden als auch ausgehenden mTLS-Datenverkehr zu steuern. In dieser Videodemo zeigen wir Ihnen alle erforderlichen Schritte.

In den folgenden Abschnitten wird auf ergänzende Dokumentation verwiesen:

Voraussetzungen (0:18)

Bevor wir mit der eigentlichen Demo begannen, haben wir die folgenden Voraussetzungen erfüllt:

  1. Die NGINX Server Mesh-Steuerungsebene wurde im Kubernetes-Cluster installiert und mTLS sowie die strict-Richtlinie für das Service Mesh eingerichtet.
  2. Installierte den auf NGINX Plus basierenden NGINX Ingress Controller als Deployment (anstelle eines DaemonSets) im Kubernetes-Cluster, aktivierte Egress und stellte ihn als Dienst vom Typ LoadBalancer bereit.Hinweis: Die Demo funktioniert nicht mit dem auf NGINX Open Source basierenden NGINX Ingress Controller. Zur besseren Lesbarkeit bezeichnen wir den auf NGINX Plus basierenden NGINX Ingress Controller im weiteren Verlauf dieses Blogs einfach als „NGINX Ingress Controller“.
  3. Unsere Anleitung befolgt, um die Beispiel-App bookinfo herunterzuladen, den NGINX Service Mesh-Sidecar einzufügen und die App bereitzustellen.

Aufgrund der in Schritt 1 erstellten strict-Richtlinie werden Anfragen von Clients außerhalb des Mesh an die bookinfo-App vom Sidecar abgelehnt. Zur Veranschaulichung führen wir in der Demo zunächst den folgenden Befehl aus, um die Portweiterleitung einzurichten:

> kubectl port-forward svc/product-page 9080Forwarding from 127.0.0.1:9080 -> 9080
Forwarding from [::1]:9080 -> 9080
Handling connection for 9080

Wenn wir versuchen, auf die App zuzugreifen, erhalten wir den Statuscode 503 , da unser lokaler Rechner nicht Teil des Service Mesh ist:

> curl localhost:9080503

Bereitstellen des NGINX Ingress Controllers mit NGINX Service Mesh (1:50)

Der erste Schritt bei der Bereitstellung einer App für den externen Zugriff besteht darin, eine Instanz des NGINX Ingress Controllers bereitzustellen. Eine entsprechende Anleitung finden Sie in unserem Tutorial „Bereitstellung mit dem NGINX Plus Ingress Controller für Kubernetes“.

NGINX stellt zu diesem Zweck sowohl Deployment- als auch DaemonSet-Manifeste bereit. In der Demo verwenden wir das Deployment-Manifest nginx-plus-ingress.yaml. Es enthält Annotationen, um sowohl den eingehenden als auch den ausgehenden Datenverkehr über dieselbe NGINX Ingress Controller-Instanz zu leiten:

Codebeispiel wird geladen…

Das Manifest ermöglicht die direkte Integration des NGINX Ingress Controllers mit Spire, der Zertifizierungsstelle (CA) für NGINX Service Mesh. Dadurch muss der Sidecar von NGINX Service Mesh nicht mehr in den NGINX Ingress Controller injiziert werden. Stattdessen ruft der NGINX Ingress Controller Zertifikate und Schlüssel direkt von der Spire-CA ab, um sie für mTLS mit den Pods im Mesh zu verwenden. Das Manifest gibt die Adresse des Spire-Agenten an:

Codebeispiel wird geladen…

und bindet den UNIX-Socket des Spire-Agenten in den Pod des NGINX Ingress Controllers ein:

Codebeispiel wird geladen…

Als Letztes ist beim Manifest noch das -enable-internal-routes-CLI-Argument zu beachten, mit dem wir Anfragen an Egress-Dienste weiterleiten können:

Codebeispiel wird geladen…

Bevor wir mit der Demo begonnen haben, führten wir den Befehl „kubectl apply -f nginx-plus-ingress.yaml“ aus, um den NGINX Ingress Controller zu installieren, und sehen uns nun das Deployment im Namespace „nginx-ingress“ an. Wie die Spalte „READY“ in der folgenden Ausgabe zeigt, enthält der Pod des NGINX Ingress Controllers nur einen Container, da wir noch keinen NGINX Service Mesh-Sidecar injiziert haben.

Außerdem haben wir einen Dienst vom Typ LoadBalancer bereitgestellt, um die externe IP-Adresse des NGINX Ingress Controllers (hier 35.233.133.188) außerhalb des Clusters verfügbar zu machen. Über diese IP-Adresse greifen wir auf die Beispielanwendung bookinfo zu.

> kubectl get pods --namespace=nginx-ingressNAME                                 READY   STATUS    RESTARTS   AGE
pod/nginx-ingress-867f954b8f0fzdrm   1/1     Running   0          3d3h

NAME                    TYPE           CLUSTER-IP      EXTERNAL-IP      ...
service-nginx-ingress   LoadBalancer   10.31.245.207   35.233.133.188   ...

      ... PORT(S)                      AGE
      ... 80:31469/TCP,443:32481/TCP   4d2h
...

Verwenden einer standardmäßigen Kubernetes-Ingress-Ressource, um die App bereitzustellen (3:55)

Nun stellen wir die bookinfo-App im Mesh mithilfe einer standardmäßigen Kubernetes-Ingress-Ressource bereit, wie in bookinfo-ingress.yaml definiert. Eine entsprechende Anleitung finden Sie in unserem Tutorial „Eine Anwendung mit dem NGINX Plus Ingress Controller bereitstellen“.

Codebeispiel wird geladen…

Die Ressource verweist in Zeile 10 auf ein Kubernetes-Secret für die bookinfo-App und enthält eine Routingregel, die festlegt, dass Anfragen an bookinfo.example.com an den Dienst productpage weitergeleitet werden (Zeilen 11–18). Das Secret ist in bookinfo-secret.yaml definiert:

Codebeispiel wird geladen…

Wir führen diesen Befehl aus, um den Schlüssel und das Zertifikat zu laden, das in der Demo selbstsigniert ist:

> kubectl apply -f bookinfo-secret.yamlsecret/bookinfo-secret unchanged

Wir aktivieren die Ingress-Ressource:

> kubectl apply -f bookinfo-ingress.yamlingress.networking.k8s.io/bookinfo-ingress deleted

und überprüfen Sie, ob der Ingress Controller die in der Ressource definierte Route hinzugefügt hat, was durch das Ereignis am Ende der Ausgabe bestätigt wird:

> kubectl describe ingress bookinfo-ingress...
Events:
  Type    Reason          Age   From                      Message
  ----    ------          ----  ----                      -------
  Normal  AddedOrUpdated  5s    nginx-ingress-controller  Configuration for ...
        ...default/bookinfo-ingress was added or updated

In der Demo greifen wir nun mit einem Browser auf die bookinfo-App unter https://bookinfo.example.com/ zu. (Zuvor haben wir in der lokalen Datei /etc/hosts eine Zuordnung zwischen der IP-Adresse des Ingress-Controller-Dienstes – in der Demo wie oben erwähnt 35.233.133.188 – und bookinfo.example.com hinzugefügt. Eine Anleitung finden Sie in der Dokumentation.) Die Informationen im Abschnitt Buchrezensionen der Seite ändern sich regelmäßig, da die Anfragen abwechselnd an die drei Versionen des in bookinfo.yaml definierten Dienstes reviews weitergeleitet werden (herunterladen).

Als Nächstes untersuchen wir den eingehenden Datenverkehr in die Cluster. Wir führen das Skript generate-traffic.sh aus, um über die öffentliche IP-Adresse des NGINX Ingress Controllers Anfragen an den Dienst productpage zu senden. Anschließend führen wir den Befehl nginx-meshctl top aus, um den Datenverkehr zu überwachen:

> nginxmesh-ctl top deploy/productpage-v1Deployment       Direction  Resource       Success Rate  P99    P90    P50   ...
productpage-v1  
                 To         details-v1     100.00%       3ms    3ms    2ms   
                 To         reviews-v2     100.00%       99ms   90ms   20ms
                 To         reviews-v3     100.00%       99ms   85ms   18ms
                 To         reviews-v1     100.00%       20ms   17ms   9ms
                 From       nginx-ingress  100.00%       192ms  120ms  38ms

      ... NumRequests 
      ... 14
      ... 5
      ... 5
      ... 12

Verwenden einer NGINX-VirtualServer-Ressource, um die App bereitzustellen (6:45)

Als Nächstes zeigen wir eine alternative Möglichkeit, eine App mithilfe einer NGINX-VirtualServer-Ressource bereitzustellen. Dabei handelt es sich um eine benutzerdefinierte Ressource des NGINX Ingress Controllers, die eine komplexere Datenverkehrssteuerung unterstützt, etwa die Aufteilung des Datenverkehrs und inhaltsbasiertes Routing.

Zunächst löschen wir die standardmäßige Ingress-Ressource:

> kubectl delete -f bookinfo-ingress.yamlingress.networking.k8s.io "bookinfo-ingress" deleted

Unsere Datei bookinfo-vs.yaml konfiguriert mTLS mit demselben Secret wie in bookinfo-ingress.yaml (Zeilen 7–8). In den Zeilen 9–12 wird der Dienst productpage als Upstream definiert und in den Zeilen 13–24 eine Route, die alle GET-Anfragen an bookinfo.example.com an diesen Upstream weiterleitet. Für andere HTTP-Methoden als GET wird der Statuscode 405 zurückgegeben.

Codebeispiel wird geladen…

Wir wenden die Ressource an:

> kubectl apply -f bookinfo-vs.yamlvirtualserver.kubernetes.nginx.org/bookinfo-vs created

Anschließend führen wir dieselben Schritte wie bei der Ingress-Ressource aus: Wir führen den Befehl „kubectl describe“ aus, um die korrekte Bereitstellung zu bestätigen, und rufen die App in einem Browser auf. Ein weiterer Beleg dafür, dass die App ordnungsgemäß funktioniert, ist, dass sie die Methode „POST“ ablehnt:

> curl -k -X POST https://bookinfo.example.com/Method not allowed

Konfigurieren einer sicheren Egress-Route mit dem NGINX Ingress Controller (8:44)

Nun zeigen wir, wie sich ausgehender Datenverkehr über den NGINX Ingress Controller leiten lässt. Unser Tutorial „Konfigurieren einer sicheren Egress-Route mit dem NGINX Plus Ingress Controller“ erläutert den Vorgang anhand verschiedener Beispielanwendungen.

Wir haben bereits einen einfachen bash-Pod in bash.yaml definiert und ihn im Standard-Namespace bereitgestellt, von dem aus wir Anfragen senden. Wie in der Spalte READY dieser Ausgabe zu sehen ist, wurde der NGINX-Service-Mesh-Sidecar in den Pod injiziert.

> kubectl get allNAME                        READY  STATUS    RESTARTS   AGE
pod/bash-6ccb678958-zsgm7   2/2    Running   0          77s

NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.31.240.1   <none>        443/TCP   4d2h
...

Es gibt verschiedene Anwendungsfälle, in denen Sie Anfragen aus dem Pod an einen Egress-Dienst zulassen möchten. Dabei handelt es sich um eine beliebige Entität, die nicht Teil von NGINX Service Mesh ist. Beispiele hierfür sind Dienste, die an folgenden Orten bereitgestellt werden:

  • Außerhalb des Clusters
  • In einem anderen Cluster
  • Im selben Cluster, jedoch ohne injizierten NGINX Service Mesh-Sidecar

In der Demo betrachten wir den letzten Anwendungsfall. Wir haben eine Anwendung im Namespace legacy bereitgestellt, der nicht von NGINX Service Mesh verwaltet wird und in dem die automatische Einbindung des NGINX Service Mesh-Sidecars deaktiviert ist. Für die Anwendung wird nur ein Pod ausgeführt.

> kubectl get all --namespaces=legacyNAME                          READY  STATUS    RESTARTS   AGE
pod/target-5f7bcb96c6-km9lz   1/1    Running   0          27m

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/target-svc   ClusterIP   10.31.245.213   <none>        80/TCP,443/TCP   27m
...

Denken Sie daran, dass wir eine strict-mTLS-Richtlinie für NGINX Service Mesh konfiguriert haben. Daher können wir keine Anfragen direkt vom bash-Pod an den Zieldienst senden, da sich die beiden nicht gegenseitig authentifizieren können. Bei einem entsprechenden Versuch erhalten wir den Statuscode 503, wie hier dargestellt:

> kubectl exec -it bash-6ccb678958-zsgm7 -c bash -- curl target-svc.legacycurl: (56) Recv failure: connection reset by peer
503command terminated with exit code 56

Die Lösung besteht darin, dem bash-Pod zu ermöglichen, ausgehenden Datenverkehr über den NGINX Ingress Controller zu senden. Dazu entfernen wir in den Zeilen 14–15 von bash.yaml die Auskommentierung der Annotation:

Codebeispiel wird geladen…

Anschließend wenden wir die neue Konfiguration an:

> kubectl apply -f bash.yamldeployment.apps/bash configured

und überprüfen Sie, ob ein neuer „bash“-Pod gestartet wurde:

> kubectl get podsNAME                    READY  STATUS        RESTARTS   AGE
bash-678c8b4579-7sfml   2/2    Running       0          6s
bash-6ccb678958-zsgm7   2/2    Terminating   0          3m28s

Wenn wir nun wie zuvor denselben kubectl exec-Befehl ausführen, um eine Anfrage vom bash-Pod an den Zieldienst zu senden, erhalten wir den Statuscode 404 anstelle von 503. Dies zeigt, dass der bash-Pod die Anfrage erfolgreich an den NGINX Ingress Controller gesendet hat, dieser jedoch nicht weiß, wohin er sie weiterleiten soll, da keine Route definiert ist.

Wir erstellen die erforderliche Route mit der folgenden Ingress-Ressourcendefinition in legacy-route.yaml. Die Annotation „internal-route“ in Zeile 7 bedeutet, dass der Zieldienst nicht über das Internet erreichbar ist, sondern nur für Workloads innerhalb von NGINX Service Mesh.

Codebeispiel wird geladen…

Wir aktivieren die neue Ressource und bestätigen, dass der NGINX Ingress Controller die in der Ressource definierte Route hinzugefügt hat:

> kubectl apply -f legacy-route.yamlingress.networking.k8s.io/target-internal-route created
> kubectl describe ingress target-internal-route -n legacy
...
Events:
  Type    Reason          Age   From                      Message
  ----    ------          ----  ----                      -------
  Normal  AddedOrUpdated  6s    nginx-ingress-controller  Configuration for ...
        ...legacy/target-internal-route was added or updated

Wenn wir nun den Befehl „kubectl exec“ ausführen, erreichen wir den Zieldienst:

{"req": {"method": "GET"                "url": "/",
                "host": "target-svc.legacy",
                "remoteAddr": "10.28.2.76:56086"}}

Ein Vorteil der Weiterleitung des ausgehenden Datenverkehrs über den NGINX Ingress Controller besteht darin, dass Sie genau steuern können, welche externen Dienste aus dem Cluster heraus erreichbar sind – nämlich nur diejenigen, für die Sie eine Route definieren.

Zum Abschluss zeigen wir in der Demo, wie sich ausgehender Datenverkehr überwachen lässt. Wir führen den Befehl kubectl exec aus, um mehrere Anfragen zu senden, und führen anschließend diesen Befehl aus:

> nginxmesh-ctl top deploy/nginx-ingress -n nginx-ingressDeployment      Direction  Resource  Success Rate  P99  P90  P50  NumRequests
nginx-ingress  
                To         target    100.00%       1ms  1ms  1ms  9
                From       bash      100.00%       0ms  0ms  0ms  9

Sagen Sie „Nein“ zu Latenz – testen Sie NGINX Service Mesh mit dem NGINX Ingress Controller

Viele Service Meshes bieten Optionen für Ingress- und Egress-Gateways. Die NGINX-Integration bietet jedoch einen zusätzlichen Vorteil, den Sie sicher zu schätzen wissen: geringere Latenz. Bei den meisten Meshes muss ein Sidecar in den Ingress Controller injiziert werden, sodass der Datenverkehr auf dem Weg zu Ihren Anwendungen einen zusätzlichen Umweg nehmen muss. Jede Sekunde zählt, und dieser zusätzliche Umweg kann Ihre digitalen Erlebnisse verlangsamen und Kunden dazu veranlassen, sich anderweitig umzusehen. NGINX Service Mesh verursacht keine unnötige Latenz, da kein Sidecar in NGINX Ingress Controller injiziert wird. Stattdessen wird NGINX Ingress Controller durch die direkte Integration mit Spire, der Zertifizierungsstelle des Meshes, Teil von NGINX Service Mesh. NGINX Ingress Controller ruft einfach Zertifikate und Schlüssel vom Spire-Agenten ab und verwendet sie, um am Austausch von mTLS-Zertifikaten mit den in das Mesh eingebundenen Pods teilzunehmen.

NGINX Ingress Controller für Kubernetes ist in zwei Versionen erhältlich: NGINX Open Source und NGINX Plus. Um NGINX Ingress Controller wie in diesem Blog beschrieben mit NGINX Service Mesh bereitzustellen, müssen Sie die NGINX Plus-Version verwenden. Diese ist im Rahmen einer kostenlosen 30-tägigen Testversion verfügbar.

NGINX Service Mesh ist völlig kostenlos und steht zum sofortigen Download bereit. Die Bereitstellung dauert weniger als 10 Minuten! Lesen Sie zunächst die Dokumentation und teilen Sie uns über GitHub mit, wie es läuft.


Teilen
Schlagwörter: 2021, F5 NGINX, Tech

Ähnliche Blogbeiträge

Die Zukunft von NGINX: Zurück zu unseren Open-Source-Wurzeln
NGINX | 23.08.2022

Die Zukunft von NGINX: Zurück zu unseren Open-Source-Wurzeln

Beim NGINX Sprint 2022 besinnen wir uns auf unsere Open-Source-Wurzeln. Erfahren Sie mehr über die Initiativen, die wir im kommenden Jahr verfolgen, und teilen Sie uns mit, was Sie sich wünschen.

Ein Leitfaden zur Auswahl eines Ingress-Controllers, Teil 1: Ermitteln Sie Ihre Anforderungen
NGINX | 08.09.2021

Ein Leitfaden zur Auswahl eines Ingress-Controllers, Teil 1: Ermitteln Sie Ihre Anforderungen

Ein Ingress-Controller kann eines der leistungsstärksten Tools in Ihrem Kubernetes-Stack sein. Erfahren Sie, wie Sie Ihre Ingress-Anforderungen ermitteln, um die beste Option auszuwählen.

Bereitstellung des NGINX Ingress Controllers auf Amazon EKS: So haben wir getestet
NGINX | 16.08.2021

Bereitstellung des NGINX Ingress Controllers auf Amazon EKS: So haben wir getestet

Wir haben kürzlich den Lösungsleitfaden zum NGINX Ingress Controller um Empfehlungen zur Dimensionierung für Amazon Elastic Kubernetes Service (EKS) ergänzt. In diesem Blogbeitrag erläutern wir, wie wir diese Empfehlungen erarbeitet haben, und stellen Ihnen alle Informationen zur Verfügung, die Sie benötigen, um selbst ähnliche Tests durchzuführen.

Protokollierung des Datenverkehrs zwischen NGINX und Upstream-Servern bei CDN77
NGINX | 12.12.2018

Protokollierung des Datenverkehrs zwischen NGINX und Upstream-Servern bei CDN77

Bei der Fehlersuche bei Datenverkehrsproblemen zwischen NGINX und Upstream-Servern konnte CDN77 die benötigten Daten nur aus dem Fehlerprotokoll mit aktivierter Debug-Ausgabe beziehen, was die Leistung beeinträchtigt und riesige Dateien erzeugt. Daher entwickelte das Team ein neues benutzerdefiniertes Modul, das ausschließlich die benötigten Daten protokolliert.

Ankündigung von NGINX Plus R16
NGINX | 05.09.2018

Ankündigung von NGINX Plus R16

NGINX Plus R16 ist eine einheitliche, elastische Ingress- und Egress-Schicht für Anwendungen, die die Funktionen eines Load Balancers, API-Gateways und einer WAF vereint und neue Features wie clusterfähige Ratenbegrenzung, Schlüssel-Wert-Speicher, „Random with Two Choices“, verbessertes UDP-Load-Balancing und vieles mehr bietet.

5 Gründe für den Umstieg auf softwarebasiertes Load Balancing
NGINX | 13.10.2016

5 Gründe für den Umstieg auf softwarebasiertes Load Balancing

Entdecken Sie fünf Gründe für den Wechsel zu einem softwarebasierten Load Balancer wie NGINX Plus, darunter Kosteneinsparungen, die Einführung von DevOps und eine einheitliche Lösung für alle Umgebungen.