BLOG | NGINX

Verwenden von DNS zur Diensterkennung mit NGINX und NGINX Plus

NGINX-Teil-von-F5-horiz-schwarz-Typ-RGB
Michael Pleshakov Miniaturbild
Michael Pleshakov
Veröffentlicht am 27. April 2016

[Editor – Dieser Beitrag wurde aktualisiert, um auf die NGINX Plus API zu verweisen, die das in der Originalversion des Beitrags erwähnte separate dynamische Konfigurationsmodul ersetzt und veraltet.]

Einer der großen Vorteile einer Microservices-Architektur besteht darin, wie schnell und einfach Sie Serviceinstanzen skalieren können. Bei mehreren Serviceinstanzen benötigen Sie einen Load Balancer und eine Möglichkeit, ihn schnell über Änderungen an der Menge der verfügbaren Serviceinstanzen zu informieren. Dies wird als Serviceerkennung bezeichnet. NGINX Plus bietet zwei Optionen für die Integration mit Service-Discovery-Systemen: die NGINX Plus-API und die Neuauflösung des Domain Name System (DNS) . Dieser Blogbeitrag konzentriert sich auf Letzteres.

Wenn Sie Serviceinstanzen (in diesem Blogbeitrag nennen wir sie Backends ) skalieren, indem Sie virtuelle Maschinen (VMs) oder Container hinzufügen oder entfernen, muss die Konfiguration des Load Balancers geändert werden, um jede Änderung am Backend-Satz widerzuspiegeln. Die Skalierung kann je nach Anwendung mehrmals pro Tag, pro Stunde oder sogar pro Minute erfolgen. Angesichts der hohen Häufigkeit von Konfigurationsänderungen müssen diese automatisiert werden. Eine Möglichkeit hierzu ist die Diensterkennung über DNS.

Viele Plattformen, auf denen Sie heute Ihre Anwendungen ausführen, wie z. B. Kubernetes , unterstützen die Diensterkennung mithilfe von DNS. Am Ende dieses Blogbeitrags stellen wir Links zu Artikeln bereit, in denen die Integration von NGINX Plus in beliebte Plattformen und Service-Discovery-Tools, die DNS verwenden, erklärt wird.

Ein kurzer Überblick über die wichtigsten DNS-Funktionen

Bevor wir erklären, wie man die Diensterkennung über DNS konfiguriert, werfen wir einen kurzen Blick auf einige Funktionen des DNS-Protokolls, die besonders relevant oder praktisch sind.

Lebensdauer

Um zu verhindern, dass DNS-Clients veraltete Informationen verwenden, enthalten DNS-Einträge das Feld „Time-to-Live“ (TTL), um zu definieren, wie lange Clients den Eintrag als gültig betrachten können. Um die DNS-Standards einzuhalten, müssen Clients den DNS-Server nach einer Aktualisierung abfragen, wenn ein Datensatz seinen TTL-Wert überschritten hat. NGINX Plus respektiert die TTL standardmäßig, bietet aber auch eine genauere Kontrolle über die „Lebensdauer“ eines Datensatzes – Sie können NGINX Plus so konfigurieren, dass TTLs ignoriert und Datensätze stattdessen in einer angegebenen Häufigkeit aktualisiert werden. (Wir besprechen später im Beitrag, wie NGINX Open Source mit dem TTL umgeht.)

DNS über TCP

Standardmäßig kommunizieren DNS-Clients und -Server über UDP. Wenn ein Domänenname jedoch in eine große Anzahl von Back-End-IP-Adressen aufgelöst wird, passt die vollständige Antwort möglicherweise nicht in ein einzelnes UDP-Datagramm, das auf 512 Byte begrenzt ist. Die Verwendung von TCP statt UDP löst dieses Problem: Wenn ein vollständiger Datensatzsatz nicht in ein Datagramm passt, setzt der Server in seiner Antwort ein Trunkierungsflag, das den Client anweist, zu TCP zu wechseln, um alle Datensätze abzurufen. DNS über TCP wird in NGINX Version 1.9.11 und höher sowie NGINX Plus R9 und höher unterstützt. Weitere Einzelheiten finden Sie unter „Load Balancing DNS Traffic with NGINX and NGINX Plus“ in unserem Blog.

SRV -Aufzeichnungen

DNS löst Hostnamen in IP-Adressen auf, aber was ist mit Portnummern? In einigen Fällen – beispielsweise beim Lastenausgleich von Docker-Containern – können Sie sich nicht auf bekannte Portnummern verlassen, da diese stattdessen dynamisch zugewiesen werden. DNS verfügt über einen speziellen Datensatztyp – den Service-Datensatz ( SRV- Datensatz) – der Portnummern und einige andere Parameter enthält. In R9 und höher unterstützt NGINX Plus SRV- Einträge (und kann daher Portinformationen daraus extrahieren).

Editor – Eine Übersicht über alle neuen Funktionen in NGINX Plus R9 finden Sie unter „Ankündigung von NGINX Plus R9“ in unserem Blog.

Methoden zur Diensterkennung mit DNS für NGINX und NGINX Plus

Jetzt zeigen wir Ihnen in der Reihenfolge zunehmender Komplexität fünf Möglichkeiten, wie Sie DNS zur Diensterkennung in NGINX und NGINX Plus verwenden können. Die ersten drei sind sowohl in NGINX als auch in NGINX Plus verfügbar, die letzten beiden nur in NGINX Plus.

In dieser Übersicht über Methoden zur Diensterkennung gehen wir davon aus, dass wir einen autoritativen Nameserver für die Zone example.com mit der IP-Adresse 10.0.0.2 haben. Es gibt drei Backend-Server, die dem Domänennamen backends.example.com entsprechen, wie in der folgenden Ausgabe des Dienstprogramms nslookup gezeigt. Bei den ersten vier Methoden, die wir besprechen, fordern NGINX und NGINX Plus Standard- A -Einträge vom DNS an; bei der letzten Methode fordert NGINX Plus stattdessen SRV- Einträge an.

$ nslookup backends.example.com 10.0.0.2 Server:		10.0.0.2 Adresse:	10.0.0.2#53 Name: backends.example.com Adresse: 10.0.0.11 Name: backends.example.com Adresse: 10.0.0.10 Name: backends.example.com Adresse: 10.0.0.12

Verwenden von DNS zur Diensterkennung mit NGINX

Wir zeigen Ihnen zunächst die drei Möglichkeiten zur Verwendung von DNS mit NGINX Open Source (wie oben erwähnt, können Sie sie auch mit NGINX Plus verwenden).

Verwenden des Domänennamens in der Proxy_Pass- Direktive

Die einfachste Möglichkeit, die Gruppe der Upstream-Server (Backends) zu definieren, besteht darin, einen Domänennamen als Parameter für die Direktive „proxy_pass“ anzugeben:

Server { Standort / {
Proxy-Passwort http://backends.example.com:8080;
}
}

Wenn NGINX startet oder seine Konfiguration neu lädt, fragt es einen DNS-Server ab, um backends.example.com aufzulösen. Der DNS-Server gibt die Liste der drei oben besprochenen Backends zurück und NGINX verwendet den standardmäßigen Round-Robin-Algorithmus, um die Last der Anfragen zwischen ihnen auszugleichen. NGINX wählt den DNS-Server aus der Betriebssystemkonfigurationsdatei /etc/resolv.conf aus.

Diese Methode stellt die am wenigsten flexible Art der Diensterkennung dar und weist folgende zusätzliche Nachteile auf:

  • Wenn der Domänenname nicht aufgelöst werden kann, schlägt der Start oder das Neuladen der Konfiguration von NGINX fehl.
  • NGINX speichert die DNS-Einträge bis zum nächsten Neustart oder Neuladen der Konfiguration im Cache und ignoriert dabei die TTL-Werte der Einträge.
  • Wir können weder einen anderen Lastausgleichsalgorithmus angeben, noch können wir passive Integritätsprüfungen oder andere durch Parameter definierte Funktionen für die Serverdirektive konfigurieren, die wir im nächsten Abschnitt beschreiben.

Verwenden eines Domänennamens in einer Upstream-Servergruppe

Um die von NGINX bereitgestellten Lastausgleichsoptionen zu nutzen, können Sie die Gruppe der Upstream-Server im Upstream- Konfigurationsblock definieren. Anstatt einzelne Server jedoch anhand der IP-Adresse zu identifizieren, verwenden Sie den Domänennamen als Parameter für die Serverdirektive .

