Vær hilset! Dette er en kort artikel, der besvarer spørgsmålene: "hvad er udsending?", "hvorfor er det nødvendigt?" og "hvor skal man begynde?".
Hvad er dette
Envoy er en L4-L7 balancer skrevet i C++, fokuseret på høj ydeevne og tilgængelighed. På den ene side er dette på en eller anden måde en analog af nginx og haproxy, sammenlignelig i ydeevne med dem. På den anden side er den mere orienteret mod mikroservicearkitektur og har funktionalitet, der ikke er værre end java og go balancere, såsom zuul eller traefik.
Sammenligningstabel for haproxy/nginx/envoy, den hævder ikke at være den absolutte sandhed, men giver et generelt billede.
Nginx
haproxy
udsending
traefik
stjerner på github
11.2k/spejl
1.1k/spejl
12.4k
27.6k
skrevet ind
C
C
C + +
go
API
ingen
kun stikkontakt/skub
dataplan/træk
Træk
aktivt sundhedstjek
ingen
ja
ja
ja
Åben sporing
eksternt plugin
ingen
ja
ja
J.W.T.
eksternt plugin
ingen
ja
ingen
udvidelse
Lua/C
Lua/C
Lua/C++
ingen
Hvad for
Dette er et ungt projekt, der mangler mange ting, nogle i tidlig alfa. Men udsending, også på grund af sin ungdom, udvikler sig hurtigt og har allerede mange interessante funktioner: dynamisk konfiguration, mange færdige filtre, en enkel grænseflade til at skrive dine egne filtre.
Anvendelsesområder følger heraf, men først er der 2 antimønstre:
- Statisk rekyl.
Faktum er, at i øjeblikket i udsending ingen caching support. Google-fyrene prøver dette
Indtil videre skal du bruge nginx til statik.
- Statisk konfiguration.
Du kan bruge det, men udsending Det er ikke det, den er skabt til. Funktioner i en statisk konfiguration vil ikke blive eksponeret. Der er mange øjeblikke:
Når du redigerer konfigurationen i yaml, vil du tage fejl, skælde udviklerne ud for ordlyd og tro, at nginx/haproxy-konfigurationerne, selvom de er mindre strukturerede, er mere kortfattede. Det er pointen. Konfigurationen af Nginx og Haproxy blev oprettet til redigering i hånden, og udsending til generering fra kode. Hele konfigurationen er beskrevet i
Canary, b/g-implementeringsscenarier og meget mere implementeres normalt kun i en dynamisk konfiguration. Jeg siger ikke, at det ikke kan lade sig gøre statisk, vi gør det alle sammen. Men til dette skal du sætte krykker på, i en hvilken som helst af balancerne, i udsending inklusive.
Opgaver, som envoy er uundværlig til:
- Trafikafbalancering i komplekse og dynamiske systemer. Dette inkluderer servicenetværket, men det er ikke nødvendigvis det eneste.
- Behovet for distribueret sporingsfunktionalitet, kompleks autorisation eller anden funktionalitet, der er tilgængelig i udsending ud af boksen eller praktisk implementeret, men i nginx/haproxy skal du være omgivet af lua og tvivlsomme plugins.
Begge giver om nødvendigt høj ydeevne.
Hvordan fungerer denne her
Envoy distribueres kun i binære filer som et docker-billede. Billedet indeholder allerede et eksempel på en statisk konfiguration. Men vi er kun interesseret i det for at forstå strukturen.
envoy.yaml statisk konfiguration
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
Dynamisk konfiguration
Hvilket problem leder vi efter en løsning på? Du kan ikke bare genindlæse load balancer-konfigurationen under belastning; "små" problemer vil opstå:
- Konfigurationsvalidering.
Konfigurationen kan være stor, den kan være meget stor, hvis vi overbelaster det hele på én gang, øges chancerne for en fejl et eller andet sted.
- Langlivede forbindelser.
Når du initialiserer en ny lytter, skal du passe på de forbindelser, der kører på den gamle; hvis ændringer sker ofte, og der er langvarige forbindelser, bliver du nødt til at lede efter et kompromis. Hej, kubernetes ingress på nginx.
- Aktive sundhedstjek.
Hvis vi har aktive sundhedstjek, skal vi dobbelttjekke dem alle i den nye konfiguration, før vi sender trafik. Hvis der er mange opstrøms, tager det tid. Hej haproxy.
Hvordan er dette løst i udsendingVed at indlæse konfigurationen dynamisk, i henhold til poolmodellen, kan du opdele den i separate dele og ikke geninitialisere den del, der ikke er ændret. For eksempel en lytter, som er dyr at geninitialisere og sjældent ændres.
Konfiguration udsending (fra filen ovenfor) har følgende entiteter:
- lytter — lytteren hænger på en bestemt ip/port
- virtuel vært - virtuel vært efter domænenavn
- rute - balanceregel
- klynge — en gruppe opstrøms med balanceringsparametre
- endpoint — upstream-instansadresse
Hver af disse entiteter plus nogle andre kan udfyldes dynamisk; til dette angiver konfigurationen adressen på den tjeneste, hvorfra konfigurationen vil blive modtaget. Tjenesten kan være REST eller gRPC, gRPC er at foretrække.
Tjenesterne hedder henholdsvis: LDS, VHDS, RDS, CDS og EDS. Du kan kombinere statisk og dynamisk konfiguration med den begrænsning, at en dynamisk ressource ikke kan specificeres i en statisk.
Til de fleste opgaver er det nok at implementere de sidste tre tjenester, de kaldes ADS (Aggregated Discovery Service), for
Konfigurationen har følgende form:
envoy.yaml dynamisk konfiguration
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
Ved opstart udsending med denne konfiguration vil den oprette forbindelse til kontrolplanet og forsøge at anmode om RDS-, CDS- og EDS-konfigurationen. Hvordan interaktionsprocessen foregår, beskrives
Kort sagt, udsending sender en anmodning, der angiver typen af ressource, der anmodes om, versionen og parametrene for noden. Som svar modtager den en ressource og en version; hvis versionen på kontrolplanet ikke er ændret, svarer den ikke.
Der er 4 interaktionsmuligheder:
- Én gRPC-strøm for alle typer ressourcer, den fulde status for ressourcen sendes.
- Separate vandløb, fuld stand.
- Én strøm, inkrementel tilstand.
- Separate strømme, inkrementel tilstand.
Inkrementel xDS giver dig mulighed for at reducere trafikken mellem kontrolplanet og udsending, dette er relevant for store konfigurationer. Men det komplicerer interaktionen; anmodningen indeholder en liste over ressourcer til at afmelde og abonnere.
Vores eksempel bruger ADS - én stream til RDS, CDS, EDS og ikke-inkrementel tilstand. For at aktivere inkrementel tilstand skal du angive api_type: DELTA_GRPC
Da anmodningen indeholder nodeparametre, kan vi sende forskellige ressourcer til kontrolplanet for forskellige instanser udsending, dette er praktisk til at bygge et servicenet.
Opvarmning
On udsending ved opstart eller ved modtagelse af en ny konfiguration fra kontrolplan, startes ressourceopvarmningsprocessen. Den er opdelt i lytteropvarmning og klyngeopvarmning. Den første lanceres når der er ændringer i RDS/LDS, den anden når CDS/EDS. Det betyder, at hvis kun upstreams ændrer sig, bliver lytteren ikke genskabt.
Under opvarmningsprocessen forventes afhængige ressourcer fra kontrolplanet under timeout. Hvis timeout opstår, vil initialiseringen ikke lykkes, og den nye lytter vil ikke begynde at lytte på porten.
Initialiseringsrækkefølge: EDS, CDS, aktivt helbredstjek, RDS, LDS. Med aktive sundhedstjek aktiveret vil trafikken kun gå opstrøms efter et vellykket sundhedstjek.
Hvis lytteren blev genskabt, går den gamle i DRAIN-tilstanden og vil blive slettet, når alle forbindelser er lukket eller timeout udløber --drain-time-s
, standard 10 minutter.
Fortsættes.
Kilde: www.habr.com