udsending. 1. Introduktion

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 at rette. Idéen vil blive implementeret én gang i udsending alle finesser (zoo-overskrifter) af RFC-overholdelse, og for specifikke implementeringer lav en grænseflade. Men for nu er det ikke engang alfa, arkitekturen er under diskussion, PR åben (mens jeg skrev PR-artiklen, frøs PR, men dette punkt er stadig relevant).

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 protobuf, at generere det fra proto-filer er meget sværere at lave en fejl.

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 Java og gå der er en færdig implementering af gRPC dataplane, hvor du blot skal udfylde objekterne fra din kilde.

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 her.

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

Tilføj en kommentar