Përshëndetje! Kjo është një artikull i vogël që përgjigjet pyetjeve: "çfarë është envoy?", "për çfarë nevojitet?" dhe "nga ku të filloj?".
ĂfarĂ« Ă«shtĂ« kjo
Envoy është një balancues L4-L7 i shkruar në C++, i orientuar ndaj performancës së lartë dhe disponueshmërisë. Nga njëra anë, ai është një lloj ekuivalenti i nginx dhe haproxy, i krahasueshëm me ta për nga performanca. Nga ana tjetër, ai është më shumë i orientuar ndaj arkitekturës së mikroshërbimeve dhe ka funksionalitete që nuk janë më të dobëta se balancuesit në java dhe go, siç janë zuul ose traefik.
Tabela krahasuese haproxy/nginx/envoy, ajo nuk pretendon të jetë e vërteta absolute, por ofron një pamje të përgjithshme.
nginx
haproxy
envoy
traefik
yjet në github
11.2k/mirror
1.1k/mirror
12.4k
27.6k
i shkruar në
C
C
C++
go
API
jo
socket only/push
dataplane/pull
pull
kontroll i shëndetit aktiv
jo
po
po
po
Open tracing
plugin i jashtëm
jo
po
po
JWT
plugin i jashtëm
jo
po
jo
Zgjerimi
Lua/C
Lua/C
Lua/C++
jo
Pse
Ky është një projekt i ri, ka shumë gjëra që i mungojnë, diçka është në alfa të hershme. Por envoy, përfshirë përfitimet e rinisë, zhvillohet shpejt dhe tashmë ka shumë mundësi interesante: konfigurim dinamik, shumë filtra të gatshëm, një ndërfaqe të thjeshtë për të shkruar filtrat tuaj.
Kjo rezulton në fusha aplikimi, por fillimisht dy antipatere:
- Shërbimi i statikës.
Fakti është se për momentin në envoy nuk ka mbështetje për caching. Po përpiqen ta . Ideja është që një herë të realizohet në envoy të gjitha nuancat (zoo e headerave) e përputhjes me RFC, dhe për zbatime specifike të bëhet një ndërfaqe. Por për momentin kjo as nuk është në alfa, arkitektura është në diskutim, hapur (derisa po shkruaja artikullin PR u fut, por ky pikë është ende aktual).
Dhe për momentin përdorni nginx për statik.
- Konfigurimi statik.
Mund të përdoret, por envoy nuk u krijua për këtë. Mundësitë në konfigurimin statik nuk do të jenë të zbuluara. Ka shumë momente:
Duke redaktuar konfigurimin në yaml, do të gaboni, do të mallkoni zhvilluesit për shumëllojshmërinë dhe do të mendoni se konfigurat e nginx/haproxy, megjithëse më pak të strukturuara, janë më të lakonshme. Kjo është thelbi. Konfigurimi Nginx dhe Haproxy është krijuar për redaktim manual, ndërsa i envoy për krijim nga kodi. E gjithë konfigurimi përshkruhet në , duke e gjeneruar atë nga skedarët proto është shumë më e vështirë për të gabuar.
Skenarët e canary, b/g deploy dhe shumë të tjera, normalisht realizohen vetëm në konfigurimin dinamik. Nuk po them se kjo nuk mund të bëhet në statik, ne të gjithë e bëjmë. Por për këtë duhet të ndihmojmë me ndihma, në çdo nga balancuesit, në envoy përfshirë.
Detyrat për të cilat Envoy është thelbësor:
- Balancimi i trafik e në sisteme komplekse dhe dinamike. Këtu përfshihet service mesh, por nuk është vetëm ai.
- Nevoja për funksionalitetin e ndjekjes së shpërndarë, autorizim të ndërlikuar ose diçka tjetër që ekziston në envoy nga kutia ose implementohet lehtësisht, kurse në nginx/haproxy duhet të ndihmojmë me lua dhe plugina të dyshimta.
Të dyja janë të nevojshme për të siguruar performancë të lartë kur është nevoja.
Si funksionon
Envoy shpërndahen në binarë vetëm si një imazh docker. Në imazh tashmë ka një shembull të konfiguracionit statik. Por ne na intereson vetëm për të kuptuar strukturën.
envoy.yaml konfigurimi statik
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
# Komentoni linjën e mëposhtme për të testuar në rrjetet 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.comKonfigurimi dinamik
Cila është problemi që po kërkojmë zgjidhje? Nuk mund të thjeshtë të rinisni konfigurimin e balancuesit nën ngarkesë, do të ndodhin "probleme të vogla":
- Validimi i konfigurimit.
Konfigi mund të jetë i madh, mund të jetë shumë i madh, nëse e rinisim të gjithë njëherësh, shanset për ndonjë gabim rriten.
- Koneksione të gjata.
Kur inicializoni një listener të ri, duhet të kujdeseni për koneksionet që punojnë në të vjetër, nëse ndryshimet ndodhin shpesh dhe ka koneksione të gjata, do të duhet të kërkoni një kompromis. Përshëndetje, kubernetes ingress në nginx.
- Kontroll të shëndetit aktiv.
Nëse kemi kontroll të shëndetit aktiv, duhet t'i kontrollojmë të gjitha në konfigurimin e ri para se të dërgojmë trafik. Nëse ka shumë upstream-e, kjo kërkon kohë. Përshëndetje, haproxy.
Si zgjidhet kjo në envoy, duke ngarkon dinamikisht konfigurimin, sipas modelit të pulave, mund ta ndajë atë në pjesë të veçanta dhe të mos ri-inicializojë atë pjesën që nuk është ndryshuar. P.sh., një listener, që rinekalon është e kushtueshme, por ndodhi rrallë.
Konfigurimi envoy (nga skedari më sipër) ka këto entitete:
- listener â njĂ« listener qĂ« Ă«shtĂ« nĂ« njĂ« ip/port tĂ« caktuar
- virtual host â njĂ« host virtual sipas emrit tĂ« domain-it
- route â njĂ« rregull balancimi
- cluster â njĂ« grup upstream-Ă«sh me parametrat e balancimit
- endpoint â adresa e instancĂ«s sĂ« upstream-it
Secili nga këto entitete plus disa të tjera mund të plotësohen dinamikisht, për këtë në konfigurim tregohet adresa e shërbimit nga ku do të merret konfigurimi. Shërbimi mund të jetë REST ose gRPC, preferohet përdorimi i gRPC.
Shërbimet quhen përkatësisht: LDS, VHDS, RDS, CDS dhe EDS. Mund të kombinohen konfigurimet statike dhe dinamike, me kufizimin që burimi dinamik nuk mund të përcaktohet në atë statik.
Për shumicën e detyrave, është e mjaftueshme të realizohen tre shërbimet e fundit, ato quhen ADS (Aggregrated Discovery Service), për dhe për go ka një implementim të gatshëm gRPC dataplane që është e mjaftueshme të plotësohen vetëm objektet nga burimi juaj.
Konfigurimi merr formën e mëposhtme:
envoy.yaml konfigurimi dinamik
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: 6565Kur të filloni, envoy me këtë konfigurim, ai do t'i bashkohet control-plane dhe do të përpiqet të kërkojë konfigurimin RDS, CDS dhe EDS. Si ndodh procesi i ndërveprimit është përshkruar .
Në mënyrë të shkurtër, envoy ai dërgon një kërkesë, me shenjimin e llojit të burimit të kërkuar, versionit dhe parametrave të nodës. Në përgjigje merr burimin dhe versionin, nëse në control-plane versioni nuk ka ndryshuar, ai nuk përgjigjet.
Ka 4 variante ndërveprimi:
- Një gRPC stream për të gjitha llojet e burimeve, dërgohet gjendja e plotë e burimit.
- Stream të veçanta, gjendja e plotë.
- Një stream, gjendja inkrementale.
- Stream të veçanta, gjendja inkrementale.
Incremental xDS lejon zvogëlimin e trafikut midis control-plane dhe envoy, kjo është e rëndësishme për konfigurime të mëdha. Por e komplikon ndërveprimin, në kërkesë dërgohet lista e burimeve për anullim dhe regjistrim.
NĂ« shembullin tonĂ« pĂ«rdoreshin ADS â njĂ« stream pĂ«r RDS, CDS, EDS dhe jo nĂ« mĂ«nyrĂ« inkrementale. PĂ«r tĂ« aktivizuar modin inkrental, duhet tĂ« tregohet api_type: DELTA_GRPC
Duke qenë se në kërkesë ka parameter të nodës, mund të dërgojmë burime të ndryshme për instance të ndryshme në control-plane envoy, kjo është e përshtatshme për ndërtimin e një rrjeti shërbimesh.
Ngrohja
Në envoy në fillim ose kur merr një konfigurim të ri nga control-plane nis procesin e ngrohjes së burimeve. Ai ndahet në ngrohjen e listener-it dhe ngrohjen e cluster-it. E para niset kur ka ndryshime në RDS/LDS, e dyta kur ka CDS/EDS. Kjo do të thotë se nëse ndodhin vetëm ndryshime në upstream, listener-i nuk rinovohet.
Gjatë procesit të ngrohjes, priten burime të varura nga control-plane për një periudhë të caktuar kohore. Nëse ka kaluar koha e caktuar, inicializimi nuk do të jetë i suksesshëm, listener-i i ri nuk do të fillojë të dëgjojë portin.
Rendi i inicializimit: EDS, CDS, vlerësimi aktiv të shëndetit, RDS, LDS. Me vlerësimet e shëndetit aktiv të aktivizuara, trafiku do të shkojë në upstream, vetëm pas një vlerësimi të suksesshëm.
Nëse është ri-inicializuar listener-i, i vjetri kalon në gjendjen DRAIN dhe do të hiqet pas mbylljes së të gjitha lidhjeve ose kalimit të kohës së caktuar --drain-time-s, në mënyrë default 10 minuta.
Vazhdon.
Burimi: habr.com
