Vyslanec. 1. Úvod

Zdravím! Tento krátký článek odpovídá na otázky: „Co je Envoy?“, „Proč ho potřebuji?“ a „Kde začít?“.

Co je to

Envoy je L4-L7 load balancer napsaný v C++, zaměřený na vysoký výkon a dostupnost. Na jedné straně je do jisté míry analogický s nginx a haproxy, srovnatelný co do výkonu. Na druhé straně je více zaměřen na mikroservisní architektury a nabízí funkcionalitu srovnatelnou s load balancery v Javě a Go, jako jsou zuul nebo traefik.

Srovnávací tabulka haproxy/nginx/envoy si nenárokuje na absolutní pravdu, ale poskytuje obecný obraz.

Nginx
haproxy
odesláno
traefik

hvězdy na GitHubu
11.2k/zrcadlo
1.1k/zrcadlo
12.4
27.6

napsané v
C
C
C + +
go

API
ne
pouze zásuvka/zatlačení
datová rovina/pull
táhnout

aktivní kontrola stavu
ne
ano
ano
ano

Otevřít trasování
externí plugin
ne
ano
ano

JWT
externí plugin
ne
ano
ne

prodloužení
Lua/C
Lua/C
Lua/C++
ne

Proč

Tohle je mladý projekt, chybí mu spousta věcí, některé z nich jsou v rané alfa verzi. Ale odesláno, částečně díky svému mládí, se rychle rozvíjí a již má mnoho zajímavých funkcí: dynamickou konfiguraci, mnoho hotových filtrů, jednoduché rozhraní pro psaní vlastních filtrů.
Z toho vyplývají oblasti použití, ale nejprve dva anti-vzory:

  • Statický zpětný ráz.

Věc se má tak, že v tuto chvíli odesláno Neexistuje žádná podpora pro ukládání do mezipaměti. Kluci z Googlu se to snaží opravit. opravitMyšlenkou je to implementovat jednou za čas odesláno Všechny jemnosti (záplava hlaviček) shody s RFC a vytvoření rozhraní pro specifické implementace. Ale tohle ještě ani není alfa verze; architektura je stále v diskusi. PR otevřené (zatímco jsem psal článek, PR se sloučily, ale tento bod je stále relevantní).

Mezitím používejte nginx pro statiku.

  • Statická konfigurace.

Můžeš to použít, ale odesláno Nebyl vytvořen pro tento účel. Možnosti statické konfigurace nebudou plně využity. Existuje mnoho bodů:

Při úpravě konfigurace YAML budete dělat chyby, proklínat vývojáře za přílišnou upovídanost a myslet si, že konfigurace nginx/haproxy, i když méně strukturované, jsou stručnější. To je právě ten smysl. Konfigurace Nginx a Haproxy byly vytvořeny pro ruční úpravu, zatímco odesláno pro generování z kódu. Celá konfigurace je popsána v protobuf, jeho generování z proto souborů značně ztěžuje chybu.

Kanárské scénáře, nasazení b/g a mnoho dalších věcí lze správně implementovat pouze v dynamické konfiguraci. Neříkám, že to nelze provést staticky; to děláme všichni. Ale abyste to dokázali, museli byste se uchýlit k nějakým alternativním řešením, v jakémkoli balanceru, v odesláno včetně.

Úkoly, kde je Envoy nepostradatelný:

  • Vyvažování provozu v komplexních a dynamických systémech. To zahrnuje i servisní síť, ale nemusí to být nutně omezeno na ni.
  • Potřeba distribuovaného trasování, komplexní autorizace nebo jiných funkcí, které jsou k dispozici v odesláno Buď se to snadno implementuje ihned po vybalení z krabice, nebo pohodlně, zatímco v nginx/haproxy se musíte zabalit do lua a pochybných pluginů.

Oba jsou k dispozici pro zajištění vysokého výkonu v případě potřeby.

Jak to funguje

Envoy je distribuován pouze jako binární obraz Dockeru. Obraz již obsahuje ukázkovou statickou konfiguraci, ale nás zajímá pouze ta, abychom pochopili její strukturu.

Statická konfigurace envoy.yaml

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

Dynamická konfigurace

Jaký problém se snažíme vyřešit? Nemůžeme jednoduše znovu načíst konfiguraci load balanceru; objeví se některé „drobné“ problémy:

  • Ověření konfigurace.

Konfigurace může být rozsáhlá, může být velmi rozsáhlá, a pokud ji celou najednou přetížíme, zvyšuje se šance na chybu někde.

  • Dlouhotrvající sloučeniny.

Při inicializaci nového listeneru je třeba dbát na připojení běžící na tom starém. Pokud dochází ke častým změnám a existují dlouhodobá připojení, budete muset najít kompromis. Dobrý den, Kubernetes ingress na nginx.

  • Aktivní zdravotní kontroly.

Pokud máme aktivní kontroly stavu, měli bychom je všechny znovu zkontrolovat v nové konfiguraci před odesláním provozu. Pokud je upstreamů hodně, zabere to čas. Ahoj, haproxy.

Jak je to řešeno v odeslánoDynamickým načtením konfigurace pomocí modelového fondu ji můžete rozdělit na samostatné části a vyhnout se opětovné inicializaci částí, které se nezměnily. Lze například použít listener, jehož opětovná inicializace je nákladná a mění se jen zřídka.

Konfigurace odesláno (z výše uvedeného souboru) má následující entity:

  • posluchač — posluchač visící na konkrétní IP/portu
  • virtuální hostitel — virtuální hostitel podle doménového jména
  • trasa — pravidlo vyvážení
  • shluk — skupina předních toků s vyrovnávacími parametry
  • Koncový bod — adresa instance nadřazeného serveru

Každou z těchto entit, spolu s některými dalšími, lze dynamicky naplnit zadáním adresy služby, ze které bude konfigurace načtena, v konfiguraci. Služba může být buď REST, nebo gRPC, ale gRPC je preferován.

Služby jsou pojmenovány odpovídajícím způsobem: LDS, VHDS, RDS, CDS a EDS. Statické a dynamické konfigurace lze kombinovat s výhradou, že dynamický zdroj nelze specifikovat v rámci statické konfigurace.

Pro většinu úkolů stačí implementovat poslední tři služby, nazývají se ADS (Aggregated Discovery Service), např. Jáva a go má hotovou implementaci datové roviny gRPC, ve které stačí vyplnit objekty pouze ze zdroje.

Konfigurace má následující podobu:

dynamická konfigurace envoy.yaml

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

Při spuštění odesláno S touto konfigurací se připojí k řídicí rovině a pokusí se vyžádat konfiguraci RDS, CDS a EDS. Proces interakce je popsán níže. zde.

Stručně řečeno, odesláno Odešle požadavek s uvedením požadovaného typu zdroje, verze a parametrů uzlu. Jako odpověď obdrží zdroj a verzi. Pokud se verze v řídicí rovině nezměnila, neodpoví.
Existují 4 možnosti interakce:

  • Jeden stream gRPC pro všechny typy zdrojů, odesílá se kompletní stav zdroje.
  • Samostatné proudy, plný stav.
  • Jeden proud, inkrementální stav.
  • Samostatné proudy, inkrementální stav.

Inkrementální xDS umožňuje snížit provoz mezi řídicí rovinou a odeslánoTo je relevantní pro rozsáhlé konfigurace. Komplikuje to však interakci, protože požadavek vyžaduje seznam zdrojů k odhlášení a přihlášení k odběru.

Náš příklad používá ADS – jeden stream pro RDS, CDS, EDS a neinkrementální režim. Chcete-li povolit inkrementální režim, je třeba specifikovat api_type: DELTA_GRPC

Protože požadavek obsahuje parametry uzlu, můžeme do řídicí roviny odesílat různé zdroje pro různé instance. odesláno, to je výhodné pro budování servisní sítě.

Zahřát se

Na odesláno Při spuštění nebo při přijetí nové konfigurace z řídicí roviny se spustí proces zahřívání zdrojů. Dělí se na zahřívání listeneru a zahřívání clusteru. První se spustí při změně RDS/LDS, druhý při změně CDS/EDS. To znamená, že pokud se změní pouze upstreamy, listener se znovu nevytvoří.

Během procesu zahřívání se po dobu časového limitu čekají na závislé zdroje z řídicí roviny. Pokud časový limit vyprší, inicializace selže a nový listener nezačne na portu naslouchat.
Pořadí inicializace: EDS, CDS, aktivní kontrola stavu, RDS, LDS. Pokud jsou povoleny aktivní kontroly stavu, provoz bude pokračovat proti proudu až po jedné úspěšné kontrole stavu.

Pokud je listener znovu vytvořen, starý přejde do stavu DRAIN a bude smazán po uzavření všech připojení nebo po vypršení časového limitu. --drain-time-s, výchozí nastavení 10 minut.

Je třeba pokračovat.

Zdroj: www.habr.com

Přidat komentář