Migrering fra Nginx til Envoy Proxy

Hei, Habr! Jeg gjør deg oppmerksom på en oversettelse av innlegget: Migrering fra Nginx til Envoy Proxy.

Envoy er en høyytelses distribuert proxy-server (skrevet i C++) designet for individuelle tjenester og applikasjoner, den er også en kommunikasjonsbuss og "universal dataplan" designet for store mikrotjenester "service mesh"-arkitekturer. Ved opprettelsen ble løsninger på problemer som oppsto under utviklingen av servere som NGINX, HAProxy, maskinvarelastbalansere og skylastbalansere tatt i betraktning. Envoy jobber sammen med hver applikasjon og abstraherer nettverket for å gi felles funksjonalitet uavhengig av plattform. Når all tjenestetrafikk i en infrastruktur flyter gjennom Envoy-nettverket, blir det enkelt å visualisere problemområder med konsistent observerbarhet, justere den generelle ytelsen og legge til kjernefunksjonalitet på et bestemt sted.

Evner

  • Ute av prosessarkitektur: envoy er en selvstendig server med høy ytelse som tar opp en liten mengde RAM. Det fungerer sammen med alle applikasjonsspråk eller rammeverk.
  • http/2- og grpc-støtte: envoy har førsteklasses http/2- og grpc-støtte for innkommende og utgående forbindelser. Dette er en gjennomsiktig proxy fra http/1.1 til http/2.
  • Avansert lastbalansering: envoy støtter avanserte lastbalanseringsfunksjoner, inkludert automatiske forsøk på nytt, kjedebrudd, global hastighetsbegrensning, forespørselsskyggelegging, lokal sonelastbalansering, etc.
  • Configuration Management API: envoy tilbyr en robust API for dynamisk administrasjon av konfigurasjonen din.
  • Observerbarhet: Dyp observerbarhet av L7-trafikk, innebygd støtte for distribuert sporing og observerbarhet av mongodb, dynamodb og mange andre applikasjoner.

Trinn 1 — Eksempel NGINX Config

Dette skriptet bruker en spesiallaget fil nginx.conf, basert på det fullstendige eksemplet fra NGINX Wiki. Du kan se konfigurasjonen i editoren ved å åpne nginx.conf

nginx kildekonfigurasjon

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-konfigurasjoner har vanligvis tre nøkkelelementer:

  1. Konfigurering av NGINX-server, loggstruktur og Gzip-funksjonalitet. Dette er definert globalt i alle tilfeller.
  2. Konfigurerer NGINX til å godta forespørsler til verten one.example.com på port 8080.
  3. Sette opp målstedet, hvordan håndtere trafikk for ulike deler av URL-en.

Ikke all konfigurasjon vil gjelde for Envoy Proxy, og du trenger ikke å konfigurere noen innstillinger. Utsendingsfullmektig har fire nøkkeltyper, som støtter kjerneinfrastrukturen som tilbys av NGINX. Kjernen er:

  • Lyttere: De bestemmer hvordan Envoy Proxy godtar innkommende forespørsler. Envoy Proxy støtter foreløpig bare TCP-baserte lyttere. Når en tilkobling er opprettet, sendes den til et sett med filtre for behandling.
  • Filtre: De er en del av en pipeline-arkitektur som kan behandle innkommende og utgående data. Denne funksjonaliteten inkluderer filtre som Gzip, som komprimerer dataene før de sendes til klienten.
  • Rutere: De videresender trafikk til ønsket destinasjon, definert som en klynge.
  • Klynger: De definerer endepunktet for trafikk- og konfigurasjonsparametere.

Vi vil bruke disse fire komponentene til å lage en Envoy Proxy-konfigurasjon for å matche en spesifikk NGINX-konfigurasjon. Envoys mål er å jobbe med APIer og dynamisk konfigurasjon. I dette tilfellet vil basekonfigurasjonen bruke statiske, hardkodede innstillinger fra NGINX.

Trinn 2 - NGINX-konfigurasjon

Den første delen nginx.conf definerer noen interne NGINX-komponenter som må konfigureres.

Arbeiderforbindelser

Konfigurasjonen nedenfor bestemmer antall arbeidsprosesser og tilkoblinger. Dette indikerer hvordan NGINX vil skalere for å møte etterspørselen.

worker_processes  2;

events {
  worker_connections   2000;
}

Envoy Proxy administrerer arbeidsflyter og tilkoblinger på forskjellige måter.

Envoy oppretter en arbeidertråd for hver maskinvaretråd i systemet. Hver arbeidertråd kjører en ikke-blokkerende hendelsesløkke som er ansvarlig for

  1. Å lytte til hver enkelt lytter
  2. Godta nye forbindelser
  3. Opprette et sett med filtre for en tilkobling
  4. Behandle alle I/O-operasjoner i løpet av tilkoblingens levetid.

All videre tilkoblingsbehandling håndteres i sin helhet i arbeidertråden, inkludert eventuell videresending.

For hver arbeidertråd i Envoy er det en koblingspool. Så HTTP/2-tilkoblingspooler oppretter bare én tilkobling per ekstern vert om gangen, hvis det er fire arbeidertråder vil det være fire HTTP/2-tilkoblinger per ekstern vert i en stabil tilstand. Ved å holde alt i én arbeidstråd, kan nesten all kode skrives uten blokkering, som om den var enkelttråd. Hvis flere arbeidertråder tildeles enn nødvendig, kan dette føre til bortkastet minne, skape et stort antall ledige tilkoblinger og redusere antall ganger tilkoblinger returneres tilbake til bassenget.

For mer informasjon besøk Envoy Proxy-blogg.

HTTP-konfigurasjon

Følgende NGINX-konfigurasjonsblokk definerer HTTP-innstillinger som:

  • Hvilke mime-typer støttes
  • Standard tidsavbrudd
  • Gzip-konfigurasjon

Du kan tilpasse disse aspektene ved å bruke filtre i Envoy Proxy, som vi vil diskutere senere.

Trinn 3 - Serverkonfigurasjon

I HTTP-konfigurasjonsblokken spesifiserer NGINX-konfigurasjonen å lytte på port 8080 og svare på innkommende forespørsler om domener one.example.com и www.one.example.com.

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

Inne i Envoy er den kontrollert av lyttere.

Utsendings lyttere

Det viktigste aspektet ved å komme i gang med Envoy Proxy er å definere lytterne dine. Du må lage en konfigurasjonsfil som beskriver hvordan du vil kjøre Envoy-forekomsten.

Utdraget nedenfor vil opprette en ny lytter og binde den til port 8080. Konfigurasjonen forteller Envoy Proxy hvilke porter den skal bindes til for innkommende forespørsler.

Envoy Proxy bruker YAML-notasjon for konfigurasjonen. For en introduksjon til denne notasjonen, se her link.

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

Ingen grunn til å definere Server navn, siden Envoy Proxy-filtre vil håndtere dette.

Trinn 4 - Plasseringskonfigurasjon

Når en forespørsel kommer inn i NGINX, bestemmer lokasjonsblokken hvordan trafikken skal behandles og hvor trafikken skal rutes. I det følgende fragmentet blir all trafikk til nettstedet overført til en oppstrømsklynge (oversetterens merknad: oppstrøms er vanligvis en applikasjonsserver) med navn targetCluster. Oppstrømsklyngen definerer nodene som skal behandle forespørselen. Vi vil diskutere dette i neste trinn.

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

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

Hos Envoy gjør Filters dette.

Utsendingsfiltre

For en statisk konfigurasjon bestemmer filtre hvordan innkommende forespørsler skal behandles. I dette tilfellet setter vi filtre som samsvarer servernavn i forrige trinn. Når innkommende forespørsler kommer som samsvarer med bestemte domener og ruter, rutes trafikken til klyngen. Dette tilsvarer en NGINX bottom-up-konfigurasjon.

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 innebygd filter i Envoy Proxy. Andre filtre inkluderer Redis, Mongo, TCP. Du finner hele listen på dokumentasjon.

For mer informasjon om andre retningslinjer for lastbalansering, besøk Utsendingsdokumentasjon.

Trinn 5 - Proxy- og oppstrømskonfigurasjon

I NGINX definerer oppstrømskonfigurasjonen et sett med målservere som skal behandle trafikk. I dette tilfellet ble to klynger tildelt.

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

I Envoy administreres dette av klynger.

Utsendingsklynger

Oppstrømsekvivalenten er definert som klynger. I dette tilfellet er vertene som skal betjene trafikken identifisert. Måten verter får tilgang til, for eksempel tidsavbrudd, er definert som en klyngekonfigurasjon. Dette gir mulighet for mer detaljert kontroll over aspekter som latens og lastbalansering.

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 bruker tjenesteoppdagelse STRICT_DNS Envoy vil kontinuerlig og asynkront løse de angitte DNS-målene. Hver returnert IP-adresse fra DNS-resultatet vil bli betraktet som en eksplisitt vert i oppstrømsklyngen. Dette betyr at hvis en forespørsel returnerer to IP-adresser, vil Envoy anta at det er to verter i klyngen, og begge må være lastbalansert. Hvis en vert fjernes fra resultatet, vil Envoy anta at den ikke lenger eksisterer og vil trekke trafikk fra eksisterende tilkoblingspooler.

For mer informasjon se Utsendingsfullmektig dokumentasjon.

Trinn 6 — Loggtilgang og feil

Den endelige konfigurasjonen er registrering. I stedet for å skyve feillogger til disk, tar Envoy Proxy en skybasert tilnærming. Alle applikasjonslogger sendes ut til stdout и stderr.

Når brukere sender en forespørsel, er tilgangslogger valgfrie og deaktivert som standard. Aktiver konfigurasjonen for å aktivere tilgangslogger for HTTP-forespørsler tilgangslogg for HTTP-tilkoblingsbehandling. Banen kan enten være en enhet som f.eks stdout, eller en fil på disk, avhengig av dine behov.

Følgende konfigurasjon vil omdirigere alle tilgangslogger til stdout (oversetterens notat - stdout kreves for å bruke envoy inside docker. Hvis brukt uten docker, erstatt /dev/stdout med banen til en vanlig loggfil). Kopier kodebiten til konfigurasjonsdelen for tilkoblingsbehandlingen:

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

Resultatene skal se slik ut:

      - 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 som inkluderer detaljene for HTTP-forespørselen:

[%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 av denne formatstrengen 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"

Utdatainnholdet kan tilpasses ved å angi 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"

Logglinjen kan også sendes ut i JSON-format ved å angi 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 mer informasjon om utsendingsregistreringsmetoden, besøk

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

Logging er ikke den eneste måten å få innsikt i arbeidet med Envoy Proxy. Den har avanserte sporings- og metrikkfunksjoner innebygd. Du kan finne ut mer på sporingsdokumentasjon eller gjennom Interaktivt sporingsskript.

Trinn 7 - Start

Du har nå migrert konfigurasjonen fra NGINX til Envoy Proxy. Det siste trinnet er å starte en Envoy Proxy-instans for å teste den.

Kjør som bruker

Øverst på NGINX-konfigurasjonslinjen bruker www www; spesifiserer å kjøre NGINX som en lavprivilegert bruker for å forbedre sikkerheten.

Envoy Proxy bruker en skybasert tilnærming til å administrere hvem som eier en prosess. Når vi kjører Envoy Proxy gjennom en container, kan vi spesifisere en lavprivilegert bruker.

Lanserer Envoy Proxy

Kommandoen nedenfor vil kjøre Envoy Proxy gjennom en Docker-beholder på verten. Denne kommandoen gir Envoy muligheten til å lytte etter innkommende forespørsler på port 80. Imidlertid, som spesifisert i lytterkonfigurasjonen, lytter Envoy Proxy etter innkommende trafikk på port 8080. Dette gjør at prosessen kan kjøres som en lavprivilegert bruker.

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

Testing

Når proxyen kjører, kan tester nå utføres og behandles. Følgende cURL-kommando sender en forespørsel med vertshodet definert i proxy-konfigurasjonen.

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

HTTP-forespørselen vil resultere i en feil 503. Dette er fordi oppstrømsforbindelser ikke fungerer og ikke er tilgjengelige. Derfor har Envoy Proxy ingen tilgjengelige destinasjoner for forespørselen. Følgende kommando vil starte en serie HTTP-tjenester som samsvarer med konfigurasjonen som er definert for Envoy.

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

Med tjenestene som er tilgjengelige, kan Envoy lykkes med proxy-trafikk til destinasjonen.

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

Du skal se et svar som indikerer hvilken Docker-beholder som behandlet forespørselen. I Envoy Proxy-loggene skal du også se en tilgangsstrengutgang.

Ytterligere HTTP-responshoder

Du vil se flere HTTP-overskrifter i svarhodene til den faktiske forespørselen. Overskriften viser tiden oppstrømsverten brukte på å behandle forespørselen. Uttrykt i millisekunder. Dette er nyttig hvis klienten ønsker å bestemme tjenestetid sammenlignet med nettverksforsinkelse.

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 }

Ytterligere informasjon fra oversetteren

Instruksjoner for installasjon av Envoy Proxy finner du på nettsiden https://www.getenvoy.io/

Som standard har ikke rpm en systemd servicekonfigurasjon.

Legg til 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 må opprette en katalog /etc/envoy/ og sette config.yaml config der.

Det er en telegramchat ved hjelp av envoy proxy: https://t.me/envoyproxy_ru

Envoy Proxy støtter ikke visning av statisk innhold. Derfor, hvem kan stemme på funksjonen: https://github.com/envoyproxy/envoy/issues/378

Kun registrerte brukere kan delta i undersøkelsen. Logg inn, vær så snill.

Oppfordret dette innlegget deg til å installere og teste envoy proxy?

  • ja

  • ikke

75 brukere stemte. 18 brukere avsto.

Kilde: www.habr.com

Legg til en kommentar