Groeten! Dit is een kort artikel dat antwoord geeft op de vragen: “wat is een gezant?”, “waarom is het nodig?” en "waar te beginnen?".
Wat is dit
Envoy is een L4-L7-balancer geschreven in C++, gericht op hoge prestaties en beschikbaarheid. Aan de ene kant is dit op de een of andere manier een analoog van nginx en haproxy, qua prestaties vergelijkbaar met hen. Aan de andere kant is het meer gericht op microservice-architectuur en heeft het functionaliteit niet slechter dan java en go balancers, zoals zuul of traefik.
Vergelijkingstabel van haproxy/nginx/envoy, het beweert niet de absolute waarheid te zijn, maar geeft een algemeen beeld.
nginx
haproxy
verzonden
Traefik
sterren op github
11.2k/spiegel
1.1k/spiegel
12.4k
27.6k
geschreven in
C
C
C + +
go
API
geen
alleen stopcontact/duwen
datavlak/trekken
trek
actieve gezondheidscheck
geen
ja
ja
ja
Open traceren
externe plug-in
geen
ja
ja
JWT
externe plug-in
geen
ja
geen
uitbreiding
Lua/C
Lua/C
Lua/C++
geen
Wat voor
Dit is een jong project, er ontbreken veel dingen, sommige bevinden zich in de vroege alfa. Maar verzonden, mede door zijn jeugd, ontwikkelt zich snel en heeft al veel interessante features: dynamische configuratie, veel kant-en-klare filters, een eenvoudige interface om je eigen filters te schrijven.
Hieruit volgen toepassingsgebieden, maar eerst zijn er 2 antipatronen:
- Statische terugslag.
Feit is dat er op dit moment in verzonden geen caching-ondersteuning. De Google-jongens proberen dit
Gebruik voorlopig nginx voor statische gegevens.
- Statische configuratie.
Je kunt het gebruiken, maar verzonden Daar is het niet voor gemaakt. Functies in een statische configuratie worden niet zichtbaar. Er zijn veel momenten:
Bij het bewerken van de configuratie in yaml zul je je vergissen, de ontwikkelaars uitschelden voor breedsprakigheid en denken dat de nginx/haproxy-configuraties, hoewel minder gestructureerd, beknopter zijn. Dat is het punt. De configuratie van Nginx en Haproxy is gemaakt voor handmatige bewerking, en verzonden voor het genereren uit code. De gehele configuratie wordt beschreven in
Implementatiescenario's van Canary, b/g en nog veel meer worden normaal gesproken alleen in een dynamische configuratie geïmplementeerd. Ik zeg niet dat dit niet statisch kan worden gedaan, we doen het allemaal. Maar hiervoor moet je krukken aantrekken, in een van de balancers, in verzonden met inbegrip van.
Taken waarvoor Envoy onmisbaar is:
- Verkeersbalancering in complexe en dynamische systemen. Dit omvat de service mesh, maar dit is niet noodzakelijkerwijs de enige.
- De behoefte aan gedistribueerde traceringsfunctionaliteit, complexe autorisatie of andere functionaliteit die beschikbaar is in verzonden out-of-the-box of handig geïmplementeerd, maar in nginx/haproxy moet je omringd zijn door lua en dubieuze plug-ins.
Beide leveren, indien nodig, hoge prestaties.
Hoe werkt dit
Envoy wordt alleen in binaire bestanden gedistribueerd als een docker-image. De afbeelding bevat al een voorbeeld van een statische configuratie. Maar we zijn er alleen in geïnteresseerd om de structuur te begrijpen.
envoy.yaml statische configuratie
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
Dynamische configuratie
Voor welk probleem zoeken we een oplossing? Je kunt de load balancer-configuratie niet zomaar opnieuw laden onder belasting; er zullen ‘kleine’ problemen optreden:
- Configuratievalidatie.
De configuratie kan groot zijn, het kan heel groot zijn, als we het allemaal in één keer overbelasten, wordt de kans op een fout ergens groter.
- Verbindingen met een lange levensduur.
Wanneer u een nieuwe luisteraar initialiseert, moet u zorgen voor de verbindingen die op de oude draaien; als er vaak wijzigingen optreden en er sprake is van verbindingen met een lange levensduur, moet u op zoek naar een compromis. Hallo, kubernetes-ingang op nginx.
- Actieve gezondheidscontroles.
Als we actieve gezondheidscontroles hebben, moeten we ze allemaal dubbel controleren in de nieuwe configuratie voordat we verkeer verzenden. Als er veel upstreams zijn, kost dit tijd. Hallo haproxy.
Hoe wordt dit opgelost in verzondenDoor de configuratie dynamisch te laden, volgens het poolmodel, kunt u deze in afzonderlijke delen verdelen en het deel dat niet is gewijzigd niet opnieuw initialiseren. Bijvoorbeeld een luisteraar, die duur is om opnieuw te initialiseren en zelden verandert.
Configuratie verzonden (uit het bovenstaande bestand) heeft de volgende entiteiten:
- luisteraar — luisteraar hangt aan een specifiek IP/poort
- virtuele host - virtuele host op domeinnaam
- route - evenwichtsregel
- cluster — een groep upstreams met balanceringsparameters
- eindpunt — adres van het stroomopwaartse exemplaar
Elk van deze entiteiten plus enkele andere kan dynamisch worden ingevuld; hiervoor specificeert de configuratie het adres van de service waarvandaan de configuratie zal worden ontvangen. De service kan REST of gRPC zijn, gRPC heeft de voorkeur.
De diensten heten respectievelijk: LDS, VHDS, RDS, CDS en EDS. U kunt een statische en dynamische configuratie combineren, met de beperking dat een dynamische bron niet kan worden gespecificeerd in een statische bron.
Voor de meeste taken is het voldoende om de laatste drie services te implementeren, deze worden ADS (Aggregated Discovery Service) genoemd.
De configuratie heeft de volgende vorm:
envoy.yaml dynamische configuratie
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
Bij het uitvoeren van verzonden met deze configuratie zal het verbinding maken met het besturingsvlak en proberen de RDS-, CDS- en EDS-configuratie op te vragen. Er wordt beschreven hoe het interactieproces verloopt
In het kort, verzonden verzendt een verzoek met vermelding van het type bron dat wordt aangevraagd, de versie en parameters van het knooppunt. Als reactie hierop ontvangt het een bron en een versie; als de versie op het besturingsvlak niet is gewijzigd, reageert het niet.
Er zijn 4 interactiemogelijkheden:
- Eén gRPC-stream voor alle soorten bronnen, de volledige status van de bron wordt verzonden.
- Aparte streams, volledige staat.
- Eén stroom, incrementele status.
- Afzonderlijke streams, incrementele status.
Met incrementele xDS kunt u het verkeer tussen het besturingsvlak en verzonden, dit is relevant voor grote configuraties. Maar het bemoeilijkt de interactie; het verzoek bevat een lijst met bronnen voor het afmelden en abonneren.
In ons voorbeeld wordt gebruik gemaakt van ADS: één stream voor RDS, CDS, EDS en niet-incrementele modus. Om de incrementele modus in te schakelen, moet u dit opgeven api_type: DELTA_GRPC
Omdat het verzoek knooppuntparameters bevat, kunnen we voor verschillende instanties verschillende bronnen naar het besturingsvlak sturen verzonden, dit is handig voor het bouwen van een servicemesh.
Opwarmen
Op verzonden bij het opstarten of bij het ontvangen van een nieuwe configuratie van het besturingsvlak wordt het opwarmproces van de bronnen gestart. Het is onderverdeeld in luisteraaropwarming en clusteropwarming. De eerste wordt gelanceerd wanneer er wijzigingen zijn in RDS/LDS, de tweede wanneer CDS/EDS. Dit betekent dat als alleen upstreams veranderen, de luisteraar niet opnieuw wordt gemaakt.
Tijdens het opwarmproces worden tijdens de time-out afhankelijke bronnen van het besturingsvlak verwacht. Als de time-out optreedt, zal de initialisatie niet succesvol zijn en zal de nieuwe luisteraar niet beginnen te luisteren op de poort.
Initialisatievolgorde: EDS, CDS, actieve statuscheck, RDS, LDS. Als actieve statuscontroles zijn ingeschakeld, wordt het verkeer pas na één succesvolle statuscontrole stroomopwaarts gestuurd.
Als de luisteraar opnieuw is gemaakt, gaat de oude naar de DRAIN-status en wordt verwijderd nadat alle verbindingen zijn gesloten of de time-out is verstreken --drain-time-s
, standaard 10 minuten.
Worden voortgezet.
Bron: www.habr.com