Migrace z Nginx na Envoy Proxy

Dobrý den, Habr! Upozorňuji na překlad příspěvku: Migrace z Nginx na Envoy Proxy.

Envoy je vysoce výkonný distribuovaný proxy server (napsaný v C++) určený pro jednotlivé služby a aplikace, dále je to komunikační sběrnice a „univerzální datová rovina“ určená pro rozsáhlé architektury „service mesh“ mikroslužeb. Při jeho tvorbě byla zohledněna řešení problémů, které vznikly při vývoji serverů jako NGINX, HAProxy, hardwarové load balancery a cloud load balancery. Envoy pracuje vedle každé aplikace a abstrahuje síť, aby poskytoval společné funkce bez ohledu na platformu. Když veškerý provoz služeb v infrastruktuře prochází sítí Envoy, je snadné vizualizovat problémové oblasti s konzistentní pozorovatelností, vyladit celkový výkon a přidat základní funkce na konkrétním místě.

Možnosti

  • Architektura mimo proces: envoy je samostatný, vysoce výkonný server, který zabírá malé množství paměti RAM. Funguje ve spojení s jakýmkoliv aplikačním jazykem nebo frameworkem.
  • Podpora http/2 a grpc: envoy má prvotřídní podporu http/2 a grpc pro příchozí a odchozí připojení. Toto je transparentní proxy z http/1.1 na http/2.
  • Pokročilé vyvažování zátěže: Envoy podporuje pokročilé funkce vyvažování zátěže včetně automatického opakování, přerušení řetězu, globálního omezení rychlosti, stínování požadavků, vyrovnávání zátěže lokální zóny atd.
  • Configuration Management API: Envoy poskytuje robustní API pro dynamickou správu vaší konfigurace.
  • Pozorovatelnost: Hluboká pozorovatelnost provozu L7, nativní podpora distribuovaného trasování a pozorovatelnost mongodb, dynamodb a mnoha dalších aplikací.

Krok 1 — Příklad NGINX Config

Tento skript používá speciálně vytvořený soubor nginx.conf, na základě úplného příkladu z Wiki NGINX. Konfiguraci si můžete prohlédnout v editoru otevřením nginx.conf

zdrojová konfigurace 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;
    }
  }
}

Konfigurace NGINX mají obvykle tři klíčové prvky:

  1. Konfigurace serveru NGINX, struktura protokolu a funkce Gzip. To je definováno globálně ve všech případech.
  2. Konfigurace NGINX pro přijímání požadavků na hostitele one.example.com na portu 8080.
  3. Nastavení cílového umístění, jak zvládnout provoz pro různé části URL.

Ne všechny konfigurace se budou vztahovat na Envoy Proxy a některá nastavení konfigurovat nemusíte. Envoy Proxy má čtyři typy klíčů, které podporují základní infrastrukturu nabízenou NGINX. Jádro je:

  • Posluchači: Určují, jak Envoy Proxy přijímá příchozí požadavky. Envoy Proxy aktuálně podporuje pouze posluchače založené na TCP. Jakmile je spojení navázáno, je předáno sadě filtrů ke zpracování.
  • Filtry: Jsou součástí architektury potrubí, která dokáže zpracovávat příchozí a odchozí data. Tato funkce zahrnuje filtry, jako je Gzip, který komprimuje data před jejich odesláním klientovi.
  • Směrovače: Přesměrují provoz do požadovaného cíle definovaného jako cluster.
  • Shluky: Definují koncový bod pro provoz a konfigurační parametry.

Tyto čtyři komponenty použijeme k vytvoření konfigurace Envoy Proxy, která bude odpovídat konkrétní konfiguraci NGINX. Cílem Envoy je práce s API a dynamickou konfigurací. V tomto případě bude základní konfigurace používat statická, pevně zakódovaná nastavení z NGINX.

Krok 2 – Konfigurace NGINX

První část nginx.conf definuje některé interní prvky NGINX, které je třeba nakonfigurovat.

Pracovní připojení

Níže uvedená konfigurace určuje počet pracovních procesů a připojení. To ukazuje, jak se bude NGINX přizpůsobovat poptávce.

worker_processes  2;

events {
  worker_connections   2000;
}

Envoy Proxy spravuje pracovní postupy a připojení různými způsoby.

Envoy vytvoří pracovní vlákno pro každé hardwarové vlákno v systému. Každé pracovní vlákno spustí neblokující smyčku událostí, která je zodpovědná

  1. Naslouchání každému posluchači
  2. Přijímání nových spojení
  3. Vytvoření sady filtrů pro připojení
  4. Zpracujte všechny I/O operace během životnosti připojení.

Veškeré další zpracování připojení je řešeno výhradně v pracovním vláknu, včetně jakéhokoli chování při předávání.

Pro každé pracovní vlákno v Envoy existuje fond připojení. Fondy připojení HTTP/2 tedy navazují pouze jedno připojení na externího hostitele najednou, pokud existují čtyři pracovní vlákna, budou ve stabilním stavu čtyři připojení HTTP/2 na externího hostitele. Udržením všeho v jednom pracovním vláknu lze téměř veškerý kód zapsat bez blokování, jako by byl jednovláknový. Pokud je přiděleno více pracovních vláken, než je nutné, může to vést k plýtvání pamětí, vytváření velkého počtu nečinných připojení a snížení počtu připojení vracených zpět do fondu.

Pro více informací navštivte Blog Envoy Proxy.

Konfigurace HTTP

Následující konfigurační blok NGINX definuje nastavení HTTP, jako například:

  • Jaké typy mime jsou podporovány
  • Výchozí časové limity
  • Konfigurace Gzip

Tyto aspekty si můžete přizpůsobit pomocí filtrů v Envoy Proxy, o kterých si povíme později.

Krok 3 – Konfigurace serveru

V konfiguračním bloku HTTP konfigurace NGINX určuje, že má naslouchat na portu 8080 a reagovat na příchozí požadavky na domény one.example.com и www.one.example.com.

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

Uvnitř Envoy ji ovládají posluchači.

Vyslanci posluchači

Nejdůležitějším aspektem, jak začít s Envoy Proxy, je definovat své posluchače. Musíte vytvořit konfigurační soubor, který popisuje, jak chcete spustit instanci Envoy.

Níže uvedený úryvek vytvoří nový posluchač a připojí jej k portu 8080. Konfigurace říká Envoy Proxy, na které porty se má vázat pro příchozí požadavky.

Envoy Proxy používá pro svou konfiguraci notaci YAML. Úvod do tohoto zápisu naleznete zde odkaz.

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

Není třeba definovat název_serveru, protože to zvládnou filtry Envoy Proxy.

Krok 4 – Konfigurace umístění

Když požadavek přijde do NGINX, blok umístění určuje, jak zpracovat a kam směrovat provoz. V následujícím fragmentu je veškerý provoz na webu přenesen do upstreamu (poznámka překladatele: upstream je obvykle aplikační server) clusteru s názvem targetCluster. Upstream cluster definuje uzly, které by měly zpracovat požadavek. Probereme to v dalším kroku.

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

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

Ve společnosti Envoy to dělá Filters.

Filtry vyslanců

U statické konfigurace určují filtry, jak zpracovat příchozí požadavky. V tomto případě nastavíme filtry, které se shodují názvy_serverů v předchozím kroku. Když dorazí příchozí požadavky, které odpovídají určitým doménám a trasám, je provoz směrován do clusteru. Toto je ekvivalent konfigurace NGINX zdola nahoru.

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ázev vyslanec.http_connection_manager je vestavěný filtr v Envoy Proxy. Mezi další filtry patří Redestilát, Mongo, TCP. Kompletní seznam najdete na dokumentace.

Další informace o dalších zásadách vyrovnávání zátěže naleznete na adrese Dokumentace vyslance.

Krok 5 – Konfigurace proxy a Upstream

V NGINX definuje upstream konfigurace sadu cílových serverů, které budou zpracovávat provoz. V tomto případě byly přiřazeny dva shluky.

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

V Envoy je to řízeno clustery.

Shluky vyslanců

Upstream ekvivalent je definován jako shluky. V tomto případě byli identifikováni hostitelé, kteří budou provoz obsluhovat. Způsob přístupu k hostitelům, jako jsou časové limity, je definován jako konfigurace clusteru. To umožňuje podrobnější kontrolu nad aspekty, jako je latence a vyrovnávání zátěž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 }}
    ]

Při použití zjišťování služeb STRICT_DNS Envoy bude průběžně a asynchronně řešit zadané cíle DNS. Každá vrácená IP adresa z výsledku DNS bude považována za explicitního hostitele v upstreamovém clusteru. To znamená, že pokud požadavek vrátí dvě IP adresy, Envoy bude předpokládat, že v clusteru jsou dva hostitelé a oba musí být vyváženi zatížením. Pokud je hostitel z výsledku odebrán, Envoy bude předpokládat, že již neexistuje, a bude stahovat provoz ze všech existujících fondů připojení.

Další informace viz Dokumentace k zmocněnci.

Krok 6 — Log Access and Errors

Poslední konfigurací je registrace. Místo odesílání chybových protokolů na disk využívá Envoy Proxy cloudový přístup. Všechny aplikační protokoly se vypisují do stdout и stderr.

Když uživatelé zadají požadavek, protokoly přístupu jsou volitelné a ve výchozím nastavení jsou zakázány. Chcete-li povolit protokoly přístupu pro požadavky HTTP, povolte konfiguraci přístupový_log pro správce připojení HTTP. Cestou může být buď zařízení jako např stdout, nebo soubor na disku, v závislosti na vašich požadavcích.

Následující konfigurace přesměruje všechny přístupové protokoly na stdout (poznámka překladatele - pro použití envoy uvnitř dockeru je vyžadován stdout. Pokud je použit bez dockeru, nahraďte /dev/stdout cestou k běžnému souboru protokolu). Zkopírujte úryvek do sekce konfigurace pro správce připojení:

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

Výsledky by měly vypadat 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:

Ve výchozím nastavení má Envoy formátovací řetězec, který obsahuje podrobnosti požadavku HTTP:

[%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ýsledkem tohoto formátovacího řetězce 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 lze upravit nastavením pole formátu. Napří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"

Řádek protokolu lze také nastavit na výstup ve formátu JSON nastavením pole json_format. Například:

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

Pro více informací o Metodice registrace vyslanců navštivte

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

Protokolování není jediný způsob, jak získat přehled o práci s Envoy Proxy. Má v sobě zabudované pokročilé možnosti sledování a metrik. Více se můžete dozvědět na trasovací dokumentace nebo přes Interaktivní sledovací skript.

Krok 7 – Spuštění

Nyní jste migrovali svou konfiguraci z NGINX na Envoy Proxy. Posledním krokem je spuštění instance Envoy Proxy za účelem jejího otestování.

Spustit jako uživatel

Na vrcholu konfigurační řady NGINX uživatel www www; určuje spuštění NGINX jako nízkoprivilegovaného uživatele pro zlepšení zabezpečení.

Envoy Proxy využívá cloudový přístup ke správě toho, kdo vlastní proces. Když spustíme Envoy Proxy prostřednictvím kontejneru, můžeme zadat uživatele s nízkým oprávněním.

Spuštění Envoy Proxy

Níže uvedený příkaz spustí Envoy Proxy prostřednictvím kontejneru Docker na hostiteli. Tento příkaz dává Envoy schopnost naslouchat příchozím požadavkům na portu 80. Jak je však uvedeno v konfiguraci listeneru, Envoy Proxy naslouchá příchozímu provozu na portu 8080. To umožňuje, aby proces běžel jako uživatel s nízkými oprávněními.

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

Testování

Se spuštěným proxy lze nyní provádět a zpracovávat testy. Následující příkaz cURL vydá požadavek s hlavičkou hostitele definovanou v konfiguraci serveru proxy.

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

Požadavek HTTP bude mít za následek chybu 503. Důvodem je, že proti proudu připojení nefungují a nejsou k dispozici. Envoy Proxy proto nemá žádné dostupné cíle pro požadavek. Následující příkaz spustí řadu HTTP služeb, které odpovídají konfiguraci definované pro Envoy.

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

S dostupnými službami může Envoy úspěšně proxy provozovat do svého cíle.

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

Měli byste vidět odpověď označující, který kontejner Docker požadavek zpracoval. V protokolech Envoy Proxy byste také měli vidět výstup přístupového řetězce.

Další záhlaví odezvy HTTP

V záhlavích odpovědí skutečného požadavku uvidíte další záhlaví HTTP. Záhlaví zobrazuje čas, který upstream hostitel strávil zpracováním požadavku. Vyjádřeno v milisekundách. To je užitečné, pokud chce klient určit dobu služby ve srovnání s latencí sítě.

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

Konečná konfigurace

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 }

Další informace od překladatele

Pokyny pro instalaci Envoy Proxy naleznete na webu https://www.getenvoy.io/

Ve výchozím nastavení rpm nemá konfiguraci služby systemd.

Přidejte konfiguraci 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 vytvořit adresář /etc/envoy/ a vložit tam konfiguraci config.yaml.

Existuje telegramový chat pomocí zástupce proxy: https://t.me/envoyproxy_ru

Envoy Proxy nepodporuje poskytování statického obsahu. Kdo tedy může pro funkci hlasovat: https://github.com/envoyproxy/envoy/issues/378

Průzkumu se mohou zúčastnit pouze registrovaní uživatelé. Přihlásit se, prosím.

Vyzval vás tento příspěvek k instalaci a testování proxy serveru?

  • ano

  • ne

Hlasovalo 75 uživatelů. 18 uživatelů se zdrželo hlasování.

Zdroj: www.habr.com

Přidat komentář