Envoy. 1. Sissejuhatus

Tere! See on väike artikkel, mis vastab küsimustele: "mis on envoy?", "miks see vajalik on?" ja "kust alustada?".

Mis see on

Envoy on C++-s kirjutatud L4-L7 koormuse tasakaalustaja, mis keskendub kõrgele jõudlusele ja kättesaadavusele. Ühelt poolt on see osaliselt sarnane nginx-ile ja haproxy-le, pakkudes samalaadset jõudlust. Teiselt poolt on see rohkem suunatud mikroteenuste arhitektuurile ning omab funktsioone, mis ei jää alla Java ja Go koormuse tasakaalustajatele nagu zuul või traefik.

Haproxy/nginx/envoy võrdlustabel, mis ei pretendeeri absoluutsele tõele, kuid annab üldise ülevaate.

nginx
haproxy
envoy
traefik

tähte GitHubis
11.2k/mirror
1.1k/mirror
12.4k
27.6k

kirjutatud
C
C
C++
go

API
ei
ainult socket/push
dataplane/pull
pull

aktiivne tervisekontroll
ei
jah
jah
jah

Open tracing
väline plugin
ei
jah
jah

JWT
väline plugin
ei
jah
ei

Laiendus
Lua/C
Lua/C
Lua/C++
ei

Miks

See on noor projekt, millel on palju puudujääke ja mõned funktsioonid on varases alphas. Kuid envoy, sealhulgas tänu noorusele, areneb see kiiresti ja omab juba praegu palju huvitavaid võimalusi: dünaamiline konfiguratsioon, palju valmis filtreid, lihtne liides oma filtrite kirjutamiseks.
See toob esile rakenduse valdkonnad, kuid alustuseks kaks antipatterngi:

  • staatika edastamine.

Tegelikult on see praegu envoy puudub vahemälu tugi. Google'i mehed püüavad seda parandada. Idee rakendada see ühekordselt envoy kõiki detaile (pealkirjade loomine) RFC vastavusest ja teha konkreetsete rakenduste jaoks liides. Aga seni pole see isegi alfa, arhitektuur on arutelul, PR avatud (samal ajal, kui ma artiklit kirjutasin, mergiti PR, kuid see punkt on endiselt aktuaalne).

Ja seni kasutage staatika jaoks nginx'i.

  • Staatiline konfiguratsioon.

Seda saab kasutada, kuid envoy see ei olnud selleks loodud. Staatilise konfiguratsiooni võimalused ei tule esile. Asju on palju:

Konfiguratsiooni redigeerides yaml'is, eksite te, pahandate arendajate pärast liialdamise tõttu ja arvate, et nginx'i/haproxy konfiguratsioonid, kuigi vähem struktureeritud, on selgemad. Just see ongi asja tuum. Nginx'i ja Haproxy konfiguratsioon loodi käsitsi redigeerimiseks, kuid envoy koodi genereerimiseks. Kõik konfiguratsioon on kirjeldatud protobuf, genereerides selle proto failide põhjal, on viga palju keerulisem.

Canary, b/g juurutamise stsenaariumid ja palju muud rakendatakse korralikult ainult dünaamilises konfiguratsioonis. Ma ei ütle, et seda ei saa staatikas teha, me kõik teeme seda. Kuid selleks on vaja palju leevendusi, ükskõik millises tasakaalustajas, envoy sealhulgas.

Situatsioonid, kus Envoy on asendamatu:

  • Liiklusjaotus keerulistes ja dünaamilistes süsteemides. Siia kuulub service mesh, kuid see ei piirne vaid sellega.
  • Vajadus hajutatud jälgimise, keerulise autoriseerimise või muu jaoks, mis on olemas envoy välja antud või mugavalt rakendatav, samas kui nginx/haproxy puhul tuleb end lua ja kahtlaste pluginatega ümbritseda.

Mõlemad peavad vajadusel tagama kõrge jõudluse.

Kuidas see toimib

Envoy jagatakse binaaridena ainult docker-pildina. Pildis on juba näidis staatilisest konfiguratsioonist. Kuid meid huvitab see ainult struktuuri mõistmiseks.

envoy.yaml staatiline konfiguratsioon

staatilised_resursid:
  kuulajad:
  - nimi: kuulaja_0
    aadress:
      pesa_aadress:
        protokoll: TCP
        aadress: 0.0.0.0
        port_väärtus: 10000
    filtriahelad:
    - filtrid:
      - nimi: envoy.http_connection_manager
        tüpitud_konf:
          "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
          stat_parempool: ingress_http
          marsruudi_konf:
            nimi: kohalik_marsruut
            virtuaalsed_kodud:
            - nimi: kohalik_teenus
              domeenid: ["*"]
              marsruudid:
              - match:
                  eelis: "/"
                marsruut:
                  host_uusnimi: www.google.com
                  klaster: teenus_google
          http_filtrid:
          - nimi: envoy.router
  klastrid:
  - nimi: teenus_google
    ühendusaeg: 0.25s
    tüüp: LOGICAL_DNS
    # Kommenteeri välja järgmine rida, et testida v6 võrkudes
    dns_otsingu_periood: V4_ONLY
    koormuse_poliitika: ROUND_ROBIN
    koormuse_määr:
      klastrinimi: teenus_google
      lõpp-punktid:
      - lb_lõpp-punktid:
        - lõpp-punkt:
            aadress:
              pesa_aadress:
                aadress: www.google.com
                port_väärtus: 443
    transport_socket:
      nimi: envoy.transport_sockets.tls
      tüpitud_konf:
        "@type": type.googleapis.com/envoy.api.v2.auth.UpstreamTlsContext
        sni: www.google.com

Dünaamiline konfigureerimine

Millise probleemi me püüdleme? Ei saa lihtsalt konfiguratsiooni koormuse all uuesti laadida, tekivad "väikesed" probleemid:

  • Konfiguratsiooni valideerimine.

Konfiguratsioon võib olla suur, võib olla väga suur, kui me ülekoormame selle kõik korraga, siis tõuseb tõenäosus, et kuskil on viga.

  • Pikaajalised ühendused.

Uue kuulaja algatamisel tuleb hoolitseda vanadele ühendustele, kui muudatused toimuvad sageli ja on pikaajalised ühendused, tuleb leida kompromiss. Tere, kubernetes ingress nginx-il.

  • Aktiivsed tervisekontrollid.

Kui meil on aktiivsed tervisekontrollid, tuleks neid kõik uuesti kontrollida uue konfiguratsiooniga, enne kui suuname liiklust. Kui upstream'e on palju, nõuab see aega. Tere, haproxy.

Kuidas seda lahendatakse envoy, laadides konfiguratsiooni dünaamiliselt, pull mudeli järgi, saab selle jagada eraldi osadeks ja mitte uuesti algatada seda osa, mis ei muutunud. Näiteks kuulaja, mille uuesti algatamine on kallis, ja see muutub harva.

Konfiguratsioon envoy (ülevalt failist) sisaldab järgmisi üksusi:

  • listener — kuulaja, mis on seotud teatud ip/portiga
  • virtual host — virtuaalne host domeeninime järgi
  • mars — tasakaalustamise reegel
  • cluster — upstream'ide rühm tasakaalustamise parameetritega
  • endpoint — upstream'i instantsi aadress

Iga neid entiteete ning mõned muud saab dünaamiliselt täita, selleks peab konfiguratsioonis olema määratud teenuse aadress, kust konfi saadakse. Teenus võib olla REST või gRPC, eelistatult kasutada gRPC-d.

Teenuseid nimetatakse vastavalt: LDS, VHDS, RDS, CDS ja EDS. Saate kombineerida staatilist ja dünaamilist konfiguratsiooni, piiranguga, et dünaamilist ressurssi ei saa määrata staatiliselt.

Enamikku ülesandeid saab lahendada, rakendades viimase kolme teenuse, mida nimetatakse ADS (Kogutud Avastus Teenus), jaoks. java ja gO-l on olemas valmis gRPC dataplane'i rakendus, millega piisab vaid objekti täitmisest oma allikast.

Konfiguratsioon omandab järgmise kuju:

envoy.yaml dünaamiline konfiguratsioon

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

Käivitamisel kuvatakse järgmine: envoy selle konfiguratsiooniga ühendub ta juhtimistasandiga ja proovib küsida RDS, CDS ja EDS konfiguratsiooni. Kuidas toimub suhtluse protsess on kirjeldatud siit.

Lühidalt öeldes, envoy saab ta päringu, milles on määratud küsitava ressursi tüüp, versioon ja sõlme parameetrid. Vastuseks saab ta ressursi ja versiooni; kui juhtimistasandil versioon ei ole muutunud, siis ta ei vasta.
On 4 võimalust suhtlemiseks:

  • Üks gRPC voog kõikide ressursitüüpide jaoks, saadetakse kogu ressursi olek.
  • Erinevad vood, täielik olek.
  • Üks voog, inkrementaalne olek.
  • Erinevad vood, inkrementeeritud olek.

Inkremeneeritud xDS vähendab liiklust control-plane'i ja envoy, see on oluline suurte konfiguratsioonide puhul. Kuid see keerukaks muudab suhtlemist, kus päringus edastatakse ressursside loetelu, millele tuleb tellimusest lahkuda ja millele tuleb liituda.

Meie näites kasutatakse ADS-i — üks voog RDS-i, CDS-i, EDS-i ja mitte-inkrementeeritud režiimis. Inkremeneeritud režiimi aktiveerimiseks tuleb määrata api_type: DELTA_GRPC

Kuna päringus on sõlme parameetrid, saame control-plane’i suunata erinevaid ressursse erinevatele instantsidele envoy, see on mugav service mesh'i ehitamiseks.

Küte

VDS-l on võimalik installida: envoy käivitamisel või uue konfiguratsiooni seadmisel control-plane'ilt algab ressursside küte. See jaguneb listener'i kütte ja klasteri kütte vahel. Esimene käivitub RDS/LDS muudatuste korral, teine CDS/EDS muudatuste korral. See tähendab, et kui muutuvad ainult upstream'id, ei luleta listenerit uuesti.

Küpsetamise protsessis oodatakse sõltuvaid ressursse control-plane'ilt ajutise ajavahemiku jooksul. Kui ajutine periood on möödas, ei õnnestu initsialiseerimine, uus listener ei hakka porti kuulama.
Algoritm initsialiseerimiseks: EDS, CDS, aktiivne tervisekontroll, RDS, LDS. Kui aktiivsed tervisekontrollid on sisse lülitatud, suunatakse liiklus ülemisse voogu alles pärast ühte edukat tervisekontrolli.

Kui kuulaja on uuesti loodud, läheb vana seisundisse DRAIN ja eemaldatakse pärast kõikide ühenduste sulgemist või ajaülemuse möödumist. --drain-time-s, vaikimisi 10 minutit.

Jätkub.

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster