Migration frÄn Nginx till Envoy Proxy

Hej, Habr! Jag erbjuder er en översÀttning av inlÀgget: Migration frÄn Nginx till Envoy Proxy.

Envoy Àr en högpresterande distribuerad proxyserver (skriven i C++), avsedd för individuella tjÀnster och applikationer. Det fungerar ocksÄ som en kommunikationsbuss och "universal data plane", utvecklad för stora mikrotjÀnstarkitekturer "service mesh". Vid skapandet beaktades lösningar pÄ problem som uppstÄtt vid utvecklingen av servrar som NGINX, HAProxy, hÄrdvarubaserade belastningsbalanserare och molnbaserade belastningsbalanserare. Envoy arbetar tillsammans med varje applikation och abstraherar nÀtverket, vilket ger gemensamma funktioner oavsett plattform. NÀr all tjÀnstetrafik i infrastrukturen gÄr genom Envoy-mÄlet blir det enkelt att visualisera problemomrÄden med hjÀlp av sammanhÀngande övervakning, justera den gemensamma prestandan och lÀgga till centrala funktioner pÄ specifika platser.

Funktioner

  • Arkitektur utanför processen: Envoy Ă€r en autonom, högpresterande server som tar upp en liten mĂ€ngd minne. Den fungerar tillsammans med vilket programmeringssprĂ„k eller ramverk som helst.
  • Stöd för HTTP/2 och gRPC: Envoy har förstklassigt stöd för HTTP/2 och gRPC för inkommande och utgĂ„ende anslutningar. Det Ă€r en transparent proxy frĂ„n HTTP/1.1 till HTTP/2.
  • Avancerad belastningsbalansering: Envoy stödjer avancerade funktioner för belastningsbalansering, inklusive automatiska omförsök, kedjeavbrott, global hastighetsbegrĂ€nsning, begĂ€rningsskuggning, lokal zonbelastningsbalansering och sĂ„ vidare.
  • API för konfigurationshantering: Envoy erbjuder ett pĂ„litligt API för dynamisk hantering av sin konfiguration.
  • Övervakning: Djup övervakning av trafik L7, inbyggt stöd för distribuerad spĂ„rning och övervakning av MongoDB, DynamoDB och mĂ„nga andra applikationer.

Steg 1 - Exempel pÄ NGINX-konfiguration

Detta scenario anvÀnder en specialdesignad fil nginx.conf, baserad pÄ ett fullstÀndigt exempel frÄn NGINX Wiki. Du kan visa konfigurationen i redigeraren genom att öppna nginx.conf

Den ursprungliga nginx-konfigurationen

anvÀndare  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;
    }
  }
}

Konfigurationer för NGINX har vanligtvis tre centrala element:

  1. Konfiguration av NGINX-servern, loggstrukturen och Gzip-funktionalitet. Detta definieras globalt i alla fall.
  2. Konfiguration av NGINX för att ta emot förfrÄgningar pÄ vÀrden one.example.com pÄ port 8080.
  3. Konfiguration av mÄlplats, hur man hanterar trafik för olika delar av URL:en.

Inte hela konfigurationen kommer att tillÀmpas pÄ Envoy Proxy, och du behöver inte konfigurera vissa parametrar. Envoy Proxy har fyra centrala typer, som stöder den grundlÀggande infrastrukturen som erbjuds av NGINX. KÀrnan Àr:

  • Lyssnare: De definierar hur Envoy Proxy tar emot inkommande förfrĂ„gningar. För nĂ€rvarande stöder Envoy Proxy endast lyssnare baserade pĂ„ TCP. SĂ„ snart anslutningen Ă€r etablerad, överförs den till en uppsĂ€ttning filter för behandling.
  • Filter: De Ă€r en del av en rörledningsarkitektur som kan hantera inkommande och utgĂ„ende data. Denna funktionalitet inkluderar filter som Gzip, som komprimerar data innan de skickas till klienten.
  • Router: De omdirigerar trafiken till den angivna destination som definieras som en kluster.
  • Kluster: De definierar slutpunkten för trafiken och konfigurationsparametrar.

