Hallo, Habr! Ich präsentiere Ihnen die Übersetzung des Beitrags: .
Envoy ist ein hochleistungsfähiger, verteilter Proxy-Server (geschrieben in C++), der für einzelne Dienste und Anwendungen konzipiert wurde. Er fungiert auch als Kommunikationsbus und "universelle Datenebene", die für große Mikroservice-Architekturen "Service Mesh" entwickelt wurde. Bei der Entwicklung wurden Lösungen für Probleme berücksichtigt, die bei Servern wie NGINX, HAProxy, Hardware-Load-Balancern und Cloud-Load-Balancern auftraten. Envoy arbeitet mit jeder Anwendung zusammen und abstrahiert das Netzwerk, indem es plattformunabhängige Funktionen bereitstellt. Wenn der gesamte Dienstverkehr innerhalb der Infrastruktur über das Envoy-Netzwerk läuft, wird es einfacher, Problemstellen mithilfe konsistenter Beobachtungsmöglichkeiten zu visualisieren, die allgemeine Leistung zu optimieren und zentrale Funktionen an einem bestimmten Ort hinzuzufügen.
Funktionen
- Architektur außerhalb des Prozesses: Envoy ist ein eigenständiger, hochleistungsfähiger Server, der nur wenig Arbeitsspeicher benötigt. Er arbeitet mit jeder Programmiersprache oder jedem Framework zusammen.
- Unterstützung für HTTP/2 und gRPC: Envoy bietet erstklassige Unterstützung für HTTP/2 und gRPC für eingehende und ausgehende Verbindungen. Es handelt sich um einen transparenten Proxy von HTTP/1.1 auf HTTP/2.
- Erweiterte Lastverteilung: Envoy unterstützt erweiterte Funktionen der Lastverteilung, einschließlich automatischer Wiederholungen, Circuit Breaking, globaler Ratenbegrenzung, Anfragen-Dimming, lokaler Lastverteilung innerhalb von Zonen usw.
- API zur Konfigurationsverwaltung: Envoy stellt eine zuverlässige API für die dynamische Verwaltung seiner Konfiguration zur Verfügung.
- Überwachung: Tiefgehende Überwachung des L7-Verkehrs, integrierte Unterstützung für verteiltes Tracing und Überwachung von MongoDB, DynamoDB und vielen anderen Anwendungen.
Schritt 1 — Beispielkonfiguration für NGINX
In diesem Szenario wird eine eigens erstellte Datei verwendet nginx.conf, basierend auf einem vollständigen Beispiel aus der . Sie können die Konfiguration im Editor betrachten, indem Sie nginx.conf
die ursprüngliche NGINX-Konfiguration öffnen
user www www;
pid /var/run/nginx.pid;
worker_processes 2;
events {
worker_connections 2000;
}
http {
gzip on;
gzip_min_length 1100;
gzip_buffers 4 8k;
gzip_types text/plain;
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$gzip_ratio"';
log_format download '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$http_range" "$sent_http_content_range"';
upstream targetCluster {
172.18.0.3:80;
172.18.0.4:80;
}
server {
listen 8080;
server_name one.example.com www.one.example.com;
access_log /var/log/nginx.access_log main;
error_log /var/log/nginx.error_log info;
location / {
proxy_pass http://targetCluster/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}Die NGINX-Konfiguration besteht typischerweise aus drei wesentlichen Elementen:
- Der Konfiguration des NGINX-Servers, der Protokollstrukturen und der Gzip-Funktionalität. Diese wird global in allen Fällen definiert.
- Die NGINX-Konfiguration, um Anfragen für den Host one.example.com auf Port 8080 anzunehmen.
- Die Konfiguration des Zielorts, wie der Verkehr für verschiedene Teile der URL verarbeitet werden soll.
Nicht alle Konfigurationen werden auf den Envoy Proxy angewendet, und Sie müssen einige Parameter nicht festlegen. Der Envoy Proxy hat vier Schlüsseltypen, die die grundlegende Infrastruktur unterstützen, die von NGINX angeboten wird. Der Kern ist:
- Listener: Sie legen fest, wie der Envoy Proxy eingehende Anfragen empfängt. Derzeit unterstützt der Envoy Proxy nur TCP-basierte Listener. Sobald die Verbindung hergestellt ist, wird sie an eine Reihe von Filtern zur Verarbeitung weitergeleitet.
- Filter: Diese sind Teil einer Pipeline-Architektur, die eingehende und ausgehende Daten verarbeiten kann. Zu dieser Funktionalität gehören Filter wie Gzip, das die Daten vor dem Senden an den Client komprimiert.
- Router: Sie leiten den Datenverkehr zum gewünschten Ziel weiter, das als Cluster definiert ist.
- Cluster: Sie definieren den Endpunkt für den Datenverkehr und die Konfigurationsparameter.
Wir werden diese vier Komponenten nutzen, um die Envoy Proxy-Konfiguration zu erstellen, die eine bestimmte NGINX-Konfiguration widerspiegelt. Das Ziel von Envoy ist die Arbeit mit APIs und dynamische Konfiguration. In diesem Fall wird die grundlegende Konfiguration statische, festgelegte Parameter aus NGINX verwenden.
Schritt 2 — NGINX-Konfiguration
Erster Teil nginx.conf definiert einige interne Komponenten von NGINX, die konfiguriert werden müssen.
Arbeiterverbindungen
Die folgende Konfiguration definiert die Anzahl der Arbeitsprozesse und Verbindungen. Sie zeigt an, wie NGINX skaliert wird, um der Nachfrage gerecht zu werden.
worker_processes 2;
events {
worker_connections 2000;
}Envoy Proxy verwaltet Arbeitsprozesse und Verbindungen auf unterschiedliche Weise.
Envoy erstellt einen Arbeitsprozess für jeden Hardware-Thread im System. Jeder Arbeitsprozess führt eine nicht blockierende Ereignisschleife aus, die verantwortlich ist für
- Das Lauschen auf jeden Listener
- Die Annahme neuer Verbindungen
- Die Erstellung eines Satzes von Filtern für die Verbindung
- Die Verarbeitung aller Ein- und Ausgabeoperationen während der Lebensdauer der Verbindung.
Alle weiteren Verarbeitungen der Verbindung werden vollständig im Arbeitsprozess bearbeitet, einschließlich jeglichem Umleitungsverhalten.
Für jeden Arbeitsstrom in Envoy gibt es eine Verbindung im Pool. Somit stellen HTTP/2-Verbindungspools nur eine Verbindung für jeden externen Host gleichzeitig her. Bei vier Arbeitsströmen gibt es jeweils vier HTTP/2-Verbindungen für jeden externen Host im stabilen Zustand. Indem alles in einem Arbeitsstrom gehalten wird, kann fast der gesamte Code ohne Blockierung geschrieben werden, als wäre er ein-threaded. Wenn mehr Arbeitsströme zugewiesen werden, als notwendig sind, kann dies zu einem ineffizienten Speicherverbrauch führen, eine große Anzahl von inaktiven Verbindungen erzeugen und die Rückführung von Verbindungen in den Pool verringern.
Für weitere Informationen besuchen Sie .
HTTP-Konfiguration
Der folgende NGINX-Konfigurationsblock definiert die HTTP-Einstellungen, wie zum Beispiel:
- Welche MIME-Typen unterstützt werden
- Standard-Timeouts
- Gzip-Konfiguration
Diese Aspekte können Sie mit Filtern im Envoy-Proxy anpassen, was wir später besprechen werden.
Schritt 3 – Server-Konfiguration
Im HTTP-Konfigurationsblock gibt die NGINX-Konfiguration an, den Port 8080 zu überwachen und auf eingehende Anfragen für die Domains zu antworten: one.example.com und www.one.example.com.
server {
listen 8080;
server_name one.example.com www.one.example.com;Im Inneren von Envoy werden sie von Listenern verwaltet.
Listener von Envoy
Der wichtigste Aspekt beim Einstieg in den Envoy Proxy ist die Definition der Listener. Sie müssen eine Konfigurationsdatei erstellen, die beschreibt, wie Sie eine Instanz von Envoy starten möchten.
Der folgende Ausschnitt erstellt einen neuen Listener und bindet ihn an den Port 8080. Die Konfiguration gibt dem Envoy Proxy an, an welchen Ports er für eingehende Anfragen gebunden werden soll.
Der Envoy Proxy verwendet YAML-Notation für seine Konfiguration. Um sich mit dieser Notation vertraut zu machen, schauen Sie hier. .
Copy to Editorstatic_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 8080 }Es ist nicht notwendig, server_name, da die Filter von Envoy Proxy dies übernehmen werden.
Schritt 4 – Konfiguration des Standorts
Wenn eine Anfrage an NGINX eingeht, bestimmt der Standortblock, wie der Datenverkehr verarbeitet und wohin er geleitet wird. Im folgenden Ausschnitt wird der gesamte Verkehr zur Website an den Upstream-Cluster mit dem Namen targetCluster. Der Upstream-Cluster legt die Knoten fest, die die Anfrage verarbeiten sollen. Wir werden dies im nächsten Schritt besprechen.
location / {
proxy_pass http://targetCluster/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}In Envoy werden diese durch Filters behandelt.
Envoy-Filter
Für die statische Konfiguration legen Filter fest, wie eingehende Anfragen bearbeitet werden. In diesem Fall setzen wir Filter, die entsprechen server_names im vorherigen Schritt. Wenn eingehende Anfragen eingehen, die bestimmten Domains und Routen entsprechen, wird der Verkehr zum Cluster geleitet. Dies entspricht der aufsteigenden Konfiguration von NGINX.
Copy to Editor filter_chains:
- filters:
- name: envoy.http_connection_manager
config:
codec_type: auto
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: backend
domains:
- "one.example.com"
- "www.one.example.com"
routes:
- match:
prefix: "/"
route:
cluster: targetCluster
http_filters:
- name: envoy.routerName envoy.http_connection_manager ist ein integrierter Filter im Envoy Proxy. Weitere Filter umfassen Redis, Mongo, TCP. Eine vollständige Liste finden Sie in .
Für weitere Informationen über andere Lastverteilungsmethoden besuchen Sie .
Schritt 5 — Proxy- und Upstream-Konfiguration
In der NGINX-Konfiguration definiert der upstream ein Set von Zielservern, die den Datenverkehr bearbeiten werden. Hier wurden zwei Cluster zugewiesen.
upstream targetCluster {
172.18.0.3:80;
172.18.0.4:80;
}In Envoy wird das durch Cluster verwaltet.
Envoy-Cluster
Das Äquivalent zu upstream wird als Cluster definiert. In diesem Fall wurden Hosts festgelegt, die den Datenverkehr bedienen werden. Der Zugang zu den Hosts, wie beispielsweise die Zeitüberschreitung, wird als Clusterkonfiguration definiert. Dies ermöglicht eine genauere Kontrolle über Aspekte wie die Zeitüberschreitung und die Lastverteilung.
Copy to Editor clusters:
- name: targetCluster
connect_timeout: 0.25s
type: STRICT_DNS
dns_lookup_family: V4_ONLY
lb_policy: ROUND_ROBIN
hosts: [
{ socket_address: { address: 172.18.0.3, port_value: 80 }},
{ socket_address: { address: 172.18.0.4, port_value: 80 }}
]Bei Verwendung der Dienstentdeckung STRICT_DNS Envoy wird die angegebenen DNS-Ziele kontinuierlich und asynchron auflösen. Jede zurückgegebene IP-Adresse als Ergebnis der DNS-Abfrage wird als expliziter Host im darüber liegenden Cluster betrachtet. Das bedeutet, wenn die Abfrage zwei IP-Adressen zurückgibt, geht Envoy davon aus, dass es zwei Hosts im Cluster gibt, und beide sollten lastbalanciert werden. Wenn ein Host aus dem Ergebnis entfernt wird, nimmt Envoy an, dass er nicht mehr existiert, und wird den Verkehr aus allen vorhandenen Verbindungspools auswählen.
Für weitere Informationen siehe: .
Schritt 6 — Zugriff auf Protokolle und Fehler
Endkonfiguration — Protokollierung. Anstatt Fehlerprotokolle auf die Festplatte zu übertragen, verwendet der Envoy Proxy einen Cloud-Ansatz. Alle Anwendungsprotokolle werden in stdout und stderr.
Wenn Benutzer eine Anfrage stellen, sind Zugriffsprotokolle optional und standardmäßig deaktiviert. Um die Zugriffsprotokolle für HTTP-Anfragen zu aktivieren, aktivieren Sie die Konfiguration access_log für den HTTP-Connection-Manager. Der Pfad kann entweder ein Gerät wie stdout, oder eine Datei auf der Festplatte sein, je nach Ihren Anforderungen.
Die folgende Konfiguration leitet alle Zugriffsprotokolle an stdout (Hinweis des Übersetzers – stdout ist erforderlich, um envoy innerhalb von Docker zu verwenden. Wenn Sie es außerhalb von Docker verwenden, ersetzen Sie /dev/stdout durch den Pfad zu einer regulären Protokolldatei). Kopieren Sie den Abschnitt in den Konfigurationsbereich für den Verbindungsmanager:
Zugriffsprotokoll:
- name: envoy.file_access_log
config:
path: "/dev/stdout"Die Ergebnisse sollten wie folgt aussehen:
- name: envoy.http_connection_manager
config:
codec_type: auto
stat_prefix: ingress_http
access_log:
- name: envoy.file_access_log
config:
path: "/dev/stdout"
route_config:Standardmäßig hat Envoy eine Formatzeile, die die Einzelheiten der HTTP-Anforderung enthält:
[%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"nDas Ergebnis dieser Formatzeile:
[2018-11-23T04:51:00.281Z] "GET / HTTP/1.1" 200 - 0 58 4 1 "-" "curl/7.47.0" "f21ebd42-6770-4aa5-88d4-e56118165a7d" "one.example.com" "172.18.0.4:80"Der Inhalt der Ausgabe kann angepasst werden, indem das Formatfeld festgelegt wird. Beispiel:
Zugriffsprotokoll:
- name: envoy.file_access_log
config:
path: "/dev/stdout"
format: "[%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"n"Die Protokollzeile kann auch im JSON-Format ausgegeben werden, indem das Feld json_formatverwendet. Zum Beispiel:
access_log:
- name: envoy.file_access_log
config:
path: "/dev/stdout"
json_format: {"protocol": "%PROTOCOL%@", "duration": "%DURATION%", "request_method": "%REQ(:METHOD)%"}Für weitere Informationen zur Protokollierungsstrategie besuchen Sie
Die Protokollierung ist nicht die einzige Möglichkeit, Einblicke in die Arbeit mit Envoy Proxy zu erhalten. Es sind erweiterte Trace- und Metrik-Funktionen integriert. Sie können mehr erfahren in der oder über .
Schritt 7 — Starten
Nun haben Sie die Konfiguration von NGINX auf Envoy Proxy übertragen. Der letzte Schritt besteht darin, eine Instanz von Envoy Proxy zu starten, um sie zu testen.
Starten als Benutzer
Am Anfang der NGINX-Konfiguration steht die Zeile user www www; die angibt, dass NGINX als Benutzer mit niedrigeren Privilegien ausgeführt wird, um die Sicherheit zu erhöhen.
Envoy Proxy verwendet einen Cloud-Ansatz für das Management des Prozessbesitzers. Wenn wir Envoy Proxy über einen Container starten, können wir einen Benutzer mit niedrigeren Privilegien angeben.
Envoy Proxy starten
Der folgende Befehl startet den Envoy Proxy in einem Docker-Container auf dem Host. Dieser Befehl ermöglicht es Envoy, eingehende Anfragen über Port 80 zu empfangen. Allerdings, wie in der Listener-Konfiguration angegeben, hört der Envoy Proxy auf den eingehenden Verkehr über Port 8080. Dies ermöglicht, dass der Prozess als Nutzer mit niedrigen Berechtigungen läuft.
docker run --name proxy1 -p 80:8080 --user 1000:1000 -v /root/envoy.yaml:/etc/envoy/envoy.yaml envoyproxy/envoyTesten
Mit dem laufenden Proxy können nun Tests durchgeführt und bearbeitet werden. Der folgende cURL-Befehl sendet eine Anfrage mit dem in der Proxy-Konfiguration definierten Host-Header.
curl -H "Host: one.example.com" localhost -iDie HTTP-Anfrage wird zu einem Fehler führen 503. Dies liegt daran, dass eingehende Verbindungen nicht funktionieren und nicht verfügbar sind. Daher hat der Envoy Proxy keine verfügbaren Zieladressen für die Anfrage. Der folgende Befehl startet eine Reihe von HTTP-Diensten, die der für Envoy definierten Konfiguration entsprechen.
docker run -d katacoda/docker-http-server; docker run -d katacoda/docker-http-server;Mit verfügbaren Diensten kann Envoy den Verkehr erfolgreich an das Ziel weiterleiten.
curl -H "Host: one.example.com" localhost -iSie sollten eine Antwort sehen, die angibt, welcher Docker-Container die Anfrage verarbeitet hat. In den Protokollen des Envoy Proxy sollten Sie ebenfalls die ausgegebene Zugriffskette sehen.
Zusätzliche HTTP-Antwortheader (HTTP Response)
In den Headern der gültigen Antwort erkennen Sie zusätzliche HTTP-Header. Der Header zeigt die Zeit an, die der übergeordnete Host für die Verarbeitung der Anfrage benötigt hat. Dies wird in Millisekunden ausgedrückt. Dies ist nützlich, wenn der Kunde die Bearbeitungszeit im Vergleich zur Netzwerkverzögerung bestimmen möchte.
x-envoy-upstream-service-time: 0
server: envoyEndkonfiguration
static_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 8080 }
filter_chains:
- filters:
- name: envoy.http_connection_manager
config:
codec_type: auto
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: backend
domains:
- "one.example.com"
- "www.one.example.com"
routes:
- match:
prefix: "/"
route:
cluster: targetCluster
http_filters:
- name: envoy.router
clusters:
- name: targetCluster
connect_timeout: 0.25s
type: STRICT_DNS
dns_lookup_family: V4_ONLY
lb_policy: ROUND_ROBIN
hosts: [
{ socket_address: { address: 172.18.0.3, port_value: 80 }},
{ socket_address: { address: 172.18.0.4, port_value: 80 }}
]
admin:
access_log_path: /tmp/admin_access.log
address:
socket_address: { address: 0.0.0.0, port_value: 9090 }Zusätzliche Informationen vom Übersetzer
Die Installationsanleitungen für den Envoy Proxy finden Sie auf der Website
Standardmäßig fehlt im RPM die Systemd-Service-Konfiguration.
Fügen Sie die Systemd-Service-Konfiguration in /etc/systemd/system/envoy.service hinzu:
[Unit]
Description=Envoy Proxy
Documentation=https://www.envoyproxy.io/
After=network-online.target
Requires=envoy-auth-server.service
Wants=nginx.service
[Service]
User=root
Restart=on-failure
ExecStart=/usr/bin/envoy --config-path /etc/envoy/config.yaml
[Install]
WantedBy=multi-user.targetSie müssen das Verzeichnis /etc/envoy/ erstellen und dort die Konfiguration config.yaml ablegen.
Es gibt einen Telegram-Chat zum Envoy Proxy:
Der Envoy Proxy unterstützt keine Verteilung statischer Inhalte. Daher stimmen Sie bitte für das Feature ab:
Nur registrierte Benutzer können an der Umfrage teilnehmen. Sind Sie an Contour interessiert?
Hat dieser Beitrag Sie dazu animiert, den Envoy Proxy zu installieren und zu testen?
ja
nein
75 Nutzer haben abgestimmt. 18 Nutzer haben sich enthalten.
Quelle: habr.com
