Migration fra Nginx til Envoy Proxy

Hej, Habr! Jeg gør dig opmærksom på en oversættelse af indlægget: Migration fra Nginx til Envoy Proxy.

Envoy er en højtydende distribueret proxyserver (skrevet i C++) designet til individuelle tjenester og applikationer, den er også en kommunikationsbus og "universal dataplan" designet til store mikroservice "service mesh" arkitekturer. Ved oprettelsen af ​​den blev der taget højde for løsninger på problemer, der opstod under udviklingen af ​​servere som NGINX, HAProxy, hardware load balancers og cloud load balancers. Envoy arbejder sammen med hver applikation og abstraherer netværket for at give fælles funktionalitet uanset platform. Når al servicetrafik i en infrastruktur flyder gennem Envoy-nettet, bliver det nemt at visualisere problemområder med ensartet observerbarhed, justere den overordnede ydeevne og tilføje kernefunktionalitet på et bestemt sted.

Capabilities

  • Ude af proces-arkitektur: envoy er en selvstændig, højtydende server, der optager en lille mængde RAM. Det fungerer sammen med ethvert applikationssprog eller -framework.
  • http/2 og grpc support: envoy har førsteklasses http/2 og grpc support til indgående og udgående forbindelser. Dette er en gennemsigtig proxy fra http/1.1 til http/2.
  • Avanceret belastningsbalancering: envoy understøtter avancerede belastningsbalanceringsfunktioner, herunder automatiske genforsøg, kædebrud, global hastighedsbegrænsning, anmodningsskygge, lokal zonebelastningsbalancering osv.
  • Configuration Management API: envoy leverer en robust API til dynamisk styring af din konfiguration.
  • Observerbarhed: Dyb observerbarhed af L7-trafik, indbygget understøttelse af distribueret sporing og observerbarhed af mongodb, dynamodb og mange andre applikationer.

Trin 1 — Eksempel NGINX Config

Dette script bruger en specielt udformet fil nginx.conf, baseret på det fulde eksempel fra NGINX Wiki. Du kan se konfigurationen i editoren ved at åbne nginx.conf

nginx kildekonfiguration

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 typisk tre nøgleelementer:

  1. Konfiguration af NGINX-server, logstruktur og Gzip-funktionalitet. Dette er i alle tilfælde defineret globalt.
  2. Konfigurerer NGINX til at acceptere anmodninger til værten one.example.com på port 8080.
  3. Opsætning af målplacering, hvordan man håndterer trafik for forskellige dele af URL'en.

Ikke al konfiguration vil gælde for Envoy Proxy, og du behøver ikke at konfigurere nogle indstillinger. Envoy Proxy har fire nøgletyper, som understøtter kerneinfrastrukturen, der tilbydes af NGINX. Kernen er:

  • Lyttere: De bestemmer, hvordan Envoy Proxy accepterer indgående anmodninger. Envoy Proxy understøtter i øjeblikket kun TCP-baserede lyttere. Når en forbindelse er etableret, sendes den til et sæt filtre til behandling.
  • Filtre: De er en del af en pipeline-arkitektur, der kan behandle indgående og udgående data. Denne funktionalitet inkluderer filtre såsom Gzip, som komprimerer dataene, før de sendes til klienten.
  • Routere: De videresender trafik til den nødvendige destination, defineret som en klynge.
  • Klynger: De definerer endepunktet for trafik- og konfigurationsparametre.

Vi vil bruge disse fire komponenter til at oprette en Envoy Proxy-konfiguration, der matcher en specifik NGINX-konfiguration. Envoys mål er at arbejde med API'er og dynamisk konfiguration. I dette tilfælde vil basiskonfigurationen bruge statiske, hårdkodede indstillinger fra NGINX.

Trin 2 - NGINX-konfiguration

Den første del nginx.conf definerer nogle NGINX internals, der skal konfigureres.

Arbejderforbindelser

Konfigurationen nedenfor bestemmer antallet af arbejdsprocesser og forbindelser. Dette indikerer, hvordan NGINX vil skalere for at imødekomme efterspørgslen.

worker_processes  2;

events {
  worker_connections   2000;
}

Envoy Proxy styrer arbejdsgange og forbindelser på forskellige måder.

Envoy opretter en arbejdstråd for hver hardwaretråd på systemet. Hver arbejdstråd udfører en ikke-blokerende hændelsesløkke, som er ansvarlig for

  1. At lytte til hver enkelt lytter
  2. Accept af nye forbindelser
  3. Oprettelse af et sæt filtre til en forbindelse
  4. Behandle alle I/O-operationer i forbindelsens levetid.

Al yderligere forbindelsesbehandling håndteres udelukkende i arbejdstråden, inklusive eventuel videresendelsesadfærd.

For hver arbejdertråd i Envoy er der en forbindelsespulje. Så HTTP/2-forbindelsespuljer etablerer kun én forbindelse pr. ekstern vært ad gangen, hvis der er fire arbejdertråde, vil der være fire HTTP/2-forbindelser pr. ekstern vært i en stabil tilstand. Ved at holde alt i én arbejdstråd kan næsten al kode skrives uden blokering, som om den var enkelttrådet. Hvis der tildeles flere arbejdstråde end nødvendigt, kan dette føre til spild af hukommelse, skabe et stort antal ledige forbindelser og reducere antallet af gange, forbindelser returneres tilbage til poolen.

For mere information besøg Envoy Proxy blog.

HTTP-konfiguration

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

  • Hvilke mime-typer understøttes
  • Standard timeouts
  • Gzip-konfiguration

Du kan tilpasse disse aspekter ved hjælp af filtre i Envoy Proxy, som vi vil diskutere senere.

Trin 3 - Serverkonfiguration

I HTTP-konfigurationsblokken specificerer NGINX-konfigurationen at lytte på port 8080 og svare på indgående anmodninger om domæner one.example.com и www.one.example.com.

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

Inde i Envoy styres det af lyttere.

Udsendings lyttere

Det vigtigste aspekt ved at komme i gang med Envoy Proxy er at definere dine lyttere. Du skal oprette en konfigurationsfil, der beskriver, hvordan du vil køre Envoy-forekomsten.

Uddraget nedenfor vil oprette en ny lytter og binde den til port 8080. Konfigurationen fortæller Envoy Proxy, hvilke porte den skal binde til for indgående anmodninger.

Envoy Proxy bruger YAML-notation til sin konfiguration. For en introduktion til denne notation, se her link.

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

Ingen grund til at definere server navn, da Envoy Proxy-filtre vil håndtere dette.

Trin 4 - Placeringskonfiguration

Når en anmodning kommer ind i NGINX, bestemmer lokationsblokken, hvordan trafikken skal behandles, og hvor den skal dirigeres. I det følgende fragment overføres al trafik til webstedet til en upstream-klynge (oversætterens note: upstream er normalt en applikationsserver) med navnet targetCluster. Opstrømsklyngen definerer de noder, der skal behandle anmodningen. Vi vil diskutere dette i næste trin.

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

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

Hos Envoy gør Filters dette.

Envoy filtre

For en statisk konfiguration bestemmer filtre, hvordan indgående anmodninger skal behandles. I dette tilfælde indstiller vi filtre, der matcher servernavne i det foregående trin. Når der kommer indgående anmodninger, der matcher bestemte domæner og ruter, dirigeres trafikken til klyngen. Dette svarer til en NGINX bottom-up konfiguration.

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 Omfor, Mongo, TCP. Du kan finde hele listen på dokumentation.

For mere information om andre belastningsbalanceringspolitikker, besøg Udsendingsdokumentation.

Trin 5 - Proxy og Upstream-konfiguration

I NGINX definerer opstrømskonfigurationen et sæt målservere, der behandler trafik. I dette tilfælde blev der tildelt to klynger.

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

I Envoy styres dette af klynger.

Udsendingsklynger

Opstrømsækvivalenten er defineret som klynger. I dette tilfælde er de værter, der skal betjene trafikken, blevet identificeret. Den måde, der tilgås værter på, såsom timeouts, er defineret som en klyngekonfiguration. Dette giver mulighed for mere granulær kontrol over aspekter som latens og belastningsbalancering.

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

Når du bruger serviceopdagelse STRICT_DNS Envoy vil løbende og asynkront løse de angivne DNS-mål. Hver returneret IP-adresse fra DNS-resultatet vil blive betragtet som en eksplicit vært i upstream-klyngen. Det betyder, at hvis en anmodning returnerer to IP-adresser, vil Envoy antage, at der er to værter i klyngen, og begge skal være load balanced. Hvis en vært fjernes fra resultatet, antager Envoy, at den ikke længere eksisterer og trækker trafik fra eksisterende forbindelsespuljer.

For mere information se Envoy proxy dokumentation.

Trin 6 — Logadgang og fejl

Den endelige konfiguration er registrering. I stedet for at skubbe fejllogfiler til disk, tager Envoy Proxy en skybaseret tilgang. Alle applikationslogfiler udsendes til stdout и stderr.

Når brugere fremsætter en anmodning, er adgangslogfiler valgfri og deaktiveret som standard. Aktiver konfigurationen for at aktivere adgangslogfiler til HTTP-anmodninger adgangslog til HTTP-forbindelsesadministratoren. Stien kan enten være en enhed som f.eks stdout, eller en fil på disk, afhængigt af dine krav.

Følgende konfiguration vil omdirigere alle adgangslogfiler til stdout (oversætterens note - stdout er påkrævet for at bruge envoy inde i docker. Hvis det bruges uden docker, så erstat /dev/stdout med stien til en almindelig logfil). Kopiér kodestykket til konfigurationssektionen for forbindelsesadministratoren:

Copy to Clipboardaccess_log:
- name: envoy.file_access_log
  config:
    path: "/dev/stdout"

Resultaterne skulle se sådan 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 detaljerne for HTTP-anmodningen:

[%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 er:

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

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

Loglinjen 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 mere information om envoy Registration Methodology, besøg

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

Logning er ikke den eneste måde at få indsigt i arbejdet med Envoy Proxy. Den har avancerede sporings- og metriske funktioner indbygget. Du kan få mere at vide på sporingsdokumentation eller via Interaktivt sporingsscript.

Trin 7 - Start

Du har nu migreret din konfiguration fra NGINX til Envoy Proxy. Det sidste trin er at starte en Envoy Proxy-instans for at teste den.

Kør som bruger

Øverst på NGINX-konfigurationslinjen bruger www www; specificerer at køre NGINX som en lavprivilegeret bruger for at forbedre sikkerheden.

Envoy Proxy har en cloud-baseret tilgang til at styre, hvem der ejer en proces. Når vi kører Envoy Proxy gennem en container, kan vi angive en lavprivilegeret bruger.

Lancering af Envoy Proxy

Kommandoen nedenfor vil køre Envoy Proxy gennem en Docker-container på værten. Denne kommando giver Envoy mulighed for at lytte efter indgående anmodninger på port 80. Som angivet i lytterkonfigurationen lytter Envoy Proxy dog ​​efter indgående trafik på port 8080. Dette gør det muligt for processen at køre som en lavprivilegeret bruger.

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

Test

Når proxyen kører, kan tests nu udføres og behandles. Følgende cURL-kommando udsteder en anmodning med værtsheaderen defineret i proxykonfigurationen.

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

HTTP-anmodningen vil resultere i en fejl 503. Dette skyldes, at opstrømsforbindelser ikke fungerer og ikke er tilgængelige. Derfor har Envoy Proxy ingen tilgængelige destinationer for anmodningen. Følgende kommando starter en række HTTP-tjenester, der matcher den konfiguration, 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 sin destination.

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

Du bør se et svar, der angiver, hvilken Docker-container, der behandlede anmodningen. I Envoy Proxy-logfilerne bør du også se en adgangsstrengoutput.

Yderligere HTTP-svar-headere

Du vil se yderligere HTTP-headers i svar-headerne for den faktiske anmodning. Overskriften viser den tid, opstrømsværten brugte på at behandle anmodningen. Udtrykt i millisekunder. Dette er nyttigt, hvis klienten ønsker at bestemme servicetid sammenlignet med netværksforsinkelse.

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

Endelig 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

Instruktioner til installation af Envoy Proxy kan findes på hjemmesiden https://www.getenvoy.io/

Som standard har rpm ikke en systemd service-konfiguration.

Tilføj systemd service config /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 config.yaml config der.

Der er en telegramchat ved hjælp af envoy proxy: https://t.me/envoyproxy_ru

Envoy Proxy understøtter ikke visning af statisk indhold. Hvem kan derfor stemme på indslaget: https://github.com/envoyproxy/envoy/issues/378

Kun registrerede brugere kan deltage i undersøgelsen. Log ind, Vær venlig.

Opfordrede dette indlæg dig til at installere og teste envoy proxy?

  • ja

  • ingen

75 brugere stemte. 18 brugere undlod at stemme.

Kilde: www.habr.com

Tilføj en kommentar