Migrace z Nginx na Envoy Proxy

Ahoj, Habr! Nabízím vám 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, a také funguje jako komunikační redakce a "univerzální datová vrstva", vyvinutá pro velké mikroslužbové architektury "service mesh". Při jeho vytváření byly zohledněny řešení problémů, které vznikly během vývoje takových serverů, jako jsou NGINX, HAProxy, hardwarové a cloudové vyrovnávače zatížení. Envoy pracuje s každou aplikací a abstraktizuje síť, poskytující společné funkce bez ohledu na platformu. Když veškerý provoz v infrastruktuře prochází sítí Envoy, je snadné vizualizovat problematické oblasti pomocí konzistentního sledování, ladění celkového výkonu a přidávání klíčových funkcí na konkrétních místech.

Funkce

  • Architektura mimo proces: Envoy je autonomní, vysoce výkonný server s nízkou spotřebou paměti. Spolupracuje s jakýmkoli jazykem aplikace nebo frameworkem.
  • Podpora http/2 a grpc: Envoy má prvotřídní podporu http/2 a grpc pro příchozí a odchozí spojení. Je to transparentní proxy od http/1.1 do http/2.
  • Pokročilé vyrovnávání zatížení: Envoy podporuje pokročilé funkce vyrovnávání zatížení, včetně automatických opakování, přerušení řetězce, globálního omezení rychlosti, oslabení požadavků, místního vyrovnání zatížení zóny atd.
  • API pro správu konfigurace: Envoy poskytuje spolehlivé API pro dynamické řízení své konfigurace.
  • Sledovatelnost: hluboká sledovatelnost provozu L7, integrovaná podpora pro distribuované sledování a sledování MongoDB, DynamoDB a mnoha dalších aplikací.

Krok 1 — Příklad konfigurace NGINX

V tomto scénáři se používá speciálně vytvořený soubor nginx.conf, založený na úplném příkladu z NGINX Wiki. Můžete si prohlédnout konfiguraci v editoru otevřením nginx.conf

Původní konfigurace nginx

uživatel 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 obvykle obsahují tři klíčové prvky:

  1. Nastavení serveru NGINX, struktury protokolů a funkčnosti Gzip. To je určeno globálně ve všech případech.
  2. Nastavení NGINX pro přijímání požadavků na hostitele one.example.com na portu 8080.
  3. Nastavení cílové polohy, jak zpracovávat provoz pro různé části URL.

Ne všechna konfigurace bude aplikována na Envoy Proxy, a nemusíte nastavovat některé parametry. Envoy Proxy má čtyři klíčové typy, které podporují základní infrastrukturu nabízenou NGINX. Jádro je:

  • Posluchače: Oni určují, jak Envoy Proxy přijímá příchozí požadavky. V současnosti Envoy Proxy podporuje pouze posluchače na bázi TCP. Jakmile je spojení navázáno, je předáno sadě filtrů pro zpracování.
  • Filtry: Jsou součástí architektury potrubí, která může zpracovávat příchozí a odchozí data. Tato funkčnost zahrnuje filtry, jako je Gzip, který komprimuje data před jejich odesláním klientovi.
  • Směrovače: Oni přesměrovávají provoz na požadovanou destinaci, určenou jako cluster.
  • Clustery: Oni určují koncovou bod pro provoz a konfigurační parametry.

Budeme používat tyto čtyři komponenty k vytvoření konfigurace Envoy Proxy, aby odpovídala určité konfiguraci NGINX. Cíl Envoy je práce s API a dynamická konfigurace. V tomto případě bude základní konfigurace používat statické, pevně stanovené parametry z NGINX.

Krok 2 — Konfigurace NGINX

První část nginx.conf určuje některé vnitřní komponenty NGINX, které musí být nastaveny.

Worker Connections (Pracovní spojení)

Následující konfigurace definuje počet pracovních procesů a připojení. To ukazuje, jak se NGINX bude škálovat, aby vyhověl poptávce.

worker_processes  2;

events {
  worker_connections   2000;
}

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

Envoy vytváří pracovní tok pro každé hardwarové vlákno v systému. Každý pracovní tok vykonává neblokující cyklus událostí, který má na starosti

  1. Poslech každého posluchače (listener)
  2. Přijímání nových připojení
  3. Vytváření sady filtrů pro připojení
  4. Zpracování všech operací vstupu a výstupu během existence připojení.

Veškeré další zpracování připojení je plně realizováno ve pracovním vlákně, včetně jakéhokoli přesměrovacího chování.

Pro každý pracovní tok v Envoy existuje připojení v poolu. Takové pulty připojení HTTP/2 vytvářejí pouze jedno připojení pro každý externí host, takže při čtyřech pracovních tocích budou čtyři připojení HTTP/2 pro každý externí host v ustáleném stavu. Udržováním všeho v jednom pracovním toku může být téměř veškerý kód napsán bez blokování, jako by byl jednovláknový. Pokud je pracovních toků vyčleněno více, než je potřeba, může to vést k neefektivnímu využití paměti, vytváření velkého množství neaktivních připojení a snížení počtu odpojení zpět do poolu.

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

Konfigurace HTTP

Následující blok konfigurace NGINX definuje nastavení HTTP, jako jsou:

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

Tyto aspekty můžete konfigurovat pomocí filtrů v Envoy Proxy, o čemž budeme diskutovat později.

Krok 3 — Konfigurace Serveru

V bloku konfigurace HTTP, konfigurace NGINX uvádí, že má poslouchat na portu 8080 a odpovídat na příchozí požadavky pro domény one.example.com a www.one.example.com.

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

Uvnitř Envoy se tímto řídí posluchači.

Posluchači Envoy

Nejdůležitějším aspektem zahájení práce s Envoy Proxy je definice posluchačů. Musíte vytvořit konfigurační soubor, který popisuje, jak chcete spustit instanci Envoy.

Následující úryvek vytvoří nového posluchače a propojí ho s portem 8080. Konfigurace určuje, na které porty by se měl Envoy Proxy připojit pro příchozí požadavky.

Envoy Proxy používá notaci YAML pro svou konfiguraci. Pro bližší seznámení s touto notací se podívejte sem odkaz.

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

Není nutné definovat server_name, protože s tím se vypořádají filtry Envoy Proxy.

Krok 4 — Konfigurace umístění

Když požadavek dorazí do NGINX, blok umístění určuje, jak zpracovávat a kam směrovat provoz. V následujícím úryvku je veškerý provoz na web přenesen do upstream (poznámka překladatele: upstream jsou obvykle aplikační servery) clusteru s názvem targetCluster. Upstream cluster určuje uzly, které by měly požadavek zpracovat. O tom budeme mluvit 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;
}

V Envoy se tímto zabývají filtry.

Envoy Filters

Pro statickou konfiguraci filtry určují, jak zpracovávat příchozí požadavky. V tomto případě nastavujeme filtry, které odpovídají server_names z předchozího kroku. Když přicházejí příchozí požadavky, které odpovídají určitým doménám a trasám, provoz je směrován do clusteru. To odpovídá vzestupné konfiguraci 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

Jméno envoy.http_connection_manager je vestavěný filtr v Envoy Proxy. Dalšími filtry jsou Redis, Mongo, TCP. Můžete najít úplný seznam v dokumentaci.

Pro více informací o dalších politikách vyvažování zatížení navštivte Dokumentaci Envoy.

Krok 5 — Proxy a upstream konfigurace

V NGINX konfigurace upstream určuje soubor cílových serverů, které budou zpracovávat provoz. V tomto případě byly přiřazeny dva clustery.

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

V Envoy to spravují clustry.

Envoy Clusters

Ekvivalent upstream je definován jako clustery. V tomto případě byly určeny hostitele, kteří budou zpracovávat provoz. Způsob přístupu k hostitelům, například časový limit, je definován jako konfigurace clustera. To umožňuje přesněji kontrolovat jemnost takových aspektů, jako je časový limit a vyvažování zátěže.

Copy to Editor  clustery:
  - 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í detekce služby STRICT_DNS Envoy bude nepřetržitě a asynchronně řešit uvedené cíle DNS. Každá vrácená IP adresa v důsledku DNS bude považována za explicitního hostitele ve vzestupném clusteru. To znamená, že pokud dotaz vrátí dvě IP adresy, Envoy předpokládá, že v clusteru jsou dva hostitelé, a oba musí být vyváženy. Pokud je hostitel odstraněn z výsledku, Envoy předpokládá, že už neexistuje, a bude vybírat provoz z jakýchkoli existujících spojení.

Pro více informací viz. Dokumentaci proxy serveru Envoy.

Krok 6 — Přístup k protokolu a chybám

Konečná konfigurace — registrace. Místo předávání protokolů chyb na disk, Envoy Proxy používá cloudový přístup. Všechny protokoly aplikací se vypisují do stdout a stderr.

Když uživatelé provádějí dotaz, protokoly přístupu jsou volitelné a standardně jsou vypnuté. Chcete-li povolit protokoly přístupu pro HTTP dotazy, aktivujte konfiguraci access_log pro správce připojení HTTP. Cesta může být buď zařízením, jako je stdout, nebo souborem na disku, v závislosti na vašich požadavcích.

Následující konfigurace přesměruje všechny protokoly přístupu do stdout (poznámka překladatele — stdout je nutné pro použití envoy uvnitř dockeru. Pokud to použijete bez dockeru, nahraďte /dev/stdout cestou k běžnému protokolu). Zkopírujte blok do části 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át řetězce, který zahrnuje podrobnosti HTTP dotazu:

[%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ýsledek tohoto formátu řetězce:

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

Obsah výstupu lze nakonfigurovat 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"

Řetězec protokolu může být také výstupem 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 logování Envoy navštivte

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

Zaznamenávání není jediným způsobem, jak získat přehled o provozu s Envoy Proxy. Obsahuje pokročilé funkce sledování a metrik. Můžete se dozvědět více v dokumentaci k sledování nebo prostřednictvím skenování interaktivního sledování.

Krok 7 – Spuštění

Nyní jste převedli konfiguraci z NGINX na Envoy Proxy. Posledním krokem je spustit instanci Envoy Proxy pro testování.

Spuštění jako uživatel

V horní části konfigurace NGINX je řádek user www www; který uvádí, že NGINX bude spuštěn jako uživatel s nízkými privilegii pro zvýšení bezpečnosti.

Envoy Proxy používá cloudový přístup k řízení, kdo je vlastníkem procesu. Když spouštíme Envoy Proxy prostřednictvím kontejneru, můžeme určit uživatele s nízkými privilegii.

Spuštění Envoy Proxy

Níže uvedený příkaz spustí Envoy Proxy v kontejneru Docker na hostiteli. Tento příkaz umožňuje Enovy naslouchat příchozím požadavkům na portu 80. Jak je uvedeno v konfiguraci naslouchání, Envoy Proxy naslouchá příchozímu provozu na portu 8080. Umožňuje tak procesu běžet jako uživatel s nízkými privilegii.

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

Testování

S běžícím proxy nyní mohou být provedeny a zpracovány testy. Následující příkaz cURL generuje požadavek s hlavičkou hostitele definovanou v konfiguraci proxy.

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

HTTP požadavek povede k chybě 503To bylo způsobeno tím, že příchozí připojení nefungují a nejsou dostupná. Tím pádem nemá Envoy Proxy k dispozici žádné cílové adresáty pro požadavek. Následující příkaz spustí sérii 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ě směrovat provoz na cílové místo.

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

Měli byste vidět odpověď, která ukazuje, který kontejner Docker zpracoval požadavek. V logu Envoy Proxy byste také měli vidět vytištěný řádek přístupu.

Další HTTP odpovědní hlavičky (HTTP Response)

V hlavičkách odpovědi platného požadavku uvidíte další HTTP hlavičky. V hlavičce je uveden čas, který nadřazený hostitel strávil zpracováním požadavku. Je vyjádřen v milisekundách. To je užitečné, pokud klient chce určit čas zpracování ve srovnání s latencí v síti.

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 k instalaci Envoy Proxy naleznete na webové stránce https://www.getenvoy.io/

Ve výchozím nastavení rpm chybí systémový service konfig.

Přidejte systémový service konfiguratér /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 umístit tam konfigurační soubor config.yaml.

K envoy proxy existuje telegramový chat: https://t.me/envoyproxy_ru

Envoy Proxy nemá podporu pro distribuci statického obsahu. Proto prosím hlasujte pro tuto funkci: https://github.com/envoyproxy/envoy/issues/378

Pouze registrovaní uživatelé se mohou účastnit ankety. Přihlaste se, prosím.

Přiměl vás tento příspěvek k instalaci a testování envoy proxy?

  • ano

  • ne

Hlasovalo 75 uživatelů. Zdrželo se 18 uživatelů.

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster