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. Myš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. 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 , 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.comDynamická 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ř. 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: 6565Př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. .
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
