Envoy. 1. Bevezetés

Üdvözlöm! Ez egy rövid cikk, amely válaszol a kérdésekre: "Mi az az envoy?", "Miért van szüksége rá?" és "Honnan kezdjük?".

Mi ez

Az Envoy egy L4-L7 terheléselosztó, amely C++ nyelven készült, a magas teljesítmény és elérhetőség érdekében. Egyrészt egyfajta analógja a nginx-nek és a haproxy-nak, teljesítményben velük összehasonlítható. Másrészt inkább a mikroservices architektúrára összpontosít, és nem kevésbé fejlett funkciókat kínál, mint a Java és Go alapú terheléselosztók, mint a zuul vagy a traefik.

A haproxy/nginx/envoy összehasonlító táblázata, nem állítja, hogy abszolút igazságot közvetít, de általános képet ad.

nginx
haproxy
envoy
traefik

csillag a github-on
11.2k/mirror
1.1k/mirror
12.4k
27.6k

nyelvek
C
C
C++
go

API
nem
csak socket/push
dataplane/pull
pull

aktív egészség-ellenőrzés
nem
igen
igen
igen

Open tracing
külső plugin
nem
igen
igen

JWT
külső plugin
nem
igen
nem

Kiterjesztés
Lua/C
Lua/C
Lua/C++
nem

Miért

Ez egy fiatal projekt, sok minden hiányzik, egyes dolgok korai alpha fázisban vannak. De envoy, többek között a fiataljából fakadóan, gyorsan fejlődik és már most rengeteg érdekes lehetőséggel rendelkezik: dinamikus konfiguráció, sok kész szűrő, egyszerű felület saját szűrők írásához.
Ebből következik a felhasználási területek, de először két antipattern:

  • Statikus tartalom kiszolgálása.

Az a helyzet, hogy jelenleg envoy nincs támogatás a gyorsítótárazáshoz. A google-es fiúk próbálják ezt javítani. Az ötlet egyszer implementálni a envoy minden finomságban (header zoo) való megfelelést az RFC-nek, és az egyes implementációkhoz interfészt készíteni. De jelenleg ez még nem alpha, az architektúra tárgyalás alatt áll, PR nyitott (míg ezt a cikket írtam, merge-elésre került, de ez a pont még mindig aktuális).

Addig is használja a statikus tartalomhoz a nginx-et.

  • Statikus konfiguráció.

Használható, de envoy nem erre lett tervezve. A statikus konfiguráció lehetőségei nem fognak megvalósulni. Sok pont van:

A yaml konfiguráció szerkesztése során hibázni fog, káromkodni fog a fejlesztőkre a szószátyárság miatt, és azt fogja gondolni, hogy a nginx/haproxy konfigurációk, bár kevésbé strukturáltak, de tömörebbek. Ez a lényeg. A nginx és a haproxy konfigurációját kézi szerkesztésre tervezték, míg az envoy kód alapján történő generálásra. Az összes konfiguráció a protobuf, protokol fájlok alapján generálva sokkal nehezebb hibázni.

A kanári, b/g telepítési forgatókönyvek és sok más dolog normálisan csak dinamikus konfigurációban valósulnak meg. Nem mondom, hogy ezt statikusan nem lehet megcsinálni, mi mindezt csináljuk. De ehhez szükség van kényszermegoldásokra, bármelyik terheléselosztónál, envoy azt is beleértve.

Feladatok, amelyekben az Envoy pótolhatatlan:

  • Forgalomelosztás bonyolult és dinamikus rendszerekben. Ide tartozik a service mesh, de nem kizárólag ez.
  • A szükségessége a elosztott nyomkövetés, bonyolult engedélyezés vagy más funkciók, amelyek már léteznek envoy do-it-yourself módon, a nginx/haproxy esetében lua-ra és kétes pluginokra van szükség.

Mindkettőt szükség esetén magas teljesítmény biztosítása érdekében.

Hogyan működik ez

Az Envoy csak docker image-ként terjesztett binárisokban elérhető. Az image-ben már van egy példa statikus konfiguráció. De számunkra csak a struktúra megértéséhez érdekes.

envoy.yaml statikus konfiguráció

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
    # Comment out the following line to test on v6 networks
    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

Dinamikus konfiguráció

Milyen problémára keresünk megoldást? Nem lehet csak úgy újraindítani a terhelés alatt lévő konfigurációt, "kisebb" problémák merülnek fel:

  • A konfiguráció validálása.

A konfiguráció lehet nagy, akár nagyon nagy, és ha egyszerre próbáljuk újraindítani, nő a hibák esélye.

  • Hosszú élettartamú kapcsolatok.

Új hallgató inicializálásakor figyelembe kell venni a régi kapcsolatok működését, ha a változások gyakoriak, és hosszú távú kapcsolatok vannak, kompromisszumot kell keresni. Helló, kubernetes ingress nginx-en.

  • Aktív egészségügyi ellenőrzések.

Ha aktív egészségügyi ellenőrzéseink vannak, mindet újra kell ellenőrizni az új konfiguráción, mielőtt forgalmat küldenénk. Ha sok upstream van, ez időt igényel. Helló, haproxy.

Hogyan oldják ezt meg a envoy, dinamikusan betöltve a konfigurációt, a pool modell szerint, külön részekre is osztható és nem kell újra inicializálni azt a részt, amely nem változott. Például a new listener, amelynek az újrainicializálása költséges, és ritkán változik.

Konfiguráció envoy (az előző fájlból) a következő entitásokat tartalmazza:

  • listener — a megadott ip/címreportot figyelő listener
  • virtual host — virtuális host a domain név alapján
  • route — terheléselosztási szabály
  • cluster — upstreamok csoportja terheléselosztási paraméterekkel
  • endpoint — az upstream példány címe

Ezeket az entitásokat, plusz néhány mást, dinamikusan lehet kitölteni, ehhez a konfigurációban meg kell adni a szolgáltatás címét, ahonnan a konfigurációt be fogják szerezni. A szolgáltatás lehet REST vagy gRPC, preferálva a gRPC használata.

A szolgáltatásokat a következőképpen hívják: LDS, VHDS, RDS, CDS és EDS. Lehet kombinálni statikus és dinamikus konfigurációt, azzal a megszorítással, hogy a dinamikus erőforrást nem lehet statikusként megadni.

A legtöbb feladathoz elegendő a három utolsó szolgáltatás megvalósítása, ezeket ADS-nek (Aggregated Discovery Service) nevezik, java és a Go-hoz létezik egy kész gRPC dataplane implementáció, amelyhez elég csak kitölteni a saját forrásaiból származó objektumokat.

A konfiguráció a következő képet ölt:

envoy.yaml dinamikus konfiguráció

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

A futtatáskor envoy ezzel a konfigurációval csatlakozik a control-plane-hez, és megpróbálja kérni az RDS, CDS és EDS konfigurációt. Az interakció folyamata a következők szerint zajlik itt.

Röviden, envoy kérdést küld, megadva a kért erőforrás típusát, a verziót és a node paramétereit. Válaszként megkapja az erőforrást és a verziót, ha a control-plane verziója nem változott, nem válaszol.
N négy lehetőség van az interakcióra:

  • Egy gRPC stream minden típusú erőforrásra, az erőforrás teljes állapotát küldi.
  • Külön streamek, teljes állapot.
  • Egy stream, inkrementális állapot.
  • Külön streamek, inkrementális állapot.

Az inkrementális xDS csökkenti a forgalmat a vezérlő sík és envoy, ez nagy konfigurációk esetén releváns. De bonyolítja az interakciót, a kérésben az erőforrások leiratkozási és feliratkozási listája kerül átadásra.

A példánkban ADS-t használunk - egy stream RDS, CDS, EDS számára és nem inkrementális módban. Az inkrementális mód engedélyezéséhez meg kell adni api_type: DELTA_GRPC

Mivel a kérésben vannak csomópont paraméterei, a vezérlő síkhoz különböző erőforrásokat küldhetünk különböző példányokhoz, envoy, ez kényelmes a szolgáltatás mesh építése során.

Bemelegítés

Ezen envoy a rendszer indításakor vagy új konfiguráció fogadásakor a vezérlő síktól az erőforrások bemelegítési folyamata elindul. Ez el van választva, listener bemelegítésre és cluster bemelegítésre. Az első RDS/LDS változásakor indul, a második CDS/EDS esetén. Ez azt jelenti, hogy ha csak az upstream-ok változnak, a listener nem lesz újra létrehozva.

A bemelegítési folyamat során a vezérlő síktól függő erőforrásokra várakoznak a timeout ideje alatt. Ha a timeout lejár, az inicializálás nem lesz sikeres, az új listener nem kezd el hallgatni a porton.
Az inicializálás sorrendje: EDS, CDS, aktív egészségellenőrzés, RDS, LDS. Ha aktív egészségellenőrzések vannak engedélyezve, a forgalom csak azután megy az upstreamra, ha egy egészségellenőrzés sikeresen teljesült.

Ha a listener újra létrejött, a régi állapot DRAIN-be kerül, és eltávolításra kerül, miután az összes kapcsolat bezárult vagy a timeout letelt --drain-time-s, alapértelmezés szerint 10 perc.

Folyatatás következik.

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster