Migration fra Nginx til Envoy Proxy

Hej, Habr! Jeg præsenterer hermed oversættelsen af indlægget: Migration fra Nginx til Envoy Proxy.

Envoy er en højtydende distribueret proxy-server (skrevet i C++), designet til individuelle tjenester og applikationer. Det fungerer også som et kommunikationsbus og "universal data plane", udviklet til store mikroservice-arkitekturer kaldet "service mesh". Under udviklingen blev der taget højde for løsninger på de problemer, der opstod ved udvikling af servere som NGINX, HAProxy, hardware load balancere og cloud load balancere. Envoy arbejder sammen med enhver applikation og abstraherer netværket, hvilket giver fælles funktioner uafhængigt af platformen. Når al service-trafik i infrastrukturen passerer gennem Envoy-netværket, bliver det nemt at visualisere problemområder med konsistent overvågning, justere den samlede ydeevne og tilføje kernefunktioner på specifikke steder.

Muligheder

  • Arkitektur uden for processen: Envoy er en autonom, højtydende server, der bruger en lille mængde hukommelse. Den arbejder sammen med ethvert programmeringssprog eller framework.
  • Understøttelse af http/2 og grpc: Envoy har førsteklasses understøttelse af http/2 og grpc for indgående og udgående forbindelser. Det er en gennemsigtig proxy fra http/1.1 til http/2.
  • Avanceret belastningsfordeling: Envoy understøtter avancerede funktioner til belastningsfordeling, herunder automatiske genforsøg, kædebrud, global hastighedsbegrænsning, skygning af anmodninger, lokal belastningsfordeling af zoner osv.
  • API til konfigurationsstyring: Envoy tilbyder et pålideligt API til dynamisk styring af sin konfiguration.
  • Overvågningsmuligheder: dyb overvågning af L7-trafik, indbygget understøttelse af distribueret sporing og overvågning af mongodb, dynamodb og mange andre applikationer.

Trin 1 — Eksempel på NGINX-konfiguration

I dette scenarie anvendes en specielt oprettet fil nginx.conf, baseret på det fulde eksempel fra NGINX Wiki. Du kan se konfigurationen i editoren ved at åbne nginx.conf

Den originale nginx-konfiguration

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;
    }
  }
}

NGINX-konfigurationer har normalt tre centrale elementer:

  1. Konfiguration af NGINX-serveren, logstrukturen og Gzip-funktionaliteten. Dette defineres globalt i alle tilfælde.
  2. Konfiguration af NGINX til at modtage anmodninger på værten one.example.com på port 8080.
  3. Konfiguration af destinationsplaceringen, hvordan trafik skal håndteres for forskellige dele af URL'en.

Ikke hele konfigurationen vil blive anvendt på Envoy Proxy, og du behøver ikke at konfigurere nogle parametre. Envoy Proxy har fire centrale typer, som understøtter den grundlæggende infrastruktur, der tilbydes af NGINX. Kernen er:

  • Lyttere: De bestemmer, hvordan Envoy Proxy modtager indkommende anmodninger. I øjeblikket understøtter Envoy Proxy kun lyttere baseret på TCP. Når forbindelsen er etableret, videregives den til et sæt filtre til behandling.
  • Filtre: De er en del af en pipeline-arkitektur, der kan håndtere indkommende og udgående data. Denne funktion inkluderer filtre som Gzip, der komprimerer data, inden de sendes til klienten.
  • Ruteledere: De omdirigerer trafik til den ønskede destination, der er defineret som et cluster.
  • Clustere: De definerer slutpunktet for trafikken og konfigurationsparametrene.

Vi vil bruge disse fire komponenter til at oprette en konfiguration af Envoy Proxy, der stemmer overens med en bestemt NGINX-konfiguration. Målet med Envoy er at arbejde med API'er og dynamisk konfiguration. I dette tilfælde vil den grundlæggende konfiguration bruge statiske, fastlagte parametre fra NGINX.