Vi kommer att anvÀnda dessa fyra komponenter för att skapa en konfiguration för Envoy Proxy som motsvarar en viss konfiguration av NGINX. MÄlet med Envoy Àr att arbeta med API:er och dynamisk konfiguration. I det hÀr fallet kommer den grundlÀggande konfigurationen att anvÀnda statiska, hÄrdkodade parametrar frÄn NGINX.

Steg 2 – Konfiguration av NGINX

Den första delen nginx.conf definierar nÄgra interna komponenter av NGINX som mÄste konfigureras.

Arbetsanslutningar

Följande konfiguration definierar antalet arbetsprocesser och anslutningar. Detta indikerar hur NGINX kommer att skalas för att möta efterfrÄgan.

worker_processes  2;

events {
  worker_connections   2000;
}

Envoy Proxy hanterar arbetsprocesser och anslutningar pÄ olika sÀtt.

Envoy skapar en arbetsström för varje hÄrdvarustress pÄ systemet. Varje arbetsström kör en icke-blockerande hÀndelsecykel, som ansvarar för

  1. Att lyssna pÄ varje lyssnare (listener)
  2. Att ta emot nya anslutningar
  3. Att skapa en uppsÀttning filter för anslutningen
  4. Att hantera alla in- och utdataoperationer under anslutningens livslÀngd.

All vidare bearbetning av anslutningen hanteras helt i arbetsströmmen, inklusive eventuell omdirigeringsbeteende.

För varje arbetsström i Envoy finns det en anslutning i poolen. DÀrmed upprÀttar HTTP/2-anslutningspooler endast en anslutning per extern vÀrd i taget; med fyra arbetsströmmar kommer det att finnas fyra HTTP/2-anslutningar för varje extern vÀrd i stabilt tillstÄnd. Genom att behÄlla allt i en arbetsström kan nÀstan all kod skrivas utan blockering, som om den var entrÄdad. Om fler arbetsströmmar tilldelas Àn nödvÀndigt kan det leda till ineffektiv minnesanvÀndning, skapande av mÄnga passiva anslutningar och minskning av antalet Äterförda anslutningar till poolen.

För mer information, besök Envoy Proxy blogg.

HTTP-konfiguration

Följande konfigurationsblock för NGINX definierar HTTP-instÀllningar sÄsom:

  • Vilka mime-typer som stöds
  • Standardtimeoutar
  • Gzip-konfiguration

Du kan justera dessa aspekter med hjÀlp av filter i Envoy Proxy, vilket vi kommer att diskutera senare.

Steg 3 — Serverkonfiguration

I HTTP-konfigurationsblocket specificerar NGINX att lyssna pÄ port 8080 och svara pÄ inkommande förfrÄgningar för domÀnerna one.example.com och www.one.example.com.

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

Inom Envoy hanteras detta av lyssnare.

Envoy-lyssnare

Den viktigaste aspekten av att komma igÄng med Envoy Proxy Àr att definiera lyssnare. Du mÄste skapa en konfigurationsfil som beskriver hur du vill köra en instans av Envoy.

NedanstÄende fragment skapar en ny lyssnare och kopplar den till port 8080. Konfigurationen anger för Envoy Proxy vilka portar den ska bindas till för inkommande förfrÄgningar.

Envoy Proxy anvÀnder YAML-notation för sin konfiguration. För att bekanta dig med denna notation, se hÀr. lÀnken.

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

Det finns ingen anledning att definiera server_name, eftersom Envoy Proxys filter hanterar detta.

Steg 4 – Konfiguration av plats

NÀr en förfrÄgan kommer till NGINX, definierar platsblocket hur trafik ska hanteras och var den ska dirigeras. I följande fragment vidarebefordras all trafik till webbplatsen till en upstream (översÀttarens kommentar: upstream Àr vanligtvis applikationsservrar) kluster med namnet targetCluster. Upstream-klustret definierar de noder som ska hantera förfrÄgan. Vi kommer att diskutera detta i nÀsta steg.

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

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

I Envoy hanteras detta av Filters.

Envoy Filters

För statisk konfiguration definierar filter hur inkommande förfrÄgningar ska hanteras. I det hÀr fallet stÀller vi in filter som motsvarar server_names frÄn föregÄende steg. NÀr inkommande förfrÄgningar matchar specifika domÀner och rutter, dirigeras trafiken till klustret. Detta Àr ekvivalent med en uppströmskonfiguration i 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

Namn envoy.http_connection_manager Àr ett inbyggt filter i Envoy Proxy. Andra filter inkluderar Redis, Mongo, TCP. Du kan hitta en fullstÀndig lista i dokumentationen.

För mer information om andra belastningsfördelningsmetoder, besök Envoy-dokumentationen.

Steg 5 – Proxy- och upstreamkonfiguration

I NGINX definierar upstream-konfigurationen en uppsÀttning mÄlservrar som ska hantera trafiken. I detta fall har tvÄ kluster tilldelats.

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

I Envoy hanteras detta av kluster.

Envoy Clusters

Uppströms ekvivalent definieras som kluster. I detta fall har vĂ€rdaridentifierats som ska hantera trafiken. Åtkomstmetoden till vĂ€rdarna, exempelvis tidsgrĂ€ns, definieras som klusterkonfiguration. Detta möjliggör mer exakt kontroll över detaljer som tidsgrĂ€ns och lastbalansering.

Kopiera till redigerare kluster:
  - namn: 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 }}
    ]

Vid anvÀndning av tjÀnstupptÀckten STRICT_DNS Envoy kommer kontinuerligt och asynkront att lösa angivna DNS-mÄl. Varje IP-adress som returneras frÄn DNS kommer att betraktas som en explicit vÀrd i det uppÄtgÄende klustret. Det innebÀr att om en förfrÄgan returnerar tvÄ IP-adresser kommer Envoy anta att det finns tvÄ vÀrdar i klustret och bÄda ska lastbalanseras. Om en vÀrd tas bort frÄn resultatet, antar Envoy att den inte lÀngre finns och kommer att dra trafik frÄn alla existerande anslutningspooler.

För mer information, se. Dokumentationen för Envoy Proxy.

Steg 6 — Åtkomst till loggar och fel

Slutlig konfiguration — loggning. IstĂ€llet för att skicka felrapporter till disk, anvĂ€nder Envoy Proxy en molnbaserad metod. Alla programloggar skickas till stdout och stderr.

NÀr anvÀndare gör en förfrÄgan Àr Ätkomstloggar valfria och som standard inaktiverade. För att aktivera Ätkomstloggar för HTTP-förfrÄgningar, aktivera konfigurationen access_log för HTTP-anslutningshanteraren. SökvÀgen kan antingen vara en enhet, sÄsom stdout, eller en fil pÄ disken, beroende pÄ dina krav.

Följande konfiguration kommer att vidarebefordra alla Ă„tkomstloggar till stdout (översĂ€ttarens anteckning — stdout Ă€r nödvĂ€ndigt för att anvĂ€nda envoy inuti docker. Om du anvĂ€nder utan docker, ersĂ€tt \/dev\/stdout med sökvĂ€gen till en vanlig loggfil). Kopiera fragmentet till konfigurationsavsnittet för anslutningshanteraren:

Kopiera till urklippaccess_log:
- namn: envoy.file_access_log
  config:
    path: "\/dev\/stdout"

Resultaten bör se ut sÄ hÀr:

      - namn: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          access_log:
          - namn: envoy.file_access_log
            config:
              path: "\/dev\/stdout"
          route_config:

Som standard har Envoy en formatstrÀng som inkluderar detaljer om HTTP-förfrÄgan:

[%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 denna formatstrÀng:

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

InnehÄllet i utdata kan anpassas genom att ange formatfÀltet. Till exempel:

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"

LoggstrÀngen kan ocksÄ skrivas ut i JSON-format genom att ange fÀltet json_formatJuniper (MX/QFX/ACX)

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

För mer information om loggmetodiken för envoy, besök

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

Loggning Àr inte det enda sÀttet att fÄ insyn i Envoy Proxy:s funktion. Den har inbyggda avancerade spÄrnings- och mÀtmöjligheter. Du kan lÀsa mer i dokumentationen för spÄrning eller via Interaktiv spÄrningsscenarie.

Steg 7 – Starta

Nu har du översatt konfigurationen frÄn NGINX till Envoy Proxy. Det sista steget Àr att starta en instans av Envoy Proxy för att testa den.

Starta som anvÀndare

I toppen av NGINX-konfigurationen anger raden user www www; att NGINX körs som en anvÀndare med lÄg privilegium för att förbÀttra sÀkerheten.

Envoy Proxy anvÀnder en molnbaserad metod för att hantera vem som Àger processen. NÀr vi kör Envoy Proxy i en container kan vi specificera en anvÀndare med lÄg privilegium.

Starta Envoy Proxy

Kommandot nedan kommer att starta Envoy Proxy via en Docker-container pÄ vÀrden. Detta kommando ger Envoy möjlighet att lyssna pÄ inkommande förfrÄgningar via port 80. Men som anges i lyssnarens konfiguration lyssnar Envoy Proxy pÄ inkommande trafik via port 8080. Detta gör att processen kan köras som en anvÀndare med lÄga privilegier.

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

Testning

Med proxy igÄng kan tester nu göras och hanteras. NÀsta cURL-kommando ger en begÀran med vÀrdhuvudet angivet i proxy-konfigurationen.

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

HTTP-förfrÄgan kommer att resultera i ett fel 503Det beror pÄ att inkommande anslutningar inte fungerar och dÀrmed Àr inte tillgÀngliga. PÄ sÄ sÀtt har Envoy Proxy inga tillgÀngliga mÄladresser för förfrÄgan. Följande kommando kommer att starta en serie HTTP-tjÀnster som motsvarar konfigurationen definierad för Envoy.

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

Med tillgÀngliga tjÀnster kan Envoy framgÄngsrikt proxy-trafik till destinationen.

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

Du bör se ett svar som anger vilken Docker-container som hanterade förfrÄgan. I loggarna för Envoy Proxy bör du ocksÄ se den utprintade access-strÀngen.

Ytterligare HTTP-svars-rubriker (HTTP Response)

I rubrikerna för den giltiga förfrÄgan ser du ytterligare HTTP-rubriker. I rubriken visas tiden som den överordnade vÀrden tog pÄ sig för att behandla förfrÄgan. Detta anges i millisekunder. Det Àr anvÀndbart om klienten vill faststÀlla tid för service i förhÄllande till nÀtverksfördröjning.

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

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

Ytterligare information frÄn översÀttaren

Installationsinstruktioner för Envoy Proxy kan du hitta pÄ webbplatsen https://www.getenvoy.io/

Som standard saknar rpm systemd service-konfiguration.

LĂ€gg till systemd service-konfigurationen i \/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 behöver skapa en mapp \/etc\/envoy\/ och lÀgga konfigurationsfilen config.yaml dÀr.

Det finns en Telegram-chat för envoy proxy: https://t.me/envoyproxy_ru

Envoy Proxy har ingen stöd för att leverera statiskt innehÄll. SÄ vÀnligen rösta för funktionen: https://github.com/envoyproxy/envoy/issues/378

Endast registrerade anvÀndare kan delta i omröstningen. Logga in, tack.

Har detta inlÀgg inspirerat dig att installera och testa envoy proxy?

  • ja

  • nej

75 anvÀndare röstade för. 18 anvÀndare avstod.

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster