NGINX als API-Gateway bereitstellen, Teil 3: gRPC-Dienste veröffentlichen

NGINX | 20. Januar 2021

Dies ist der dritte Blogbeitrag in unserer Reihe über den Einsatz von NGINX Open Source und NGINX Plus als API-Gateway.

  • Teil 1 enthält detaillierte Anleitungen für verschiedene Anwendungsfälle von NGINX Open Source und NGINX Plus als API-Gateway für RESTful, HTTP-basierte APIs.
  • Teil 2 erweitert diese Anwendungsfälle und befasst sich mit einer Reihe von Schutzmaßnahmen, die zum Schutz und zur Absicherung von Backend-API-Diensten in Produktionsumgebungen eingesetzt werden können.
  • In diesem Beitrag wird erläutert, wie Sie NGINX Open Source und NGINX Plus als API-Gateway für gRPC-Dienste bereitstellen. Der ursprünglich 2018 veröffentlichte Beitrag wurde aktualisiert, um die in NGINX Plus Release 23 eingeführte Unterstützung für das native gRPC-Protokoll für Zustandsprüfungen zu nutzen. Siehe „Implementieren von Zustandsprüfungen“.

Hinweis: Sofern nicht anders angegeben, gelten alle Informationen in diesem Beitrag sowohl für NGINX Plus als auch für NGINX Open Source. Zur besseren Lesbarkeit wird im weiteren Verlauf des Blogbeitrags einfach von „NGINX“ gesprochen, wenn sich die Ausführungen auf beide Versionen beziehen.

Die Konzepte und Vorteile von Microservices-Anwendungsarchitekturen wurden in den letzten Jahren ausführlich dokumentiert – und nirgendwo umfassender als im NGINX-Blog. Das Herzstück von Microservices-Anwendungen ist die HTTP-API. In den ersten beiden Blogbeiträgen dieser Reihe wird anhand einer hypothetischen REST-API veranschaulicht, wie NGINX diesen Anwendungsstil unterstützt.

Trotz der Beliebtheit von REST-APIs mit JSON-Nachrichtenformaten für moderne Anwendungen ist dieser Ansatz nicht für jedes Szenario und jede Organisation ideal. Zu den häufigsten Herausforderungen gehören:

  • Dokumentationsstandards – Ohne ausreichende Disziplin seitens der Entwickler oder verbindliche Dokumentationsanforderungen kann es allzu leicht dazu kommen, dass zahlreiche REST-APIs keine präzise Definition aufweisen. Die Open API Specification hat sich als allgemeine Schnittstellenbeschreibungssprache für REST-APIs etabliert, ihre Verwendung ist jedoch optional und erfordert eine konsequente Governance innerhalb der Entwicklungsorganisation.
  • Ereignisse und langlebige Verbindungen – REST-APIs und die Verwendung von HTTP als Transportprotokoll geben für alle API-Aufrufe weitgehend ein Anfrage-Antwort-Muster vor. Wenn die Anwendung servergenerierte Ereignisse benötigt, können Lösungen wie HTTP Long Polling und WebSocket hilfreich sein. Der Einsatz solcher Lösungen erfordert jedoch letztlich die Entwicklung einer separaten, ergänzenden API.
  • Komplexe Transaktionen – REST-APIs basieren auf dem Konzept eindeutiger Ressourcen, die jeweils durch einen URI repräsentiert werden. Wenn ein Anwendungsereignis die Aktualisierung mehrerer Ressourcen erfordert, sind entweder mehrere API-Aufrufe notwendig, was ineffizient ist, oder es muss eine komplexe Transaktion im Backend implementiert werden, was dem Grundprinzip von REST widerspricht.

In den letzten Jahren hat sich gRPC als alternativer Ansatz für die Entwicklung verteilter Anwendungen und insbesondere von Microservices-Anwendungen etabliert. Ursprünglich bei Google entwickelt, wurde gRPC 2015 als Open Source veröffentlicht und ist heute ein Projekt der Cloud Native Computing Foundation. Besonders hervorzuheben ist, dass gRPC HTTP/2 als Transportmechanismus nutzt und dabei von dessen binärem Datenformat und den Möglichkeiten des Multiplex-Streamings profitiert.

Die wichtigsten Vorteile von gRPC sind:

  • Eng verzahnte Schnittstellenbeschreibungssprache (Protocol Buffers)
  • Native Unterstützung für Streaming-Daten (in beide Richtungen)
  • Effizientes binäres Datenformat
  • Automatisierte Codegenerierung für zahlreiche Programmiersprachen, die eine echte polyglotte Entwicklungsumgebung ermöglicht, ohne Interoperabilitätsprobleme zu verursachen

Das gRPC-Gateway definieren

In den ersten beiden Beiträgen dieser Reihe wurde beschrieben, wie mehrere APIs über einen einzigen Einstiegspunkt bereitgestellt werden können (zum Beispiel https://api.example.com). Aufgrund des Standardverhaltens und der Eigenschaften des gRPC-Datenverkehrs verfolgen wir denselben Ansatz, wenn NGINX als gRPC-Gateway eingesetzt wird. Zwar ist es möglich, HTTP- und gRPC-Datenverkehr über denselben Hostnamen und Port abzuwickeln, doch gibt es mehrere Gründe, die für eine Trennung sprechen:

  • API-Clients für REST- und gRPC-Anwendungen erwarten Fehlerantworten in unterschiedlichen Formaten
  • Die relevanten Felder für Zugriffsprotokolle unterscheiden sich bei REST und gRPC
  • Da gRPC nie mit veralteten Webbrowsern umgehen muss, kann dafür eine strengere TLS-Richtlinie gelten.

Um diese Trennung zu erreichen, legen wir die Konfiguration für unser gRPC-Gateway in einem eigenen server{}-Block in der gRPC-Hauptkonfigurationsdatei grpc_gateway.conf ab, die sich im Verzeichnis /etc/nginx/conf.d befindet.

Codebeispiel wird geladen…

Zunächst definieren wir das Format der Einträge im Zugriffsprotokoll für gRPC-Datenverkehr (Zeilen 1–4). In diesem Beispiel verwenden wir ein JSON-Format, um die wichtigsten Daten jeder Anfrage zu erfassen. Beachten Sie beispielsweise, dass die HTTP-Methode nicht enthalten ist, da alle gRPC-Anfragen POST verwenden. Außerdem protokollieren wir neben dem HTTP-Statuscode auch den gRPC-Statuscode. Der gRPC-Statuscode kann jedoch auf unterschiedliche Weise erzeugt werden. Unter normalen Bedingungen wird grpc-status vom Backend als HTTP/2-Trailer zurückgegeben. Bei bestimmten Fehlerbedingungen kann er jedoch als HTTP/2-Header zurückgegeben werden, entweder vom Backend oder von NGINX selbst. Um das Zugriffsprotokoll zu vereinfachen, verwenden wir einen map-Block (Zeilen 6–9), um eine neue Variable $grpc_status auszuwerten und den gRPC-Status unabhängig von seiner Herkunft zu ermitteln.

Diese Konfiguration enthält zwei listen-Direktiven (Zeilen 12 und 13), sodass wir sowohl unverschlüsselten Datenverkehr (Port 50051) als auch TLS-geschützten Datenverkehr (Port 443) testen können. Der Parameter http2 konfiguriert NGINX so, dass HTTP/2-Verbindungen akzeptiert werden. Beachten Sie, dass dies unabhängig vom Parameter ssl ist. Beachten Sie außerdem, dass Port 50051 zwar der übliche Port für unverschlüsseltes gRPC ist, sich jedoch nicht für den Einsatz in Produktionsumgebungen eignet.

Die TLS-Konfiguration ist mit Ausnahme der ssl_protocols-Direktive (Zeile 23), die TLS 1.2 als schwächstes zulässiges Protokoll festlegt, konventionell. Die HTTP/2-Spezifikation schreibt die Verwendung von TLS 1.2 (oder höher) vor. Dadurch ist gewährleistet, dass alle Clients die TLS-Erweiterung Server Name Indication (SNI) unterstützen. Somit kann das gRPC-Gateway Port 443 gemeinsam mit virtuellen Servern verwenden, die in anderen server{}-Blöcken definiert sind.

Ausführen von gRPC-Beispieldiensten

Um die gRPC-Funktionen von NGINX zu erkunden, verwenden wir eine einfache Testumgebung, die die wichtigsten Komponenten eines gRPC-Gateways mit mehreren bereitgestellten gRPC-Diensten abbildet. Wir verwenden zwei Beispielanwendungen aus den offiziellen gRPC-Leitfäden: helloworld (in Go geschrieben) und RouteGuide (in Python geschrieben). Die Anwendung RouteGuide ist besonders nützlich, da sie alle vier gRPC-Dienstmethoden umfasst:

  • Einfacher RPC (einzelne Anfrage und Antwort)
  • RPC mit Antwort-Streaming
  • RPC mit Anforderungsstreaming
  • RPC mit bidirektionalem Streaming

Beide gRPC-Dienste sind als Docker-Container auf unserem NGINX-Host installiert. Eine vollständige Anleitung zum Einrichten der Testumgebung finden Sie im Anhang.

Testumgebung für NGINX als gRPC-Gateway

Wir konfigurieren NGINX so, dass es die Dienste RouteGuide und helloworld sowie die Adressen der verfügbaren Container kennt.

Codebeispiel wird geladen…

Wir fügen für jeden der gRPC-Dienste einen upstream-Block hinzu (Zeilen 40–45 und 47–51) und tragen darin die Adressen der einzelnen Container ein, in denen der gRPC-Servercode ausgeführt wird.

gRPC-Anfragen weiterleiten

Da NGINX den konventionellen Klartext-Port für gRPC (50051) überwacht, fügen wir der Konfiguration Routing-Informationen hinzu, damit Clientanfragen den richtigen Backend-Dienst erreichen. Zunächst müssen wir jedoch verstehen, wie gRPC-Methodenaufrufe als HTTP/2-Anfragen dargestellt werden. Das folgende Diagramm zeigt eine gekürzte Version der Datei „route_guide.proto“ für den RouteGuide-Dienst und veranschaulicht, wie Paket, Dienst und RPC-Methode den URI bilden, den NGINX sieht.

Wie RPC-Methoden von Protocol Buffers in HTTP/2-Anfragen übersetzt werden

Die in der HTTP/2-Anfrage enthaltenen Informationen können daher für das Routing verwendet werden, indem einfach der Paketname abgeglichen wird (hier routeguide oder helloworld).

Codebeispiel wird geladen…

Der erste location-Block (Zeile 26) ohne Modifikatoren definiert einen Präfixabgleich, sodass /routeguide. mit allen Diensten und RPC-Methoden übereinstimmt, die in der entsprechenden .proto-Datei für dieses Paket definiert sind. Die Direktive grpc_pass (Zeile 27) leitet daher alle Anfragen des RouteGuide-Clients an die Upstream-Gruppe routeguide_service weiter. Diese Konfiguration (sowie die entsprechende Konfiguration für den helloworld-Dienst in den Zeilen 29 und 30) ermöglicht eine einfache Zuordnung zwischen einem gRPC-Paket und seinen Backend-Diensten.

Beachten Sie, dass das Argument der grpc_pass-Direktiven mit dem Schema grpc:// beginnt, das Anfragen über eine unverschlüsselte gRPC-Verbindung weiterleitet. Wenn das Backend für TLS konfiguriert ist, können wir das Schema grpcs:// verwenden, um die gRPC-Verbindung durch eine Ende-zu-Ende-Verschlüsselung abzusichern.

Nachdem wir den RouteGuide-Client ausgeführt haben, können wir das Routing-Verhalten anhand der Einträge in der Protokolldatei überprüfen. Hier sehen wir, dass die RPC-Methode RouteChat an den auf Port 10002 ausgeführten Container weitergeleitet wurde.

$ python route_guide_client.py...
$ tail -1 /var/log/nginx/grpc_log.json | jq
{
  "timestamp": "2021-01-20T12:17:56+01:00",
  "client": "127.0.0.1",
  "uri": "/routeguide.RouteGuide/RouteChat",
  "http-status": 200,
  "grpc-status": 0,
  "upstream": "127.0.0.1:10002",
  "rx-bytes": 161,
  "tx-bytes": 212
}

Präzises Routing

Wie oben gezeigt, ist das Routing mehrerer gRPC-Dienste an unterschiedliche Backends einfach und effizient und erfordert nur wenige Konfigurationszeilen. In einer Produktionsumgebung können die Routing-Anforderungen jedoch komplexer sein und ein Routing anhand anderer Elemente im URI erfordern (des gRPC-Dienstes oder sogar einzelner RPC-Methoden).

Der folgende Konfigurationsausschnitt erweitert das vorherige Beispiel, sodass die bidirektionale Streaming-RPC-Methode RouteChat an ein Backend und alle anderen RouteGuide-Methoden an ein anderes Backend weitergeleitet werden.

Codebeispiel wird geladen…

Die zweite location-Direktive (Zeile 7) verwendet den Modifikator = (Gleichheitszeichen), um anzugeben, dass die URI der RPC-Methode RouteChat exakt übereinstimmen muss. Exakte Übereinstimmungen werden vor Präfixübereinstimmungen verarbeitet. Das bedeutet, dass für die location-URI von RouteChat keine anderen Blöcke berücksichtigt werden.

Auf Fehler reagieren

gRPC-Fehler unterscheiden sich in gewisser Weise von Fehlern bei herkömmlichem HTTP-Datenverkehr. Clients erwarten, dass Fehlerzustände als gRPC-Antworten ausgegeben werden. Daher eignen sich die standardmäßigen NGINX-Fehlerseiten (im HTML-Format) nicht, wenn NGINX als gRPC-Gateway konfiguriert ist. Dieses Problem lösen wir, indem wir eine Reihe benutzerdefinierter Fehlerantworten für gRPC-Clients festlegen.

Codebeispiel wird geladen…

Der vollständige Satz von gRPC-Fehlerantworten ist eine relativ umfangreiche und weitgehend statische Konfiguration. Daher speichern wir diese in einer separaten Datei namens errors.grpc_conf und verweisen mit der Direktive include (Zeile 34) darauf. Anders als bei HTTP-/REST-Clients wird von gRPC-Clientanwendungen nicht erwartet, dass sie eine Vielzahl von HTTP-Statuscodes verarbeiten. In der gRPC-Dokumentation ist festgelegt, wie ein zwischengeschalteter Proxy wie NGINX HTTP-Fehlercodes in gRPC-Statuscodes umwandeln muss, damit Clients stets eine geeignete Antwort erhalten. Für diese Zuordnung verwenden wir die Direktive error_page.

Codebeispiel wird geladen…

Jeder der standardmäßigen HTTP-Statuscodes wird mithilfe des Präfixes „@“ an eine benannte Location weitergeleitet, damit eine gRPC-konforme Antwort generiert werden kann. Beispielsweise wird die HTTP-Antwort 404 intern an die Location „@grpc_unimplemented“ umgeleitet, die weiter unten in der Datei definiert ist:

Codebeispiel wird geladen…

Der benannte Speicherort @grpc_unimplemented steht nur für die interne Verarbeitung durch NGINX zur Verfügung – Clients können ihn nicht direkt anfordern, da kein routingfähiger URI vorhanden ist. Innerhalb dieses Speicherorts erstellen wir eine gRPC-Antwort, indem wir die obligatorischen gRPC-Header setzen und sie ohne Antworttext mit dem HTTP-Statuscode 204 (Kein Inhalt) senden.

Mit dem Befehl curl(1) können wir einen fehlerhaft arbeitenden gRPC-Client simulieren, der eine nicht vorhandene gRPC-Methode anfordert. Beachten Sie jedoch, dass sich curl im Allgemeinen nicht als gRPC-Testclient eignet, da Protokollpuffer ein binäres Datenformat verwenden. Für gRPC-Tests über die Befehlszeile empfiehlt sich grpc_cli.

$ curl -i --http2 -H "Content-Type: application/grpc" -H "TE: trailers" -X POST https://grpc.example.com/does.Not/ExistHTTP/2 204 
server: nginx/1.19.5
date: Wed, 20 Jan 2021 15:03:41 GMT
grpc-status: 12
grpc-message: unimplemented

Die oben erwähnte Datei „grpc_errors.conf“ enthält außerdem Zuordnungen von HTTP- zu gRPC-Statuscodes für andere Fehlerantworten, die NGINX möglicherweise generiert, beispielsweise bei Zeitüberschreitungen und Clientzertifikatfehlern.

Authentifizierung von Clients mit gRPC-Metadaten

gRPC-Metadaten ermöglichen es Clients, zusammen mit RPC-Methodenaufrufen zusätzliche Informationen zu senden, ohne dass diese Daten Teil der Protocol-Buffers-Spezifikation (.proto-Datei) sein müssen. Metadaten sind eine einfache Liste von Schlüssel-Wert-Paaren, wobei jedes Paar als separater HTTP/2-Header übertragen wird. Daher kann NGINX problemlos auf die Metadaten zugreifen.

Von den zahlreichen Anwendungsfällen für Metadaten ist die Clientauthentifizierung bei einem gRPC-API-Gateway der häufigste. Der folgende Konfigurationsausschnitt zeigt, wie NGINX Plus gRPC-Metadaten verwenden kann, um eine JWT-Authentifizierung durchzuführen (die JWT-Authentifizierung ist ausschließlich in NGINX Plus verfügbar). In diesem Beispiel wird das JWT in den Metadaten auth-token gesendet.

Codebeispiel wird geladen…

Jeder HTTP-Anfrage-Header steht NGINX Plus als Variable namens $http_header zur Verfügung. Bindestriche (-) im Header-Namen werden im Variablennamen in Unterstriche ( _ ) umgewandelt, sodass das JWT als $http_auth_token verfügbar ist (Zeile 2).

Wenn API-Schlüssel zur Authentifizierung verwendet werden, beispielsweise bei bestehenden HTTP-/REST-APIs, können diese ebenfalls in gRPC-Metadaten übertragen und von NGINX validiert werden. Eine Konfiguration für die API-Schlüssel-Authentifizierung<.htmla> finden Sie in Teil 1 dieser Blogreihe.

Implementieren von Integritätsprüfungen

Beim Lastenausgleich des Datenverkehrs auf mehrere Backends ist es wichtig, keine Anfragen an Backends zu senden, die ausgefallen oder anderweitig nicht verfügbar sind. Mit NGINX Plus können wir aktive Integritätsprüfungen verwenden, um proaktiv separate Anfragen an Backends zu senden und sie aus der Lastenausgleichsrotation zu entfernen, wenn sie nicht wie erwartet auf die Integritätsprüfungen reagieren. So stellen wir sicher, dass Clientanfragen niemals Backends erreichen, die außer Betrieb sind.

Der folgende Konfigurationsausschnitt aktiviert aktive Integritätsprüfungen für die gRPC-Dienste RouteGuide und helloworld. Um die relevanten Konfigurationseinstellungen hervorzuheben, werden einige Direktiven ausgelassen, die in der in den vorherigen Abschnitten verwendeten Datei „grpc_gateway.conf“ enthalten sind.

Codebeispiel wird geladen…

Für jede Route geben wir nun auch die health_check-Direktive an (Zeilen 17 und 21). Wie durch das Argument type=grpc festgelegt, verwendet NGINX Plus das gRPC-Protokoll für Zustandsprüfungen, um eine Zustandsprüfung an jeden Server in der Upstream-Gruppe zu senden. Unsere einfachen gRPC-Dienste implementieren das gRPC-Protokoll für Zustandsprüfungen jedoch nicht. Daher erwarten wir, dass sie mit dem Statuscode für „nicht implementiert“ antworten (grpc_status=12). Diese Antwort reicht als Hinweis darauf aus, dass wir mit einem aktiven gRPC-Dienst kommunizieren.

Mit dieser Konfiguration können wir jeden beliebigen Backend-Container herunterfahren, ohne dass es bei gRPC-Clients zu Verzögerungen oder Zeitüberschreitungen kommt. Aktive Systemdiagnosen sind ausschließlich in NGINX Plus verfügbar. Weitere Informationen zu gRPC-Systemdiagnosen finden Sie in unserem Blog.

Anwenden von Ratenbegrenzung und anderen API-Gateway-Kontrollen

Die Beispielkonfiguration in grpc_gateway.conf eignet sich mit einigen geringfügigen Anpassungen für TLS für den Produktivbetrieb. Da gRPC-Anfragen anhand von Paket, Dienst oder RPC-Methode weitergeleitet werden können, lassen sich vorhandene NGINX-Funktionen auf gRPC-Datenverkehr genauso anwenden wie auf HTTP-/REST-APIs oder normalen Webdatenverkehr. Der jeweils relevante location-Block kann um weitere Konfigurationseinstellungen ergänzt werden, beispielsweise zur Ratenbegrenzung oder Bandbreitensteuerung.

Zusammenfassung

In diesem dritten und letzten Blogbeitrag unserer Reihe über die Bereitstellung von NGINX Open Source und NGINX Plus als API-Gateway haben wir uns auf gRPC als Cloud-native-Technologie für die Entwicklung von Microservices-Anwendungen konzentriert. Wir haben gezeigt, dass NGINX gRPC-Anwendungen ebenso effektiv bereitstellen kann wie HTTP-/REST-APIs und dass beide API-Arten über NGINX als vielseitiges API-Gateway veröffentlicht werden können.

Eine Anleitung zum Einrichten der in diesem Blogbeitrag verwendeten Testumgebung finden Sie im Anhang weiter unten. Alle Dateien können Sie außerdem aus unserem GitHub-Gist-Repository herunterladen.

Lesen Sie auch die anderen Blogbeiträge dieser Reihe:

  • Teil 1 erläutert, wie NGINX für einige grundlegende HTTP-basierte API-Gateway-Anwendungsfälle konfiguriert wird.
  • Teil 2 befasst sich mit fortgeschritteneren Anwendungsfällen zum Schutz von Backend-Diensten vor böswilligen oder sich fehlerhaft verhaltenden Clients.

Wenn Sie NGINX Plus als API-Gateway testen möchten, starten Sie noch heute Ihre kostenlose 30-Tage-Testversion oder kontaktieren Sie uns, um Ihre Anwendungsfälle zu besprechen. Verwenden Sie während Ihres Testzeitraums den vollständigen Satz an Konfigurationsdateien aus unserem GitHub-Gist-Repository.

Anhang: Einrichten der Testumgebung

Mit den folgenden Anweisungen wird die Testumgebung auf einer virtuellen Maschine installiert, sodass sie isoliert und reproduzierbar ist. Sie kann jedoch ebenso auf einem physischen „Bare-Metal“-Server installiert werden.

Um die Testumgebung zu vereinfachen, führen wir die gRPC-Dienste in Docker-Containern aus. Dadurch benötigen wir nicht mehrere Hosts für die Testumgebung, NGINX kann Proxy-Verbindungen aber dennoch wie in einer Produktionsumgebung über einen Netzwerkaufruf herstellen.

Durch den Einsatz von Docker können wir außerdem mehrere Instanzen jedes gRPC-Dienstes an unterschiedlichen Ports ausführen, ohne den Code ändern zu müssen. Jeder gRPC-Dienst lauscht innerhalb des Containers an Port 50051, der einem eindeutigen localhost-Port auf der virtuellen Maschine zugeordnet ist. Dadurch wird wiederum Port 50051 frei, sodass NGINX ihn als Listen-Port verwenden kann. Wenn die Testclients also über ihren vorkonfigurierten Port 50051 eine Verbindung herstellen, erreichen sie NGINX.

Installation von NGINX Open Source oder NGINX Plus

  1. Installieren Sie NGINX Open Source oder NGINX Plus gemäß den Anweisungen im NGINX Plus-Administratorhandbuch.
  2. Kopieren Sie die folgenden Dateien aus dem GitHub-Gist-Repository nach /etc/nginx/conf.d: Hinweis: Wenn Sie TLS nicht verwenden, kommentieren Sie die ssl_*-Direktiven in grpc_gateway.conf aus.
    • grpc_gateway.conf
    • errors.grpc_conf
  3. Starten Sie NGINX Open Source oder NGINX Plus.
$ sudo nginx

Docker installieren

Führen Sie für Debian und Ubuntu Folgendes aus:

$ sudo apt-get install docker.io

Führen Sie für CentOS, RHEL und Oracle Linux Folgendes aus:

$ sudo yum install docker

Installieren der RouteGuide-Dienstcontainer

  1. Erstellen Sie das Docker-Image für die RouteGuide-Container anhand des folgenden Dockerfiles.

    Codebeispiel wird geladen…

    Sie können das Dockerfile vor dem Build entweder in ein lokales Unterverzeichnis kopieren oder die URL des Gists für das Dockerfile als Argument für den Befehl docker build angeben:
$ sudo docker build -t routeguide https://gist.githubusercontent.com/nginx-gists/87ed942d4ee9f7e7ebb2ccf757ed90be/raw/ce090f92f3bbcb5a94bbf8ded4d597cd47b43cbe/routeguide.Dockerfile
  1. Das Herunterladen und Erstellen des Images kann einige Minuten dauern. Sobald die Meldung „Successfully built“ und eine hexadezimale Zeichenfolge (die Image-ID) angezeigt werden, ist der Build abgeschlossen.
  2. Überprüfen Sie, ob das Image erstellt wurde, indem Sie docker images ausführen.
$ sudo docker imagesREPOSITORY     TAG          IMAGE ID          CREATED         SIZE
routeguide     latest       63058a1cf8ca      1 minute ago    1.31 GB
python         latest       825141134528      9 days ago      923 MB
  1. Starten Sie die RouteGuide-Container.
$ sudo docker run --name rg1 -p 10001:50051 -d routeguide$ sudo docker run --name rg2 -p 10002:50051 -d routeguide
$ sudo docker run --name rg3 -p 10003:50051 -d routeguide
  1. Nach jeder erfolgreichen Ausführung eines Befehls wird eine lange hexadezimale Zeichenfolge angezeigt, die den laufenden Container repräsentiert.
  2. Überprüfen Sie mit dem Befehl „docker ps“, ob alle drei Container ausgeführt werden. (Zur besseren Lesbarkeit ist die Beispielausgabe auf mehrere Zeilen verteilt.)
$ sudo docker psCONTAINER ID  IMAGE       COMMAND              STATUS        ...
d0cdaaeddf0f  routeguide  "python route_g..."  Up 2 seconds  ...
c04996ca3469  routeguide  "python route_g..."  Up 9 seconds  ...
2170ddb62898  routeguide  "python route_g..."  Up 1 minute   ...

      ... PORTS                     NAMES
      ... 0.0.0.0:10003->50051/tcp  rg3
      ... 0.0.0.0:10002->50051/tcp  rg2
      ... 0.0.0.0:10001->50051/tcp  rg1
  1. Die Spalte PORTS in der Ausgabe zeigt, wie jeder Container einen anderen lokalen Port dem Port 50051 innerhalb des Containers zugeordnet hat.

Installieren der helloworld-Service-Container

  1. Erstellen Sie das Docker-Image für die helloworld-Container anhand des folgenden Dockerfiles.

    Codebeispiel wird geladen…

    Sie können das Dockerfile vor dem Build entweder in ein lokales Unterverzeichnis kopieren oder die URL des Gists für das Dockerfile als Argument für den Befehl docker build angeben:
$ sudo docker build -t helloworld https://gist.githubusercontent.com/nginx-gists/87ed942d4ee9f7e7ebb2ccf757ed90be/raw/ce090f92f3bbcb5a94bbf8ded4d597cd47b43cbe/helloworld.Dockerfile
  1. Das Herunterladen und Erstellen des Images kann einige Minuten dauern. Sobald die Meldung „Successfully built“ und eine hexadezimale Zeichenfolge (die Image-ID) angezeigt werden, ist der Build abgeschlossen.
  2. Überprüfen Sie, ob das Image erstellt wurde, indem Sie docker images ausführen.
$ sudo docker images
REPOSITORY     TAG          IMAGE ID          CREATED           SIZE
helloworld     latest       e5832dc0884a      10 seconds ago    926MB
routeguide     latest       170761fa3f03      4 minutes ago     1.31GB
python         latest       825141134528      9 days ago        923MB
golang         latest       d0e7a411e3da      3 weeks ago       794MB
  1. Starten Sie die helloworld-Container.
$ sudo docker run --name hw1 -p 20001:50051 -d helloworld$ sudo docker run --name hw2 -p 20002:50051 -d helloworld
  1. Nach der erfolgreichen Ausführung jedes Befehls wird eine lange hexadezimale Zeichenfolge angezeigt, die den laufenden Container repräsentiert.
  2. Überprüfen Sie mit docker ps, ob die beiden helloworld-Container ausgeführt werden.
$ sudo docker psCONTAINER ID  IMAGE       COMMAND              STATUS        ... 
e0d204ae860a  helloworld  "go run greeter..."  Up 5 seconds  ... 
66f21d89be78  helloworld  "go run greeter..."  Up 9 seconds  ... 
d0cdaaeddf0f  routeguide  "python route_g..."  Up 4 minutes  ... 
c04996ca3469  routeguide  "python route_g..."  Up 4 minutes  ... 
2170ddb62898  routeguide  "python route_g..."  Up 5 minutes  ... 

      ... PORTS                     NAMES
      ... 0.0.0.0:20002->50051/tcp  hw2
      ... 0.0.0.0:20001->50051/tcp  hw1
      ... 0.0.0.0:10003->50051/tcp  rg3
      ... 0.0.0.0:10002->50051/tcp  rg2
      ... 0.0.0.0:10001->50051/tcp  rg1

Installieren der gRPC-Clientanwendungen

  1. Installieren Sie die Voraussetzungen für die Programmiersprache, von denen einige möglicherweise bereits in der Testumgebung installiert sind. Beachten Sie, dass für python-pip das EPEL-Repository aktiviert sein muss (führen Sie bei Bedarf zuerst sudo yum install epel-release aus).
    • Führen Sie für Ubuntu und Debian Folgendes aus:
$ sudo apt-get install golang-go python3 python-pip git
  • Führen Sie für CentOS, RHEL und Oracle Linux Folgendes aus:
$ sudo yum install golang python python-pip git
  1. Laden Sie die helloworld-Anwendung herunter:
$ go get google.golang.org/grpc
  1. Laden Sie die RouteGuide-Anwendung herunter:
$ git clone -b v1.14.1 https://github.com/grpc/grpc
$ pip install grpcio-tools

Einrichtung testen

  1. Führen Sie den helloworld-Client aus:
$ go run go/src/google.golang.org/grpc/examples/helloworld/greeter_client/main.go
  1. Führen Sie den RouteGuide-Client aus:
$ cd grpc/examples/python/route_guide
$ python route_guide_client.py
  1. Überprüfen Sie die NGINX-Protokolle, um sicherzustellen, dass die Testumgebung betriebsbereit ist:
$ tail /var/log/nginx/grpc_log.json


Teilen
Schlagwörter: 2021, Tech, F5 NGINX

Über den Autor

Liam Crilly
Liam CrillySenior Director, Produktmanagement

Weitere Blogbeiträge von Liam Crilly

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