Përshëndetje! Ky është një artikull i vogël që përgjigjet pyetjeve: "çfarë është envoy?", "përse ka nevojë?" dhe "nga ku të filloj?".
ĂfarĂ« Ă«shtĂ« kjo
Envoy është një balancues i ngarkesës L4-L7 i shkruar në C++, i fokusuar në performancën dhe disponueshmërinë e lartë. Në një anë, është një farë analogji me nginx dhe haproxy, të krahasueshëm me ta në performancë. Nga ana tjetër, është më shumë i orientuar ndaj arkitekturës së mikroshërbimeve dhe ka funksionalitete që nuk janë më pak të mira se balancuesit në java dhe go, si zuul ose traefik.
Tabela e krahasimit haproxy/nginx/envoy, ajo nuk pretendojnë të jetë e vërteta absolute, por jep një pamje të përgjithshme.
nginx
haproxy
envoy
traefik
yjet në github
11.2k/mirror
1.1k/mirror
12.4k
27.6k
shkruar në
C
C
C++
go
API
jo
socket only/push
dataplane/pull
pull
kontroll aktiv i shëndetit
jo
po
po
po
Open tracing
plugin i jashtëm
jo
po
po
JWT
plugin i jashtëm
jo
po
jo
Zgjerim
Lua/C
Lua/C
Lua/C++
jo
Pse
Ky është një projekt i ri, në të ka shumë gjëra që mungojnë, disa janë në alfa të hershme. Por envoy, përfshirë falë 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.
Nga kjo dalin fushat e përdorimit, por për fillim 2 antipatern:
- Dorëzimi i statikës.
Fakti është se, tani për tani, në envoy nuk ka mbështetje për caching. Djemtë nga google po përpiqen ta . Ideja është të realizohet njëherë në envoy të gjitha hollësitë (zoo e headers) përputhshmëria me RFC, dhe për zbatime specifike të bëhet një ndërfaqe. Por për tani kjo ashtë edhe jo alfa, arkitektura është në diskutim, e hapur (derisa po shkruaja artikullin, PR u bashkua, por ky pikë është ende aktual).
Dhe për tani përdorni nginx për statikën.
- Konfigurimi statik.
Mund ta përdorni, por envoy u krijua jo për këtë. Mundësitë në konfigurimin statik nuk do të shpalosen. Ka shumë momente:
Duke redaktuar konfigurimin nĂ« yaml, do tĂ« gaboni, do tâi mallkoni zhvilluesit pĂ«r fjalosje dhe do tĂ« mendoni se konfigurimet nginx/haproxy, ndoshta mĂ« pak tĂ« strukturuara, por mĂ« tĂ« qarta. Kjo Ă«shtĂ« e vĂ«rteta. Konfigurimi i Nginx dhe Haproxy u krijua pĂ«r redaktimin manual, ndĂ«rsa ai i envoy pĂ«r gjenerimin nga kodi. E gjithĂ« konfigurimi Ă«shtĂ« e pĂ«rshkruar nĂ« , duke e gjeneruar atĂ« nga skedarĂ«t proto Ă«shtĂ« shumĂ« mĂ« e vĂ«shtirĂ« tĂ« gabosh.
Skenarët canary, b/g deploy dhe shumë gjëra të tjera, realizohen normalisht vetëm në konfigurimin dinamik. Unë nuk po them që kjo nuk mund të bëhet në statikë, ne e bëjmë të gjithë këtë. Por për këtë duhet të përdorni kulla, në cilindo nga balancuesit, në envoy në përfshirë.
Detyrat në të cilat Envoy është i pazëvendësueshëm:
- Balancimi i trafikut në sisteme të komplikuara dhe dinamike. Këtu përfshihet service mesh, por kjo nuk është domosdoshmërisht vetëm ai.
- Nevoja për funksionalitetin e gjurmimit të shpërndarë, autorizimit të komplikuar ose një tjetër që ekziston në envoy mënyrë standarde ose implementohet lehtësisht, ndryshe në nginx/haproxy duhet të përdorim lua dhe plugina të dyshimta.
Të dyja janë të nevojshme për të siguruar performancë të lartë.
Si funksionon kjo
Envoy shpërndahet në binarë vetëm si imazh docker. Në imazh tashmë ka një shembull të konfiguracionit statik. Por ne e kemi interes vetëm për të kuptuar strukturën.
envoy.yaml konfigurimi statik
resources_static:
dëgjuesit:
- emri: dëgjuesi_0
adresa:
socket_address:
protokolli: TCP
adresa: 0.0.0.0
vlera_porti: 10000
zinxhirët_filtrues:
- filtrat:
- emri: envoy.http_connection_manager
konfigurimi_typed:
"@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
stat_prefix: ingress_http
konfigurimi_rrugësh:
emri: local_route
pritë virtuale:
- emri: shërbimi_vendës
domainet: ["*"]
rrugët:
- përputh:
prefiksi: "\/"
rrugë:
host_rewrite: www.google.com
klasteri: service_google
filtrat_http:
- emri: envoy.router
klasteret:
- emri: service_google
connect_timeout: 0.25s
lloji: LOGICAL_DNS
# Komentoni rreshtin e mëposhtëm për të testuar në rrjetet v6
dns_lookup_family: V4_ONLY
politika_lb: ROUND_ROBIN
ngarkesa_remis:
emri_klasteri: service_google
pikat:
- lb_endpoints:
- pika:
adresa:
socket_address:
adresa: www.google.com
vlera_porti: 443
transport_socket:
emri: envoy.transport_sockets.tls
konfigurimi_typed:
"@type": type.googleapis.com/envoy.api.v2.auth.UpstreamTlsContext
sni: www.google.comKonfigurimi dinamik
ĂfarĂ« problemi po kĂ«rkojmĂ« tĂ« zgjidhim? Nuk mund tĂ« rindezim thjesht konfigurimin e balancuesit nĂ«n ngarkesĂ«, do tĂ« ndodhin "probleme tĂ« vogla":
- Validimi i konfiguracionit.
Konfigurimi mund të jetë i madh, madje shumë i madh, nëse e ngarkojmë të gjithë në një kohë, shanset që të ketë ndonjë gabim do të rriten.
- Koneksionet afatgjata.
Kur inicializohet një dëgjues i ri, duhet të kujdesemi për lidhjet që punojnë në të vjetrit, nëse ndryshimet ndodhin shpesh dhe ka konneksione afatgjata, do të duhet të kërkojmë një kompromis. Përshëndetje, kubernetes ingress në nginx.
- Kontrollet aktive të shëndetit.
Nëse kemi kontrolle aktive të shëndetit, duhet t'i verifikojmë të gjitha në konfigurimin e ri para se të dërgojmë trafikun. Nëse ka shumë upstream, kjo kërkon kohë. Përshëndetje, haproxy.
Si zgjidhet kjo në envoy, duke ngarkon dinamikisht konfigurimin, sipas modelit të pulsave, mund ta ndanit atë në pjesë të veçanta dhe të mos e ri-inizializoni atë pjesë që nuk është ndryshuar. Për shembull, një dëgjues, që ri-inizializohet me shpenzime të mëdha, ndryshohet rrallë.
Konfigurimi envoy (nga skedari më sipër) ka entitete të mëposhtme:
- dĂ«gjues â dĂ«gjuesi qĂ« Ă«shtĂ« i varur nĂ« njĂ« ip/port tĂ« caktuar
- mikpritĂ«si virtual â mikpritĂ«si virtual sipas emrit tĂ« domain-it
- rrugĂ«n â rregulli i balansimit
- grupi â grupi i upstream-Ă«ve me parametrat e balansimit
- endpoint â adresa e instancĂ«s sĂ« upstream-it
Ădo 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, Ă«shtĂ« mĂ« e preferueshme tĂ« pĂ«rdoret gRPC.
Shërbimet quhen përkatësisht: LDS, VHDS, RDS, CDS dhe EDS. Mund të kombinoni konfigurimin statik dhe dinamik, me kushtin që burimi dinamik të mos tregojë në një statik.
Për shumicën e detyrave, mjafton të realizoni tre shërbimet e fundit, ato quhen ADS (Shërbimi i Zbulimit të Agreguar), për dhe go ka një implementim të gatshëm gRPC dataplane ku mjafton të plotësoni 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 aktivizohet envoy ky konfigurim, do të lidhet me control-plane dhe do të përpiqet të kërkojë konfigurimin RDS, CDS dhe EDS. Si ndodh procesi i ndërveprimit është e përshkruar .
Nëse e përmbledhim, envoy dërgon një kërkesë, duke treguar llojin e burimit që kërkon, versionin dhe parametrat e nodës. Në përgjigje merr burimin dhe versionin, nëse në control-plane versioni nuk ka ndryshuar, ai nuk përgjigjet.
Ka 4 mundësi ndërveprimi:
- Një gRPC stream për të gjitha llojet e burimeve, dërgohet statusi i plotë i burimit.
- Stream të ndara, gjendje e plotë.
- Një stream, gjendje inkrementale.
- Stream të ndara, gjendje inkrementale.
xDS inkremental lejon të reduktojë trafikun ndërmjet 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 një listë e burimeve për anullim dhe abonim.
NĂ« shembullin tonĂ« pĂ«rdoret ADS â njĂ« stream pĂ«r RDS, CDS, EDS dhe modalitetin jo-inkremental. PĂ«r tĂ« aktivizuar modalitetin inkremental, duhet tĂ« specifikoni api_type: DELTA_GRPC
Duke pasur parasysh që në kërkesë ka parametra nodi, mund të dërgojmë burime të ndryshme për instancat e ndryshme në control-plane envoy, kjo është e përshtatshme për ndërtimin e service mesh.
Ngrohje
Në envoy në fillim ose kur merr një konfigurim të ri nga control-plane nis procesin e ngrohjes së burimeve. Ajo ndahet në ngrohjen e dëgjuesit dhe ngrohjen e klasterit. E para niset kur ndodhin ndryshime në RDS/LDS, e dyta në CDS/EDS. Kjo do të thotë se nëse ndryshojnë vetëm upstream-t, dëgjuesi nuk krijohet sërish.
Në procesin e ngrohjes, priten burimet e varura nga control-plane brenda një kohëmatësi. Nëse koha e matjes skadon dhe inicializimi nuk është i suksesshëm, dëgjuesi i ri nuk do të fillojë të dëgjojë portin.
Rendi i inicializimit: EDS, CDS, kontrolli aktiv i shëndetit, RDS, LDS. Kur janë aktivizuar kontrollet aktive të shëndetit, trafiku do të shkojë në upstream, vetëm pas një kontrolli të suksesshëm.
Nëse dëgjuesi krijohet sërish, i vjetri kalon në gjendjen DRAIN, dhe do të hiqet pas mbylljes së të gjitha lidhjeve ose skadimit të kohëmatësit --drain-time-s, për default është 10 minuta.
Vazhdon...
Burimi: habr.com
