Envoy. 1. Úvod

Zdravím! Toto je krátky článok, ktorý odpovedá na otázky: " čo je envoy?", "na čo sa používa?" a "ako začať?".

Čo to je

Envoy je L4-L7 vyvažovač zaťaženia napísaný v C++, zameraný na vysoký výkon a dostupnosť. Z jednej strany je to akýsi ekvivalent nginx a haproxy, porovnateľný s nimi svojím výkonom. Na druhej strane, je viac zameraný na mikroservisnú architektúru a má funkčnosť, ktorá nie je horšia ako vyvažovače v jazykoch Java a Go, ako sú zuul alebo traefik.

Tabuľka porovnania haproxy/nginx/envoy, nepretenduje na absolútnu pravdu, ale poskytuje celkový obraz.

nginx
haproxy
envoy
traefik

hviezd na github
11.2k/mirror
1.1k/mirror
12.4k
27.6k

napísaný v
C
C
C++
go

API
nie
len socket/push
dataplane/pull
pull

aktívny healthcheck
nie
áno
áno
áno

Open tracing
externý plugin
nie
áno
áno

JWT
externý plugin
nie
áno
nie

Prípona
Lua/C
Lua/C
Lua/C++
nie

Prečo

Toto je mladý projekt, chýba mu mnoho vecí, niečo je v ranných alfa verziách. Ale envoy, vrátane mladej fázy, sa rýchlo vyvíja a už teraz má mnoho zaujímavých funkcií: dynamickú konfiguráciu, množstvo predpripravených filtrov, jednoduché rozhranie na písanie vlastných filtrov.
Z toho vyplývajú oblasti aplikácií, ale na začiatok 2 antipatterny:

  • Podávanie statiky.

Faktom je, že v súčasnosti v envoy neexistuje podpora caching. Tím z Google sa snaží to opraviť. Myšlienka jednorazového implementovania v na envoy všetky nuansy (zoo hlavičiek) dodržiavania RFC, a pre konkrétne implementácie vytvoriť rozhranie. Ale zatiaľ to nie je ani alfa, architektúra je v diskusii, PR otvorený (kým som písal článok, PR bol zlúčený, ale tento bod je stále aktuálny).

A zatiaľ používajte na statické súbory nginx.

  • Statická konfigurácia.

Môže sa používať, ale envoy nebol vytvorený na tento účel. Možnosti v statickej konfigurácii nebudú úplne využité. Mnoho aspektov:

Pri úprave konfigurácie v yaml sa môžete pomýliť, nadávať vývojárov za zdĺhavý popis a myslieť si, že konfigurácie nginx/haproxy, aj keď menej štruktúrované, sú stručnejšie. V tom je pointa. Konfigurácia Nginx a Haproxy bola navrhnutá na úpravy ručne, zatiaľ čo envoy bola navrhnutá na generovanie z kódu. Celá konfigurácia je popísaná v protobuf, generovanie podľa proto súborov je oveľa ťažšie na chyby.

Scenáre canary, b/g nasadenia a mnoho iného, sa normálne realizujú len v dynamickej konfigurácii. Netrvám, že to nemožno urobiť v statickej, všetko to robíme. Ale na to treba mať veľa obstdorov, v ktoromkoľvek z vyvažovačov, vrátane. envoy Okrem toho.

Úlohy, pri ktorých je Envoy nepostrádateľný:

  • Vyvažovanie prevádzky v zložitých a dynamických systémoch. Tu patrí service mesh, ale nemusí byť jediný.
  • Potrebnosť funkcie distribuovaného trasovania, zložitého oprávnenia alebo iného, ktorý je prítomný v envoy základnej výbave alebo sa pohodlne implementuje, zatiaľ čo v nginx/haproxy je potrebné sa obliecť do lua a pochybného pluginu.

Oba prístupy môžu, ak je to potrebné, zabezpečiť vysoký výkon.

Ako to funguje

Envoy sa distribuuje v binárkach iba ako docker obraz. V obraze už existuje príklad statickej konfigurácie. Ale pre nás je zaujímavý iba pre pochopenie štruktúry.

envoy.yaml statická konfigurácia

static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address:
        protocol: TCP
        address: 0.0.0.0
        port_value: 10000
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: local_service
              domains: ["*"]
              routes:
              - match:
                  prefix: "\/"
                route:
                  host_rewrite: www.google.com
                  cluster: service_google
          http_filters:
          - name: envoy.router
  clusters:
  - name: service_google
    connect_timeout: 0.25s
    type: LOGICAL_DNS
    # Odkomentujte nasledujúcu líniu, aby ste otestovali na sieti v6
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: service_google
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: www.google.com
                port_value: 443
    transport_socket:
      name: envoy.transport_sockets.tls
      typed_config:
        "@type": type.googleapis.com/envoy.api.v2.auth.UpstreamTlsContext
        sni: www.google.com

Dynamická konfigurácia

Aké problémy sa snažíme vyriešiť? Nemôžete jednoducho zobrať a reštartovať konfiguráciu vyvažovača pod záťažou, vzniknú "malé" problémy:

  • Validácia konfigurácie.

Konfigurácia môže byť veľká, môže byť veľmi veľká, ak ju preťažujeme celú naraz, šance na chyby niekde rastú.

  • Dlhodobé spojenia.

Pri inicializácii nového poslucháča je potrebné dbať na spojenia, ktoré fungujú na starom, ak sa zmeny vyskytujú často a existujú dlhodobé spojenia, bude potrebné hľadať kompromis. Ahoj, kubernetes ingress na nginx.

  • Aktívne health-checky.

Ak máme aktívne health-checky, bolo by dobré ich všetky prekontrolovať na novej konfigurácii pred tým, ako pošleme prevádzku. Ak je veľa upstreamov, zaberie to čas. Ahoj, haproxy.

Ako sa to rieši v envoy, načítaním konfigurácie dynamicky, podľa pool modelu, môže byť rozdelená na samostatné časti a nie je potrebné reinitializovať tú časť, ktorá sa nezmenila. Napríklad listener, ktorý je nákladný na reinitializáciu, sa mení len zriedka.

Konfigurácia envoy (z vyššie uvedeného súboru) má nasledujúce entity:

  • listener — listener visí na určitej ip/porte
  • virtual host — virtuálny host podľa názvu domény
  • route — pravidlo vyvažovania
  • cluster — skupina upstreamov s parametrami vyvažovania
  • endpoint — adresa inštancie upstreamu

Každú z týchto entít plus niektoré ďalšie je možné vyplniť dynamicky, na to sa v konfigurácii uvádza adresa služby, odkiaľ bude konfigurácia získaná. Služba môže byť REST alebo gRPC, uprednostňuje sa používanie gRPC.

Služby sa nazývajú zodpovedajúco: LDS, VHDS, RDS, CDS a EDS. Je možné kombinovať statickú a dynamickú konfiguráciu, s obmedzením, že dynamický zdroj nemožno uviesť v statickom.

Pre väčšinu úloh stačí implementovať posledné tri služby, nazývajú sa ADS (Aggregated Discovery Service), pre java a go existuje hotová implementácia gRPC dataplane, v ktorej stačí iba vyplniť objekty zo svojho zdroja.

Konfigurácia nadobúda nasledujúcu podobu:

envoy.yaml dynamická konfigurácia

dynamic_resources:
  ads_config:
    api_type: GRPC
    grpc_services:
      envoy_grpc:
        cluster_name: xds_clr
  cds_config:
    ads: {}
static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address:
        protocol: TCP
        address: 0.0.0.0
        port_value: 10000
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
          stat_prefix: ingress_http
          rds:
            route_config_name: local_route
            config_source:
              ads: {}
          http_filters:
          - name: envoy.router
  clusters:
  - name: xds_clr
    connect_timeout: 0.25s
    type: LOGICAL_DNS
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: xds_clr
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: xds
                port_value: 6565

Pri spustení sa zobrazuje nasledujúce: envoy s touto konfiguráciou sa pripojí k control-plane a pokúsi sa vyžiadať konfigurácie RDS, CDS a EDS. Ako prebieha proces interakcie je opísané tu.

Ak zhrniem, envoy posiela žiadosť, s uvedením typu požadovaného zdroja, verziou a parametrami uzla. V odpovedi dostane zdroj a verziu, ak sa verzia na control-plane nezmenila, neodpovedá.
Existujú 4 varianty interakcie:

  • Jeden gRPC stream pre všetky typy zdrojov, posiela sa kompletný stav zdroja.
  • Oddelené streamy, plný stav.
  • Jeden stream, inkrementálny stav.
  • Oddelené streamy, inkrementálny stav.

Inkrementálne xDS umožňuje znížiť prevádzku medzi control-plane a envoy, je to relevantné pre veľké konfigurácie. Ale zložitosti interakcie, v požiadavke sa odosiela zoznam zdrojov na odhlásenie a prihlásenie.

V našom príklade sa používa ADS — jeden stream pre RDS, CDS, EDS a nie inkrementálny režim. Pre aktiváciu inkrementálneho režimu je potrebné zadať api_type: DELTA_GRPC

Keďže v požiadavke sú parametre uzla, môžeme na control-plane posielať rôzne zdroje pre rôzne inštancie envoy, to je praktické pre budovanie service mesh.

Warmup

Na envoy pri spustení alebo po získaní novej konfigurácie od control-plane sa spúšťa proces warmup zdrojov. Je rozdelený na warmup listenera a warmup clusteru. Prvý sa spúšťa pri zmenách v RDS/LDS, druhý pri CDS/EDS. To znamená, že ak sa menia len upstreamy, listener sa neprebuduje.

V priebehu warmupu sa očakávajú závislé zdroje od control-plane počas timeoutu. Ak timeout uplynul a inicializácia nebude úspešná, nový listener nezačne počúvať port.
Poradie inicializácie: EDS, CDS, aktívny health check, RDS, LDS. Pri zapnutých aktívnych health checkoch, prevádzka pôjde na upstream, až po jednom úspešnom health checku.

Ak bol listener znovu vytvorený, starý prechádza do stavu DRAIN a bude odstránený po uzavretí všetkých spojení alebo uplynutí timeoutu --drain-time-s, predvolene 10 minút.

Pokračovanie nasleduje.

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster