Migrácia z Nginx na Envoy Proxy

Ahoj Habr! Dávam do pozornosti preklad príspevku: Migrácia z Nginx na Envoy Proxy.

Envoy je vysokovýkonný distribuovaný proxy server (napísaný v C++) určený pre jednotlivé služby a aplikácie, je to tiež komunikačná zbernica a „univerzálna dátová rovina“ určená pre veľké mikroservisné architektúry „service mesh“. Pri jeho vytváraní sa brali do úvahy riešenia problémov, ktoré vznikli pri vývoji serverov ako NGINX, HAProxy, hardwarové load balancery a cloud load balancery. Envoy pracuje spolu s každou aplikáciou a abstrahuje sieť, aby poskytoval spoločné funkcie bez ohľadu na platformu. Keď všetka prevádzka služieb v infraštruktúre prúdi cez sieť Envoy, je ľahké vizualizovať problémové oblasti s konzistentnou pozorovateľnosťou, vyladiť celkový výkon a pridať základné funkcie na konkrétnom mieste.

Možnosti

  • Architektúra mimo procesu: envoy je samostatný, vysokovýkonný server, ktorý zaberá malé množstvo pamäte RAM. Funguje v spojení s akýmkoľvek aplikačným jazykom alebo rámcom.
  • Podpora http/2 a grpc: envoy má prvotriednu podporu http/2 a grpc pre prichádzajúce a odchádzajúce pripojenia. Toto je transparentný proxy z http/1.1 na http/2.
  • Pokročilé vyvažovanie záťaže: Envoy podporuje pokročilé funkcie vyvažovania záťaže vrátane automatického opakovania, prerušenia reťaze, globálneho obmedzenia rýchlosti, tieňovania požiadaviek, vyrovnávania záťaže lokálnej zóny atď.
  • Configuration Management API: Envoy poskytuje robustné API pre dynamickú správu vašej konfigurácie.
  • Pozorovateľnosť: Hlboká pozorovateľnosť prevádzky L7, natívna podpora pre distribuované sledovanie a pozorovateľnosť mongodb, dynamodb a mnohých ďalších aplikácií.

Krok 1 — Príklad NGINX Config

Tento skript používa špeciálne vytvorený súbor nginx.conf, na základe úplného príkladu z Wiki NGINX. Konfiguráciu si môžete pozrieť v editore otvorením nginx.conf

konfigurácia zdroja nginx

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

Konfigurácie NGINX majú zvyčajne tri kľúčové prvky:

  1. Konfigurácia servera NGINX, štruktúra protokolu a funkčnosť Gzip. Toto je definované globálne vo všetkých prípadoch.
  2. Konfigurácia NGINX na prijímanie požiadaviek hostiteľovi one.example.com na porte 8080.
  3. Nastavenie cieľového umiestnenia, ako zvládnuť návštevnosť pre rôzne časti adresy URL.

Nie všetky konfigurácie sa budú vzťahovať na Envoy Proxy a nemusíte konfigurovať niektoré nastavenia. Envoy Proxy má štyri typy kľúčov, ktoré podporujú základnú infraštruktúru ponúkanú NGINX. Jadrom je:

  • Poslucháči: Určujú, ako Envoy Proxy prijíma prichádzajúce požiadavky. Envoy Proxy v súčasnosti podporuje iba poslucháčov na báze TCP. Po nadviazaní spojenia sa odovzdá skupine filtrov na spracovanie.
  • Filtre: Sú súčasťou pipeline architektúry, ktorá dokáže spracovať prichádzajúce a odchádzajúce údaje. Táto funkcia zahŕňa filtre, ako je Gzip, ktorý komprimuje údaje pred ich odoslaním klientovi.
  • Smerovače: Preposielajú prevádzku do požadovaného cieľa, definovaného ako klaster.
  • Klastre: Definujú koncový bod pre prenos a konfiguračné parametre.

Tieto štyri komponenty použijeme na vytvorenie konfigurácie Envoy Proxy, ktorá bude zodpovedať konkrétnej konfigurácii NGINX. Cieľom Envoy je pracovať s API a dynamickou konfiguráciou. V tomto prípade bude základná konfigurácia používať statické, pevne zakódované nastavenia z NGINX.

Krok 2 – Konfigurácia NGINX

Prvá časť nginx.conf definuje niektoré interné prvky NGINX, ktoré je potrebné nakonfigurovať.

Pripojenie pracovníkov

Konfigurácia uvedená nižšie určuje počet pracovných procesov a pripojení. To naznačuje, ako sa NGINX prispôsobí dopytu.

worker_processes  2;

events {
  worker_connections   2000;
}

Envoy Proxy spravuje pracovné toky a pripojenia rôznymi spôsobmi.

Envoy vytvorí pracovné vlákno pre každé hardvérové ​​vlákno v systéme. Každé pracovné vlákno vykoná neblokujúcu slučku udalostí, za ktorú je zodpovedné

  1. Počúvanie každého poslucháča
  2. Prijímanie nových spojení
  3. Vytvorenie sady filtrov pre pripojenie
  4. Spracujte všetky I/O operácie počas životnosti pripojenia.

Všetko ďalšie spracovanie pripojenia je spracované výlučne v pracovnom vlákne, vrátane akéhokoľvek správania pri preposielaní.

Pre každé pracovné vlákno v Envoy existuje fond pripojení. Takže oblasti pripojení HTTP/2 vytvárajú naraz iba jedno pripojenie na externého hostiteľa, ak existujú štyri pracovné vlákna, na externého hostiteľa budú v stabilnom stave štyri pripojenia HTTP/2. Udržiavaním všetkého v jednom pracovnom vlákne možno takmer celý kód napísať bez blokovania, ako keby bol jednovláknový. Ak je alokovaných viac pracovných vlákien, ako je potrebné, môže to viesť k plytvaniu pamäťou, vytváraniu veľkého počtu nečinných pripojení a zníženiu počtu pripojení vrátených späť do oblasti.

Pre viac informácií navštívte Blog Envoy Proxy.

Konfigurácia HTTP

Nasledujúci konfiguračný blok NGINX definuje nastavenia HTTP, ako napríklad:

  • Aké typy mime sú podporované
  • Predvolené časové limity
  • Konfigurácia Gzip

Tieto aspekty si môžete prispôsobiť pomocou filtrov v Envoy Proxy, o ktorých budeme diskutovať neskôr.

Krok 3 - Konfigurácia servera

V konfiguračnom bloku HTTP konfigurácia NGINX špecifikuje počúvať na porte 8080 a odpovedať na prichádzajúce požiadavky na domény one.example.com и www.one.example.com.

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

Vo vnútri Envoy ho ovládajú poslucháči.

Vyslanec poslucháčov

Najdôležitejším aspektom, ako začať s Envoy Proxy, je definovanie vašich poslucháčov. Musíte vytvoriť konfiguračný súbor, ktorý popisuje, ako chcete spustiť inštanciu Envoy.

Úryvok nižšie vytvorí nový poslucháč a naviaže ho na port 8080. Konfigurácia povie Envoy Proxy, na ktoré porty sa má viazať pre prichádzajúce požiadavky.

Envoy Proxy používa na svoju konfiguráciu notáciu YAML. Úvod do tohto zápisu nájdete tu odkaz.

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

Netreba definovať názov servera, pretože to zvládnu filtre Envoy Proxy.

Krok 4 – Konfigurácia polohy

Keď do NGINX príde požiadavka, blok umiestnenia určuje, ako sa má spracovať a kam smerovať prenos. V nasledujúcom fragmente je všetka prevádzka na lokalite prenesená do upstreamu (poznámka prekladateľa: upstream je zvyčajne aplikačný server) klastra s názvom targetCluster. Upstream klaster definuje uzly, ktoré by mali spracovať požiadavku. Budeme o tom diskutovať v ďalšom kroku.

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

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

V Envoy to robí Filters.

Filtre vyslancov

V prípade statickej konfigurácie určujú filtre spôsob spracovania prichádzajúcich požiadaviek. V tomto prípade nastavíme filtre, ktoré sa zhodujú názvy_serverov v predchádzajúcom kroku. Keď prichádzajú prichádzajúce požiadavky, ktoré zodpovedajú určitým doménam a trasám, prevádzka je smerovaná do klastra. Toto je ekvivalent konfigurácie NGINX zdola nahor.

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

názov vyslanec.http_connection_manager je vstavaný filter v Envoy Proxy. Medzi ďalšie filtre patrí Redis, mongo, TCP. Kompletný zoznam nájdete na dokumentáciu.

Ďalšie informácie o ďalších zásadách vyvažovania záťaže nájdete na stránke Dokumentácia vyslanca.

Krok 5 - Konfigurácia proxy a upstream

V NGINX konfigurácia upstream definuje množinu cieľových serverov, ktoré budú spracovávať prevádzku. V tomto prípade boli priradené dva klastre.

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

V Envoy to riadia klastre.

Zhluky vyslancov

Upstream ekvivalent je definovaný ako klastre. V tomto prípade boli identifikovaní hostitelia, ktorí budú obsluhovať prevádzku. Spôsob, akým sa pristupuje k hostiteľom, ako sú časové limity, je definovaný ako konfigurácia klastra. To umožňuje podrobnejšiu kontrolu nad aspektmi, ako je latencia a vyrovnávanie záťaže.

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

Pri použití zisťovania služby STRICT_DNS Envoy bude nepretržite a asynchrónne riešiť zadané ciele DNS. Každá vrátená IP adresa z výsledku DNS sa bude považovať za explicitného hostiteľa v upstreamovom klastri. To znamená, že ak požiadavka vráti dve adresy IP, Envoy bude predpokladať, že v klastri sú dvaja hostitelia a obaja musia byť vyvážení záťažou. Ak je hostiteľ odstránený z výsledku, Envoy bude predpokladať, že už neexistuje a stiahne prenos z akýchkoľvek existujúcich oblastí pripojení.

Viac informácií nájdete na Dokumentácia splnomocnenca.

Krok 6 — Log Access and Errors

Poslednou konfiguráciou je registrácia. Namiesto odosielania protokolov chýb na disk využíva Envoy Proxy cloudový prístup. Všetky denníky aplikácií sa vypisujú do stdout и stderr.

Keď používatelia zadajú požiadavku, denníky prístupu sú voliteľné a predvolene sú zakázané. Ak chcete povoliť protokoly prístupu pre požiadavky HTTP, povoľte konfiguráciu access_log pre správcu pripojenia HTTP. Cestou môže byť buď zariadenie ako napr stdout, alebo súbor na disku, v závislosti od vašich požiadaviek.

Nasledujúca konfigurácia presmeruje všetky prístupové denníky na stdout (poznámka prekladateľa - stdout je potrebný na použitie envoy vnútri dockeru. Ak sa používa bez dockeru, nahraďte /dev/stdout cestou k bežnému log súboru). Skopírujte útržok do sekcie konfigurácie pre správcu pripojenia:

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

Výsledky by mali vyzerať takto:

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

V predvolenom nastavení má Envoy formátovací reťazec, ktorý obsahuje podrobnosti o HTTP požiadavke:

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

Výsledkom tohto formátovacieho reťazca je:

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

Výstupný obsah je možné prispôsobiť nastavením poľa formátu. Napríklad:

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"

Záznamový riadok môže byť tiež zobrazený vo formáte JSON nastavením poľa json_format, Napríklad:

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

Viac informácií o Metodike registrácie vyslancov nájdete na

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

Logovanie nie je jediný spôsob, ako získať prehľad o práci s Envoy Proxy. Má v sebe zabudované pokročilé funkcie sledovania a metrík. Viac sa dozviete na sledovacia dokumentácia alebo cez Interaktívny sledovací skript.

Krok 7 - Spustenie

Teraz ste migrovali svoju konfiguráciu z NGINX na Envoy Proxy. Posledným krokom je spustenie inštancie Envoy Proxy na jej otestovanie.

Spustiť ako používateľ

Na vrchole konfiguračného radu NGINX užívateľ www www; určuje, aby sa NGINX spúšťal ako používateľ s nízkymi právami, aby sa zlepšila bezpečnosť.

Envoy Proxy využíva cloudový prístup k správe toho, kto vlastní proces. Keď spustíme Envoy Proxy cez kontajner, môžeme určiť nízkoprivilegovaného používateľa.

Spustenie Envoy Proxy

Príkaz nižšie spustí Envoy Proxy cez kontajner Docker na hostiteľovi. Tento príkaz dáva Envoyovi možnosť počúvať prichádzajúce požiadavky na porte 80. Ako je však špecifikované v konfigurácii načúvača, Envoy Proxy počúva prichádzajúcu prevádzku na porte 8080. To umožňuje procesu bežať ako nízkoprivilegovaný používateľ.

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

Testovanie

So spusteným serverom proxy je teraz možné vykonávať a spracovávať testy. Nasledujúci príkaz cURL vydá požiadavku s hlavičkou hostiteľa definovanou v konfigurácii servera proxy.

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

Požiadavka HTTP bude mať za následok chybu 503. Je to preto, že upstream pripojenia nefungujú a nie sú dostupné. Envoy Proxy preto nemá žiadne dostupné miesta určenia pre požiadavku. Nasledujúci príkaz spustí sériu HTTP služieb, ktoré zodpovedajú konfigurácii definovanej pre Envoy.

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

S dostupnými službami môže Envoy úspešne proxy prevádzkovať do svojho cieľa.

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

Mali by ste vidieť odpoveď označujúcu, ktorý kontajner Docker spracoval požiadavku. V protokoloch Envoy Proxy by ste mali vidieť aj výstup prístupového reťazca.

Ďalšie hlavičky odpovede HTTP

V hlavičkách odpovede skutočnej požiadavky uvidíte ďalšie hlavičky HTTP. Hlavička zobrazuje čas, ktorý upstream hostiteľ strávil spracovaním požiadavky. Vyjadrené v milisekundách. To je užitočné, ak chce klient určiť čas služby v porovnaní s latenciou siete.

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

Finálna konfigurácia

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 }

Ďalšie informácie od prekladateľa

Pokyny na inštaláciu Envoy Proxy nájdete na webovej stránke https://www.getenvoy.io/

V predvolenom nastavení rpm nemá konfiguráciu služby systemd.

Pridajte konfiguráciu služby systemd /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

Musíte vytvoriť adresár /etc/envoy/ a umiestniť tam konfiguráciu config.yaml.

Existuje telegramový rozhovor pomocou proxy servera: https://t.me/envoyproxy_ru

Envoy Proxy nepodporuje poskytovanie statického obsahu. Kto teda môže hlasovať za funkciu: https://github.com/envoyproxy/envoy/issues/378

Do prieskumu sa môžu zapojiť iba registrovaní užívatelia. Prihlásiť saProsím.

Nabádal vás tento príspevok na inštaláciu a testovanie servera proxy?

  • áno

  • nie

Hlasovalo 75 užívateľov. 18 užívateľov sa zdržalo hlasovania.

Zdroj: hab.com

Pridať komentár