Pozdravljam! To je kratek članek, ki odgovarja na vprašanja: "Kaj je envoy?", "Zakaj je potreben?" in "Kako začeti?".
Hvad er det
Envoy je L4-L7 uravnoteževalnik, napisan v C++, ki je osredotočen na visoko zmogljivost in razpoložljivost. Po eni strani je nekakšna analogija nginx in haproxy, primerljiv z njimi po zmogljivosti. Po drugi strani pa je bolj usmerjen v mikroservisno arhitekturo in ima funkcionalnosti, ki niso nič manjše od uravnoteževalnikov na javi in go, kot sta zuul ali traefik.
Tabela primerjave haproxy/nginx/envoy, ki sicer ne zahteva absolutne resnice, ampak daje splošen pregled.
nginx
haproxy
envoy
traefik
zvezd na githubu
11.2k/mirror
1.1k/mirror
12.4k
27.6k
napisano v
C
C
C++
go
API
ne
samo socket/push
dataplane/pull
pull
aktivno zdravstveno preverjanje
ne
da
da
da
Open tracing
zunanji vtičnik
ne
da
da
JWT
zunanji vtičnik
ne
da
ne
Ekstenzija
Lua/C
Lua/C
Lua/C++
ne
Zakaj
To je mlad projekt, ki mu manjka veliko, nekaj pa je v zgodnji alfa fazi. A envoy, vključno s hitrim napredkom zaradi mladosti, že ima veliko zanimivih možnosti: dinamično konfiguracijo, množico pripravljenih filtrov in preprost vmesnik za pisanje lastnih filtrov.
To prinaša področja uporabe, vendar sta tukaj najprej dva antipatterna:
- Servisiranje statike.
Problem je v tem, da v envoy trenutno ni podpore za predpomnjenje. Fantje iz google poskušajo to . Ideja je enkrat implementirati v na envoy vse zapletenosti (zoo headerjev) v skladu z RFC, za konkretne implementacije pa narediti vmesnik. A to je še vedno v razpravi, arhitektura je v razpravi, odprt (ko sem pisal članek, so PR združili, a ta točka je še vedno aktualna).
Zaenkrat pa uporabite nginx za statiko.
- Statistična konfiguracija.
Lahko jo uporabite, vendar envoy niso jo ustvarili za to. Možnosti v statični konfiguraciji ne bodo razkrite. Obstaja veliko vidikov:
Ko urejate konfiguracijo v yaml, boste delali napake, se pritoževali nad razvijalci zaradi obsežnosti in razmišljali, da so konfiguracije nginx/haproxy, čeprav manj strukturirane, vendar bolj jedrnate. To je bistvo. Konfiguracija Nginx in Haproxy je bila zasnovana za ročno urejanje, medtem ko je envoy namenjena generiranju iz kode. Cela konfiguracija je opisana v , njena generacija po proto datotekah je veliko težja.
Scenariji canary, b/g implementacije in še marsikaj drugega se normalno izvajajo le v dinamični konfiguraciji. Ne trdim, da tega ne moremo storiti v statiki, vse to počnemo. Toda za to je potrebno obkrožiti s kostmi, v katerem koli od uravnoteževalnikov, v envoy vključno s tem.
Naloge, pri katerih je Envoy nezamenljiv:
- Usklajevanje prometa v zapletenih in dinamičnih sistemih. Sem spada tudi service mesh, vendar to ni nujno samo on.
- Potrebnost funkcionalnosti razdeljene sledenja, zapletene avtentikacije ali drugega, kar je na voljo v envoy osnovni različici ali se enostavno implementira, medtem ko je v nginx/haproxy treba uporabiti lua in dvomljive vtičnike.
Oboje je potrebno, da zagotovi visoko zmogljivost.
Kako to funkcionira
Envoy se distribuira v binarnih oblikah samo kot docker slika. V sliki je že primer statične konfiguracije. Vendar nas ta zanima le za razumevanje strukture.
envoy.yaml statična konfiguracija
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
# Komentirajte naslednjo vrstico, da testirate na v6 omrežjih
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.comDinamična konfiguracija
Katero težavo iščemo? Ne moremo kar tako vzeti in ponovno naložiti konfiguracije uravnoteževalnika pod obremenitvijo, pojavljale se bodo 'majhne' težave:
- Validacija konfiguracije.
Konfiguracija je lahko obsežna, lahko je zelo obsežna, če jo ponovno naložimo v celoti, se možnosti, da se kje pojavijo napake, povečajo.
- Dolgoživost povezav.
Ob inicializaciji novega poslušalnika je treba poskrbeti za povezave, ki delujejo na starem, če se spremembe dogajajo pogosto in so prisotne dolgožive povezave, bo treba poiskati kompromis. Pozdrav, kubernetes ingress na nginx.
- Aktivni health-checki.
Če imamo aktivne health-checke, je treba vse ponovno preveriti z novo konfiguracijo, preden pošljemo promet. Če je veliko upstreamov, to zahteva čas. Pozdrav, haproxy.
Kako se to rešuje v envoy, dinamično učitavajući konfiguraciju, po principu modela, moguće je podijeliti je na posebne dijelove i ne ponovo inicijalizirati one dijelove koji se nisu mijenjali. Na primjer, listener koji se skupo ponovo inicijalizira, a rijetko se mijenja.
Конфигурация envoy (iz prethodne datoteke) ima sljedeće entitete:
- listener — listener koji visi na određenom ip/portu
- virtual host — virtualni host po imenu domene
- route — pravilo balansiranja
- cluster — grupa upstream-a s parametrima balansiranja
- endpoint — adresa instance upstream-a
Svaki od ovih entiteta plus neki drugi mogu se dinamički popuniti, za što se u konfiguraciji navodi adresa servisa s kojeg će se dobiti konfiguracija. Servis može biti REST ili gRPC, a preferira se korištenje gRPC.
Servisi se imenuju na sljedeći način: LDS, VHDS, RDS, CDS i EDS. Mogu se kombinirati statička i dinamička konfiguracija, s ograničenjem da dinamički resurs ne može biti naveden u statičkom.
Za većinu zadataka dovoljno je implementirati posljednja tri servisa, oni se nazivaju ADS (Aggregated Discovery Service), za i go postoji gotova implementacija gRPC dataplane u kojoj je dovoljno samo popuniti objekte iz vlastitog izvora.
Konfiguracija dobiva sljedeći oblik:
envoy.yaml dinamička konfiguracija
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: 6565Ob zagonu se prikaže naslednje: envoy s ovom konfiguracijom, povezat će se na control-plane i pokušati zatražiti konfiguraciju RDS, CDS i EDS. Kako proces interakcije prolazi opisano je .
Ukratko, envoy šalje zahtjev, s naznakom tipa traženog resursa, verzijom i parametrima čvora. Kao odgovor dobiva resurs i verziju, ako na control-plane verzija nije promijenjena, ne odgovara.
Postoje 4 opcije interakcije:
- Jedan gRPC stream za sve tipove resursa, šalje se potpuno stanje resursa.
- Ločeni tokovi, polno stanje.
- Eden tok, inkrementalno stanje.
- Ločeni tokovi, inkrementalno stanje.
Inkrementalni xDS omogoča zmanjšanje prometa med kontrolnim vlaknom in envoy, to je pomembno za velike konfiguracije. Vendar pa zapleta interakcijo, saj se v zahtevi pošilja seznam virov za odjavo in prijavo.
V našem primeru uporabljamo ADS — en tok za RDS, CDS, EDS in neinkrementalni način. Za vklop inkrementalnega načina je potrebno navesti api_type: DELTA_GRPC
Ker v zahtevi obstajajo parametri vozlišča, lahko pošiljamo različne vire na kontrolno vlakno za različne instance, envoyto je priročno za gradnjo službene mreže.
Ogrevanje
Na envoy ob zagonu ali ob prejemu nove konfiguracije iz kontrolnega vlakna se zažene postopek ogrevanja virov. Ta je razdeljen na ogrevanje poslušalca in ogrevanje grozda. Prvi se zažene ob spremembah v RDS/LDS, drugi pa ob CDS/EDS. To pomeni, da se, če se spremenijo samo upstreami, poslušalec ne ponovno ustvari.
Med postopkom ogrevanja se pričakujejo odvisni viri iz kontrolnega vlakna v času prekoračitve. Če rok poteče, inicializacija ne bo uspešna, nov poslušalec ne bo začel poslušati vrata.
Vrstni red inicializacije: EDS, CDS, aktivni zdravstveni pregledi, RDS, LDS. Ko so aktivni zdravstveni pregledi vklopljeni, bo promet tekel na upstream šele po enem uspešnem zdravstvenem pregledu.
Če je bil poslušalec ponastavljen, stari preide v stanje DRAIN in bo odstranjen po zaprtju vseh povezav ali poteku roka --drain-time-s, privzeto 10 minut.
Nadaljuje se.
Izvor: habr.com
