Salutari! Acesta este un articol scurt care răspunde la întrebările: „ce este trimis?”, „de ce este nevoie?” și „de unde să încep?”.
Ce este asta?
Envoy este un echilibrator L4-L7 scris în C++, axat pe performanță ridicată și disponibilitate. Pe de o parte, acesta este într-un fel un analog al nginx și haproxy, comparabil ca performanță cu acestea. Pe de altă parte, este mai orientat către arhitectura de microservicii și are o funcționalitate nu mai proastă decât java și balansoarele go, cum ar fi zuul sau traefik.
Tabel de comparație al haproxy/nginx/envoy, nu pretinde a fi adevărul absolut, dar oferă o imagine generală.
Nginx
haproxy
trimis
traefik
stele pe github
11.2k/oglindă
1.1k/oglindă
12.4k
27.6k
scris in
C
C
C ++
go
API
nu
numai priză/împingere
dataplane/pull
trage
controlul de sănătate activ
nu
da
da
da
Deschideți urmărirea
plugin extern
nu
da
da
J.W.T.
plugin extern
nu
da
nu
extensie
Lua/C
Lua/C
Lua/C++
nu
Pentru ce
Acesta este un proiect tânăr, lipsesc multe lucruri, unele în alfa timpurie. Dar trimis, tot datorită tinereții sale, se dezvoltă rapid și are deja multe caracteristici interesante: configurație dinamică, multe filtre gata făcute, o interfață simplă pentru a scrie propriile filtre.
De aici rezultă domenii de aplicare, dar mai întâi există 2 antimodeluri:
- Recul static.
Cert este că în acest moment în trimis fără suport pentru cache. Băieții de la Google încearcă asta
Pentru moment, utilizați nginx pentru statice.
- Configurație statică.
Îl poți folosi, dar trimis Nu pentru asta a fost creat. Caracteristicile într-o configurație statică nu vor fi expuse. Sunt multe momente:
Când editați configurația în yaml, vă veți înșela, certați dezvoltatorii pentru verbozitate și credeți că configurațiile nginx/haproxy, deși mai puțin structurate, sunt mai concise. Acesta este ideea. Configurația Nginx și Haproxy a fost creată pentru editare manual și trimis pentru generare din cod. Întreaga configurație este descrisă în
Scenariile de implementare Canary, b/g și multe altele sunt în mod normal implementate doar într-o configurație dinamică. Nu spun că acest lucru nu se poate face static, o facem cu toții. Dar pentru asta trebuie să puneți cârje, în oricare dintre balansoare, în trimis inclusiv.
Sarcini pentru care Envoy este indispensabil:
- Echilibrarea traficului în sisteme complexe și dinamice. Aceasta include rețeaua de serviciu, dar nu este neapărat singura.
- Nevoia de funcționalitate de urmărire distribuită, autorizare complexă sau alte funcționalități care sunt disponibile în trimis ieșit din cutie sau implementat convenabil, dar în nginx/haproxy trebuie să fii înconjurat de plugin-uri lua și dubioase.
Ambele, dacă este necesar, oferă performanțe ridicate.
Cum funcționează
Envoy este distribuit în binare doar ca imagine docker. Imaginea conține deja un exemplu de configurație statică. Dar ne interesează doar pentru înțelegerea structurii.
configurație statică 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
Configurație dinamică
La ce problemă căutăm o soluție? Nu puteți să reîncărcați configurația echilibrului de încărcare sub încărcare; vor apărea probleme „mici”:
- Validarea configurației.
Configurația poate fi mare, poate fi foarte mare, dacă o supraîncărcăm pe toate odată, șansele unei erori undeva cresc.
- Legături de lungă durată.
Când inițializați un nou ascultător, trebuie să aveți grijă de conexiunile care rulează pe cel vechi; dacă schimbările apar frecvent și există conexiuni de lungă durată, va trebui să căutați un compromis. Bună ziua, intrarea kubernetes pe nginx.
- Controale active de sănătate.
Dacă avem verificări de sănătate active, trebuie să le verificăm pe toate în noua configurație înainte de a trimite trafic. Dacă există o mulțime de amonte, acest lucru necesită timp. Bună, haproxy.
Cum se rezolvă asta în trimisÎncărcând configurația în mod dinamic, în funcție de modelul piscinei, o puteți împărți în părți separate și nu reinițializați partea care nu s-a schimbat. De exemplu, un ascultător, care este scump de reinițializat și se schimbă rar.
configurație trimis (din dosarul de mai sus) are următoarele entități:
- ascultător — ascultător agățat de un anumit ip/port
- gazdă virtuală - gazdă virtuală după nume de domeniu
- traseu - regula de echilibrare
- grup — un grup de amonte cu parametri de echilibrare
- punct final — adresa instanței din amonte
Fiecare dintre aceste entități plus unele altele pot fi completate dinamic; pentru aceasta, configurația specifică adresa serviciului de unde va fi primită configurația. Serviciul poate fi REST sau gRPC, este de preferat gRPC.
Serviciile sunt denumite respectiv: LDS, VHDS, RDS, CDS și EDS. Puteți combina configurația statică și dinamică, cu limitarea că o resursă dinamică nu poate fi specificată într-una statică.
Pentru majoritatea sarcinilor, este suficient să implementați ultimele trei servicii, acestea se numesc ADS (Aggregated Discovery Service), pentru
Configurația ia următoarea formă:
configurație dinamică 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
La pornire trimis cu această configurație, se va conecta la planul de control și va încerca să solicite configurația RDS, CDS și EDS. Este descris modul în care are loc procesul de interacțiune
Pe scurt, trimis trimite o cerere indicând tipul de resursă solicitată, versiunea și parametrii nodului. Ca răspuns, primește o resursă și o versiune; dacă versiunea de pe planul de control nu s-a schimbat, nu răspunde.
Există 4 opțiuni de interacțiune:
- Un flux gRPC pentru toate tipurile de resurse, se trimite starea completă a resursei.
- Fluxuri separate, stare completă.
- Un singur flux, stare incrementală.
- Fluxuri separate, stare incrementală.
xDS incremental vă permite să reduceți traficul între planul de control și trimis, acest lucru este relevant pentru configurații mari. Dar complică interacțiunea; cererea conține o listă de resurse pentru dezabonare și abonare.
Exemplul nostru folosește ADS - un flux pentru RDS, CDS, EDS și modul non-incremental. Pentru a activa modul incremental, trebuie să specificați api_type: DELTA_GRPC
Deoarece cererea conține parametrii nodului, putem trimite diferite resurse către planul de control pentru diferite instanțe trimis, acest lucru este convenabil pentru construirea unei rețele de serviciu.
Încălzire
Pe trimis la pornire sau la primirea unei noi configurații din planul de control, procesul de încălzire a resurselor este lansat. Este împărțit în încălzire ascultător și încălzire cluster. Primul este lansat când există modificări în RDS/LDS, al doilea când CDS/EDS. Aceasta înseamnă că, dacă se schimbă doar în amonte, ascultătorul nu este recreat.
În timpul procesului de încălzire, sunt așteptate resurse dependente de la planul de control în timpul expirării. Dacă are loc expirarea, inițializarea nu va avea succes și noul ascultător nu va începe să asculte pe port.
Ordin de inițializare: EDS, CDS, verificare de sănătate activă, RDS, LDS. Cu verificările active de sănătate activate, traficul va merge în amonte numai după o verificare de sănătate reușită.
Dacă ascultătorul a fost recreat, cel vechi intră în starea DRAIN și va fi șters după ce toate conexiunile sunt închise sau expiră timpul de expirare --drain-time-s
, implicit 10 minute.
Pentru a fi continuat.
Sursa: www.habr.com