Trin 2 — NGINX-konfiguration

Første del nginx.conf definerer nogle interne komponenter af NGINX, der skal konfigureres.

Worker Connections

Den følgende konfiguration definerer antallet af arbejdsprocesser og forbindelser. Dette angiver, hvordan NGINX vil skalere for at imødekomme efterspørgslen.

worker_processes  2;

events {
  worker_connections   2000;
}

Envoy Proxy håndterer arbejdsprocesser og forbindelser på forskellig måde.

Envoy opretter en arbejdsstrøm for hver hardware-tråd i systemet. Hver arbejdsstrøm kører en ikke-blokerende begivenhedscyklus, som er ansvarlig for

  1. At lytte til hver lytter (listener)
  2. At acceptere nye forbindelser
  3. At oprette et sæt filtre til forbindelsen
  4. At håndtere alle input-output-operationer i forbindelse med forbindelsens levetid.

Al videre behandling af forbindelsen udføres fuldstændigt i arbejdsstrømmen, herunder enhver omdirigeringsadfærd.

For hver arbejdsstrøm i Envoy findes der en forbindelse i puljen. Derfor etablerer HTTP/2-forbindelsespuljer kun én forbindelse for hver ekstern vært ad gangen; med fire arbejdsstrømme vil der være fire HTTP/2-forbindelser for hver ekstern vært i stabil tilstand. Ved at holde alt i én arbejdsstrøm kan næsten al koden skrives uden blokeringer, som hvis den var enkelttrådet. Hvis der tildeles flere arbejdsstrømme, end nødvendigt, kan det føre til en ineffektiv brug af hukommelse, oprettelse af mange inaktive forbindelser og et reduceret antal forbindelser tilbage til puljen.

For mere information, besøg Envoy Proxy blog.

HTTP-konfiguration

Den følgende NGINX-konfigurationsblok definerer HTTP-indstillinger såsom:

  • Hvilke MIME-typer der understøttes
  • Standard timeout-indstillinger
  • Gzip-konfiguration

Du kan konfigurere disse aspekter med filtre i Envoy Proxy, som vi vil diskutere senere.

Trin 3 — Serverkonfiguration

I HTTP-konfigurationsblokken angiver NGINX at lytte til port 8080 og svare på indkommende anmodninger for domæner one.example.com og www.one.example.com.

 server {
    listen        8080;
    server_name   one.example.com  www.one.example.com;

Inde i Envoy styres dette af Lyttere.

Envoy Lyttere

Den vigtigste aspekt ved at komme i gang med Envoy Proxy er at definere lytterne. Du skal oprette en konfigurationsfil, der beskriver, hvordan du ønsker at køre en instans af Envoy.

Det følgende fragment vil oprette en ny lytter og knytte den til port 8080. Konfigurationen angiver, hvilke porte Envoy Proxy skal være knyttet til for indkommende forespørgsler.

Envoy Proxy bruger YAML-notation til sin konfiguration. For at lære om denne notation, se her. linket.

Copy to Editorstatic_resources:
  listeners:
  - name: listener_0
    address:
      socket_address: { address: 0.0.0.0, port_value: 8080 }

Der er ikke behov for at definere server_name, da Envoy Proxy-filtre vil tage sig af dette.

Trin 4 — Konfiguration af lokation

Når en forespørgsel kommer til NGINX, bestemmer lokationsblokken, hvordan man behandler og hvor man sender trafikken. I det følgende fragment overføres al trafik til webstedet til upstream (note fra oversætteren: upstream — normalt applikationsservere) klyngen med navnet targetCluster. Upstream-klyngen bestemmer, hvilke noder der skal håndtere forespørgslen. Vi vil diskutere dette i det næste trin.

location / {
    proxy_pass         http://targetCluster/;
    proxy_redirect     off;

    proxy_set_header   Host             $host;
    proxy_set_header   X-Real-IP        $remote_addr;
}

I Envoy håndteres dette af filtre.

Envoy Filtre

For statisk konfiguration definerer filtrene, hvordan man behandler indkommende forespørgsler. I dette tilfælde sætter vi filtre, der matcher server_names from the previous step. Når der kommer indkommende forespørgsler, der matcher bestemte domæner og ruter, sendes trafikken til klyngen. Dette svarer til den opstegne konfiguration af 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.router

Navn envoy.http_connection_manager er et indbygget filter i Envoy Proxy. Andre filtre inkluderer Redis, Mongo, TCP. Du kan finde en komplet liste i dokumentationen.

For mere information om andre belastningsfordelingspolitikker, besøg Dokumentationen for Envoy.

Trin 5 — Proxy- og upstream-konfiguration

I NGINX definerer upstream-konfigurationen et sæt målservere, der skal håndtere trafikken. I dette tilfælde er to klynger blevet tildelt.

  upstream targetCluster {
    172.18.0.3:80;
    172.18.0.4:80;
  }

I Envoy styres dette af klynger.

Envoy Klynger

En upstreamækvivalent defineres som klynger. I dette tilfælde er der defineret værter, der vil betjene trafikken. Måden at få adgang til værterne, for eksempel timeout, defineres som klusterkonfiguration. Dette gør det muligt at kontrollere granulariteten af aspekter som timeout og belastningsfordeling mere præcist.

Kopier til editoren  klynger:
  - navn: targetCluster
    connect_timeout: 0.25s
    type: STRICT_DNS
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    værter: [
      { socket_address: { address: 172.18.0.3, port_value: 80 }},
      { socket_address: { address: 172.18.0.4, port_value: 80 }}
    ]

Ved brug af tjenesteopdagelse STRICT_DNS Envoy vil kontinuerligt og asynkront opløse de angivne DNS-mål. Hver IP-adresse, der returneres som resultat af DNS, vil blive betragtet som en eksplicit vært i upstream-klyngen. Det betyder, at hvis en forespørgsel returnerer to IP-adresser, antager Envoy, at der er to værter i klyngen, og begge skal balanceres belastningsmæssigt. Hvis en vært fjernes fra resultatet, antager Envoy, at den ikke længere eksisterer, og vil vælge trafik fra eventuelle eksisterende forbindelsespuljer.

For yderligere information, se. Dokumentationen for Envoy-proxy.

Trin 6 - Adgang til loggen og fejl

Den endelige konfiguration - registrering. I stedet for at sende fejlrapporter til disk, benytter Envoy Proxy en skytilgang. Alle applikationslogfiler outputtes til stdout og stderr.

Når brugerne laver en forespørgsel, er adgangsloggene valgfrie og som standard deaktiveret. For at aktivere adgangslogs for HTTP-forespørgsler, aktiver konfigurationen. access_log for HTTP-forbindelseschef. Stien kan enten være en enhed, som f.eks. stdout, eller en fil på disken afhængigt af dine krav.

Den følgende konfiguration vil omdirigere alle adgangslogs til stdout (redaktørens note - stdout er nødvendigt for at bruge envoy inden for docker. Hvis det bruges uden docker, skal du erstatte /dev/stdout med stien til en almindelig logfil). Kopier segmentet til konfigurationsafsnittet for forbindelseschefen:

Kopier til udklipsholderen access_log:
- name: envoy.file_access_log
  config:
    path: "/dev/stdout"

Resultaterne bør se således ud:

      - 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:

Som standard har Envoy en formatstreng, der inkluderer detaljer om HTTP-forespørgslen:

[%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%"n

Resultatet af denne formatstreng:

[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"

Indholdet af output kan tilpasses ved at indstille formatfeltet. For eksempel:

access_log:
- 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"

Logstrengen kan også udskrives i JSON-format ved at indstille feltet json_format. For eksempel:

access_log:
- name: envoy.file_access_log
  config:
    path: "/dev/stdout"
    json_format: {"protocol": "%PROTOCOL%", "duration": "%DURATION%", "request_method": "%REQ(:METHOD)%"}

For at få flere oplysninger om metoden til at logge beskeder, besøg

https://www.envoyproxy.io/docs/envoy/latest/configuration/access_log#config-access-log-format-dictionaries

Logging er ikke den eneste måde at få indsigt i arbejdet med Envoy Proxy. Den har indbygget avanceret sporings- og metrics-funktionalitet. Du kan læse mere i dokumentationen for sporing eller gennem Interaktiv sporing.

Trin 7 — Start

Nu har du oversat konfigurationen fra NGINX til Envoy Proxy. Det sidste skridt er at køre en instans af Envoy Proxy for at teste det.

Kørsel som bruger

Øverst i NGINX-konfigurationen angiver linjen user www www; at NGINX kører som en bruger med lave rettigheder for at øge sikkerheden.

Envoy Proxy bruger en skybaseret tilgang til at håndtere, hvem der ejer processen. Når vi kører Envoy Proxy via en container, kan vi angive en bruger med lave rettigheder.

Start Envoy Proxy

Kommandoen nedenfor starter Envoy Proxy gennem en Docker-container på værten. Denne kommando giver Envoy mulighed for at lytte til indkommende anmodninger på port 80. Men som angivet i lytterkonfigurationen, lytter Envoy Proxy til indkommende trafik via port 8080. Dette gør det muligt for processen at køre som en bruger med lave rettigheder.

docker run --name proxy1 -p 80:8080 --user 1000:1000 -v /root/envoy.yaml:/etc/envoy/envoy.yaml envoyproxy/envoy

Testning

Med den kørende proxy kan tests nu udføres og behandles. Den næste cURL-kommando sender en anmodning med værtens header som er defineret i proxy-konfigurationen.

curl -H "Host: one.example.com" localhost -i

HTTP-anmodningen resulterer i en fejl 503. Dette skyldes, at de opstammende forbindelser ikke fungerer og ikke er tilgængelige. Derfor har Envoy Proxy ingen tilgængelige destinationsadresser for anmodningen. Den følgende kommando vil starte en række HTTP-tjenester, der svarer til konfigurationen, der er defineret for Envoy.

docker run -d katacoda/docker-http-server; docker run -d katacoda/docker-http-server;

Med de tilgængelige tjenester kan Envoy med succes proxy trafik til destinationen.

curl -H "Host: one.example.com" localhost -i

Du bør se et svar, der angiver, hvilken Docker-container der behandlede anmodningen. I loggene fra Envoy Proxy skal du også se den udskrevne adgangsstreng.

Yderligere HTTP-svaroverskrifter (HTTP Response)

I overskrifterne af den gyldige anmodning vil du se yderligere HTTP-overskrifter. I overskriften vises den tid, som den overordnede vært brugte på at behandle anmodningen. Dette måles i millisekunder. Dette er nyttigt, hvis klienten ønsker at bestemme behandlingstiden i forhold til netværksforsinkelsen.

x-envoy-upstream-service-time: 0
server: envoy

Den endelige konfig

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 }

Yderligere information fra oversætteren

Du kan finde installationsanvisninger for Envoy Proxy på hjemmesiden https://www.getenvoy.io/

Som standard er der ikke en systemd service-konfiguration i rpm.

Tilføj systemd service-konfigurationen \/etc\/systemd\/system\/envoy.service:

[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.target

Du skal oprette en mappe \/etc\/envoy\/ og placere konfigurationen config.yaml deri.

Der er en Telegram-chat om Envoy Proxy: https://t.me/envoyproxy_ru

Envoy Proxy har ikke støtte til udlevering af statisk indhold. Så please stem på denne funktion: https://github.com/envoyproxy/envoy/issues/378

Kun registrerede brugere kan deltage i undersøgelsen. Log ind, please.

Har dette indlæg motiveret dig til at installere og teste Envoy Proxy?

  • ja

  • nej

75 brugere stemte for. 18 brugere undlod at stemme.

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster