Hälsningar! Det här är en kort artikel som svarar på frågorna: "vad är sändebud?", "varför behövs det?" och "var ska man börja?".
Vad är det här
Envoy är en L4-L7-balanserare skriven i C++, fokuserad på hög prestanda och tillgänglighet. Å ena sidan är detta på något sätt en analog av nginx och haproxy, jämförbar i prestanda med dem. Å andra sidan är den mer orienterad mot mikrotjänstarkitektur och har funktionalitet inte sämre än java och go balanserare, såsom zuul eller traefik.
Jämförelsetabell för haproxy/nginx/envoy, den gör inte anspråk på att vara den absoluta sanningen, men ger en allmän bild.
nginx
haproxy
skickat
traefik
stjärnor på github
11.2k/spegel
1.1k/spegel
12.4k
27.6k
skrivet i
C
C
C + +
go
API
ingen
endast uttag/tryck
dataplan/drag
dra
aktiv hälsokontroll
ingen
ja
ja
ja
Öppna spårning
extern plugin
ingen
ja
ja
J.W.T.
extern plugin
ingen
ja
ingen
förlängning
Lua/C
Lua/C
Lua/C++
ingen
För vad
Det här är ett ungt projekt, det är mycket som saknas, några i tidig alfa. Men skickat, även på grund av sin ungdom, utvecklas snabbt och har redan många intressanta funktioner: dynamisk konfiguration, många färdiga filter, ett enkelt gränssnitt för att skriva dina egna filter.
Användningsområden följer av detta, men först finns det 2 antimönster:
- Statisk rekyl.
Faktum är att för tillfället i skickat inget cachingstöd. Google-killarna försöker detta
För nu, använd nginx för statik.
- Statisk konfiguration.
Du kan använda det, men skickat Det var inte det den skapades för. Funktioner i en statisk konfiguration kommer inte att exponeras. Det finns många ögonblick:
När du redigerar konfigurationen i yaml kommer du att missta dig, skälla ut utvecklarna för detaljerad information och tro att nginx/haproxy-konfigurationerna, även om de är mindre strukturerade, är mer koncisa. Det är poängen. Konfigurationen av Nginx och Haproxy skapades för redigering för hand, och skickat för generering från kod. Hela konfigurationen beskrivs i
Canary, b/g-distributionsscenarier och mycket mer implementeras normalt endast i en dynamisk konfiguration. Jag säger inte att detta inte kan göras statiskt, vi gör det alla. Men för detta måste du sätta på kryckor, i någon av balanserna, in skickat Inklusive.
Uppgifter som envoy är oumbärlig för:
- Trafikbalansering i komplexa och dynamiska system. Detta inkluderar servicenätet, men det är inte nödvändigtvis det enda.
- Behovet av distribuerad spårningsfunktionalitet, komplex auktorisering eller annan funktionalitet som är tillgänglig i skickat out of the box eller praktiskt implementerad, men i nginx/haproxy måste du vara omgiven av lua och tvivelaktiga plugins.
Båda ger vid behov hög prestanda.
Hur fungerar den här
Envoy distribueras endast i binärer som en docker-bild. Bilden innehåller redan ett exempel på en statisk konfiguration. Men vi är bara intresserade av det för att förstå 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
Vilket problem letar vi efter en lösning på? Du kan inte bara ladda om lastbalanserarens konfiguration under belastning; "små" problem kommer att uppstå:
- Konfigurationsvalidering.
Konfigurationen kan vara stor, den kan vara väldigt stor, om vi överbelastas allt på en gång ökar chanserna för ett fel någonstans.
- Långlivade förbindelser.
När du initierar en ny lyssnare måste du ta hand om anslutningarna som körs på den gamla, om ändringar sker ofta och det finns långlivade anslutningar måste du leta efter en kompromiss. Hej, kubernetes ingress på nginx.
- Aktiva hälsokontroller.
Om vi har aktiva hälsokontroller måste vi dubbelkolla dem alla i den nya konfigurationen innan vi skickar trafik. Är det mycket uppströms tar detta tid. Hej haproxy.
Hur löses detta i skickatGenom att ladda konfigurationen dynamiskt, enligt poolmodellen, kan du dela upp den i separata delar och inte återinitiera den del som inte har ändrats. Till exempel en lyssnare, som är dyr att återinitiera och sällan ändras.
konfiguration skickat (från filen ovan) har följande enheter:
- lyssnare — lyssnare som hänger på en specifik ip/port
- virtuell värd - virtuell värd efter domännamn
- rutt - balanseringsregel
- kluster — en grupp uppströms med balanseringsparametrar
- slutpunkt — Uppströmsinstansadress
Var och en av dessa enheter plus några andra kan fyllas i dynamiskt; för detta anger konfigurationen adressen till tjänsten varifrån konfigurationen kommer att tas emot. Tjänsten kan vara REST eller gRPC, gRPC är att föredra.
Tjänsterna heter respektive: LDS, VHDS, RDS, CDS och EDS. Du kan kombinera statisk och dynamisk konfiguration, med begränsningen att en dynamisk resurs inte kan anges i en statisk.
För de flesta uppgifter räcker det att implementera de tre sista tjänsterna, de kallas ADS (Aggregated Discovery Service), för
Konfigurationen har följande 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
Vid start skickat med denna konfiguration kommer den att ansluta till kontrollplanet och försöka begära RDS-, CDS- och EDS-konfigurationen. Hur interaktionsprocessen går till beskrivs
Kortfattat, skickat skickar en begäran som indikerar typen av resurs som efterfrågas, versionen och parametrarna för noden. Som svar får den en resurs och en version, om versionen på kontrollplanet inte har ändrats svarar den inte.
Det finns 4 interaktionsalternativ:
- En gRPC-ström för alla typer av resurser, hela statusen för resursen skickas.
- Separata bäckar, fullt skick.
- En ström, inkrementellt tillstånd.
- Separata strömmar, inkrementellt tillstånd.
Inkrementell xDS låter dig minska trafiken mellan kontrollplanet och skickat, detta är relevant för stora konfigurationer. Men det komplicerar interaktionen, begäran innehåller en lista med resurser för att av- och prenumerera.
Vårt exempel använder ADS - en ström för RDS, CDS, EDS och icke-inkrementellt läge. För att aktivera inkrementellt läge måste du ange api_type: DELTA_GRPC
Eftersom begäran innehåller nodparametrar kan vi skicka olika resurser till kontrollplanet för olika instanser skickat, detta är praktiskt för att bygga ett servicenät.
Uppvärmning
På skickat vid uppstart eller när en ny konfiguration tas emot från kontrollplanet, startas resursuppvärmningsprocessen. Den är uppdelad i lyssnaruppvärmning och klusteruppvärmning. Den första lanseras när det finns ändringar i RDS/LDS, den andra när CDS/EDS. Det betyder att om bara uppströms ändras så återskapas inte lyssnaren.
Under uppvärmningsprocessen förväntas beroende resurser från kontrollplanet under timeout. Om timeout inträffar kommer initieringen inte att lyckas och den nya lyssnaren kommer inte att börja lyssna på porten.
Initieringsordning: EDS, CDS, aktiv hälsokontroll, RDS, LDS. Med aktiva hälsokontroller aktiverade kommer trafiken att gå uppströms först efter en lyckad hälsokontroll.
Om lyssnaren återskapades går den gamla till DRAIN-tillståndet och kommer att raderas efter att alla anslutningar stängts eller timeouten löper ut --drain-time-s
, standard 10 minuter.
Att fortsätta
Källa: will.com