Wie bei der ersten Methode wird backends.example.com in drei Backend-Server aufgelöst, wenn NGINX seine Konfiguration startet oder neu lädt. Jetzt können wir jedoch einen ausgefeilteren Algorithmus zum Lastenausgleich, Least Connections , definieren und den Parameter max_fails verwenden, um passive Integritätsprüfungen zu aktivieren. Dabei legen wir fest, dass NGINX einen Server als ausgefallen markiert, wenn drei aufeinanderfolgende Anforderungen fehlschlagen.

Upstream-Backends { least_conn;

Server backends.example.com:8080 max_fails=3;
}

Server {
Standort / {
Proxy-Passwort http://backends;
}
}

Obwohl wir mit dieser Methode den Lastausgleichsalgorithmus auswählen und Integritätsprüfungen konfigurieren können, weist sie hinsichtlich Start, Neuladen und TTL immer noch dieselben Nachteile auf wie die vorherige Methode.

Festlegen des Domänennamens in einer Variablen

Diese Methode ist eine Variante der ersten , ermöglicht uns aber zu steuern, wie oft NGINX den Domänennamen erneut auflöst:

Resolver 10.0.0.2 gültig=10s;
Server {
Standort / {
Setze $backend_servers backends.example.com;
Proxy_Pass http://$backend_servers:8080;
}
}

Wenn Sie eine Variable verwenden, um den Domänennamen in der Proxy_pass- Direktive anzugeben, löst NGINX den Domänennamen erneut auf, wenn seine TTL abläuft. Sie müssen die Resolver- Direktive einschließen, um den Nameserver explizit anzugeben (NGINX verweist nicht auf /etc/resolv.conf wie in den ersten beiden Methoden). Indem Sie den gültigen Parameter in die Resolver- Direktive aufnehmen, können Sie NGINX anweisen, die TTL zu ignorieren und Namen stattdessen in einer angegebenen Häufigkeit erneut aufzulösen. Hier weisen wir NGINX an, Namen alle 10 Sekunden neu aufzulösen.

Notiz: Für den TCP/UDP-Lastausgleich wird diese Methode der Verwendung einer Variablen in der Proxy_pass- Direktive in NGINX 1.11.3 und höher sowie in NGINX Plus R10 und höher unterstützt.

Diese Methode behebt zwei Nachteile der ersten Methode, da der Start- oder Neuladevorgang von NGINX nicht fehlschlägt, wenn der Domänenname nicht aufgelöst werden kann, und wir steuern können, wie oft NGINX den Namen erneut auflöst. Da jedoch keine Upstream-Gruppe verwendet wird, können Sie der Serverdirektive weder den Lastausgleichsalgorithmus noch andere Parameter angeben (wie wir es bei der zweiten Methode getan haben).

Verwenden von DNS zur Diensterkennung mit NGINX Plus

Jetzt schauen wir uns die beiden Methoden zur Diensterkennung mit DNS an, die exklusiv für NGINX Plus verfügbar sind.

Verwenden von A- Records mit NGINX Plus

Mit NGINX Plus können wir DNS-Namen beliebig oft neu auflösen , und zwar ohne die oben für die ersten drei Methoden beschriebenen Nachteile. Um diese Funktion zu nutzen, müssen wir:

  • Fügen Sie die Resolver- Direktive ein, um den Nameserver anzugeben, wie in der vorherigen Methode.
  • Fügen Sie die Zonendirektive in den Upstream -Konfigurationsblock ein, um eine gemeinsam genutzte Speicherzone zuzuordnen.
  • Fügen Sie der Serverdirektive , in der wir den Domänennamen verwenden, den Resolve -Parameter hinzu.

Betrachten Sie das folgende Beispiel:

Resolver 10.0.0.2 gültig = 10 s ; Upstream-Backends { Zone Backends 64k ; Server Backends.example.com:8080 Resolve ; } Server {Standort / {Proxy-Passwort http://backends; } }

Standardmäßig beachtet NGINX Plus die TTL und löst Namen erneut auf, wenn Datensätze ablaufen. Um NGINX Plus stattdessen dazu zu bringen, Namen in einer angegebenen Häufigkeit neu aufzulösen, fügen Sie der Resolver- Direktive den gültigen Parameter hinzu.

Im Snippet fragt NGINX Plus alle 10 Sekunden den Nameserver bei 10.0.0.2 ab, um backends.example.com aufzulösen. Wenn der Name nicht aufgelöst werden kann, schlägt NGINX Plus weder beim Start, noch beim Neuladen der Konfiguration oder während der Laufzeit fehl. Stattdessen sieht der Kunde den Standard502 Fehlerseite.

Verwenden von SRV -Einträgen mit NGINX Plus

NGINX Plus R9 und höher unterstützt DNS- SRV- Einträge. Dadurch kann NGINX Plus nicht nur IP-Adressen von einem Nameserver abrufen, sondern auch Portnummern, Gewichte und Prioritäten. Dies ist in Microservices-Umgebungen von entscheidender Bedeutung, in denen die Portnummern der Dienste häufig dynamisch zugewiesen werden.

Editor – Eine Übersicht über alle neuen Funktionen in NGINX Plus R9 finden Sie unter „Ankündigung von NGINX Plus R9“ in unserem Blog.

SRV- Einträge werden durch ein Tripel aus dem Dienstnamen, dem Protokoll für die Kommunikation mit dem Dienst und dem Domänennamen definiert. Bei der Abfrage des Nameservers müssen wir alle drei angeben. Unser 10.0.0.2-Nameserver hat drei SRV- Einträge mit dem Triplett aus Dienstname http , Protokoll tcp und Domänenname backends.example.com , wie in dieser Ausgabe des Dienstprogramms nslookup gezeigt:

$ nslookup -query=SRV _http._tcp.backends.example.com 10.0.0.2 Server:		10.0.0.2 Adresse:	10.0.0.2#53 _http._tcp.backends.example.com Dienst = 0 2 8090 backend-0.example.com. _http._tcp.backends.example.com Dienst = 0 1 8091 backend-1.example.com. _http._tcp.backends.example.com Dienst = 10 1 8092 backend-2.example.com.

Wenn wir den Hostnamen in jedem SRV- Eintrag abfragen, erhalten wir seine IP-Adresse:

$ nslookup backend-0.example.com 10.0.0.2 …
Name: backend-0.example.com Adresse: 10.0.0.10 $ nslookup backend-1.example.com 10.0.0.2 …
Name: backend-1.example.com Adresse: 10.0.0.11 $ nslookup backend-2.example.com 10.0.0.2 …
Name: backend-2.example.com Adresse: 10.0.0.12

Sehen wir uns die Informationen im ersten SRV- Eintrag genauer an, die vom ersten nslookup -Befehl zurückgegeben wurden:

_http._tcp.backends.example.com Dienst = 0 2 8090 backend-0.example.com.
  • _http._tcp. – Der Name und das Protokoll des SRV- Eintrags. Wir geben dies als Wert des Serviceparameters für die Serverdirektive in der NGINX Plus-Konfigurationsdatei an (siehe unten).
  • 0 – Die Priorität. Je niedriger der Wert, desto höher die Priorität. NGINX Plus bestimmt die Server mit der höchsten Priorität als primäre Server und die restlichen Server als Backup-Server. Dieser Datensatz hat den niedrigsten Wert (die höchste Priorität) aller Datensätze, deshalb bestimmt NGINX Plus das entsprechende Back-End als primären Server.
  • 2 – Das Gewicht. NGINX Plus setzt das Gewicht des Backends auf diesen Wert, wenn es das Backend zur Upstream-Gruppe hinzufügt (entspricht dem Gewichtsparameter in der Serverdirektive ).
  • 8090 – Die Portnummer. NGINX Plus setzt den Port des Back-Ends auf diesen Wert, wenn es das Back-End zur Upstream-Gruppe hinzufügt.
  • backend‑0.example.com – Der Hostname des Backend-Servers. NGINX Plus löst diesen Namen auf und fügt das entsprechende Backend zur Upstream-Gruppe hinzu. Wenn der Name in mehrere Datensätze aufgelöst wird, fügt NGINX Plus mehrere Server hinzu.

Sehen wir uns nun an, wie wir NGINX Plus für die Verwendung von SRV -Einträgen konfigurieren. Hier ist die Beispielkonfigurationsdatei:

Resolver 10.0.0.2 gültig=10s;

Upstream-Backends {
Zone-Backends 64k;
Server-Backends.example.com Service=_http._tcp Resolve;
}

Server {
Standort / {
Proxy-Passwort http://backends;
}
}

Mithilfe des Serviceparameters der Serverdirektive geben wir den Namen und das Protokoll der SRV -Einträge an, die wir auflösen möchten. In unserem Fall sind dies _http und _tcp . Abgesehen vom Serviceparameter und der Tatsache, dass wir keinen Port angeben, sieht es genauso aus wie das Konfigurationsbeispiel aus dem vorherigen Abschnitt .

Basierend auf den vom ersten nslookup -Befehl in diesem Abschnitt zurückgegebenen Werten wird NGINX Plus mit drei Backend-Servern konfiguriert:

  • 10.0.0.10 – Primärer Server mit Port 8090 und Gewicht 2.
  • 10.0.0.11 – Primärer Server mit Port 8091 und Gewicht 1.
  • 10.0.0.12 – Backup-Server mit Port 8092 und Gewicht 1.

Wenn wir die Live-Aktivitätsüberwachung für NGINX Plus konfigurieren, können wir diese Backends auf dem integrierten Dashboard sehen:

Das Dashboard zur Live-Aktivitätsüberwachung, das zeigt, wie NGINX Plus Anfragen entsprechend der den Upstream-Servern in ihren DNS-SRV-Einträgen zugewiesenen Gewichtungen verteilt, kann zur Überwachung von NGINX in einer Microservices-Architektur mit NGINX als Lastenausgleich verwendet werden.

Beachten Sie, wie die Anfragen entsprechend der angegebenen Gewichtung verteilt werden. Der Server 10.0.0.11:8091 (mit Gewichtung 1) erhält ein Drittel der Anfragen, während der Server 10.0.0.10:8090 (mit Gewichtung 2) zwei Drittel erhält. Als Backup-Server erhält der Server 10.0.0.12:8092 keine Anfragen, es sei denn, die anderen beiden Server sind ausgefallen.

Vorbehalte

Bei der Verwendung von DNS zur Diensterkennung mit NGINX Plus müssen Sie einige Dinge beachten:

  • Der DNS-Server muss entweder hochverfügbar sein oder über einen Backup-Server verfügen. Wenn der DNS-Server nicht mehr verfügbar ist, erhält NGINX Plus keine Updates mehr. Es behält die vorhandenen Backends in der Konfiguration bei (es sei denn, Sie starten es neu oder laden die Konfiguration neu) und ignoriert die TTL-Werte der entsprechenden Datensätze.
  • Sie können mit der Resolver- Direktive mehrere Nameserver angeben, sodass NGINX Plus es bei den anderen versucht, wenn einer davon ausfällt.
  • Wie in der Einleitung erwähnt, ist die NGINX Plus-API eine Alternative zu DNS für die Diensterkennung mit NGINX Plus. Mit dieser können Sie einfache HTTP-Anfragen stellen, um Server in einer Upstream-Gruppe hinzuzufügen oder zu entfernen.

Beispiele

Wenn Sie sich ausführliche Beispiele ansehen möchten, lesen Sie diese Blogbeiträge zur Integration von NGINX und NGINX Plus mit Service-Discovery-Plattformen, die DNS verwenden:

Wir werden diese Liste aktualisieren, wenn wir in Zukunft mehr über neue Integrationsoptionen schreiben.

Abschluss

Die in NGINX Plus vollständig verfügbare Diensterkennung über DNS bietet eine einfache Möglichkeit, die Konfiguration des Load Balancers in einer Microservices-Umgebung zu aktualisieren. Die Unterstützung für SRV- Einträge in Release 9 und höher macht NGINX Plus noch leistungsfähiger, da NGINX Plus dadurch nicht nur IP-Adressen, sondern auch Portnummern von Backends abrufen kann.

Sind Sie bereit, die Diensterkennung mit DNS für NGINX Plus und seine anderen erweiterten Funktionen auszuprobieren? Starten Sie noch heute Ihre kostenlose 30-Tage-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."