I dërguari. 1. Hyrje

pershendetje! Ky është një artikull i shkurtër që i përgjigjet pyetjeve: "çfarë është i dërguari?", "Pse është i nevojshëm?" dhe "ku të filloni?".

Çfarë është kjo

Envoy është një balancues L4-L7 i shkruar në C++, i fokusuar në performancën dhe disponueshmërinë e lartë. Nga njëra anë, ky është në një farë mënyre një analog i nginx dhe haproksi, i krahasueshëm në performancë me to. Nga ana tjetër, ai është më i orientuar drejt arkitekturës së mikroservices dhe ka funksionalitet jo më të keq se balancuesit e java dhe go, si zuul ose traefik.

Tabela e krahasimit të haproksi/nginx/i dërguar, nuk pretendon të jetë e vërteta absolute, por jep një pamje të përgjithshme.

nginx
haproksi
i dërguar
trafik

yjet në github
11.2k/pasqyrë
1.1k/pasqyrë
12.4k
27.6k

shkruar në
C
C
C + +
go

API
jo
vetëm prizë/shty
rrafsh i të dhënave/tërheq
tërheq

kontroll shëndetësor aktiv
jo
po
po
po

Gjurmimi i hapur
shtojcë e jashtme
jo
po
po

J.W.T.
shtojcë e jashtme
jo
po
jo

zgjerim
Lua/C
Lua/C
Lua/C++
jo

Çfarë për

Ky është një projekt i ri, ka shumë gjëra që mungojnë, disa në alfa të hershme. Por i dërguar, edhe për shkak të rinisë së tij, po zhvillohet me shpejtësi dhe tashmë ka shumë veçori interesante: konfigurim dinamik, shumë filtra të gatshëm, një ndërfaqe e thjeshtë për të shkruar filtrat tuaj.
Fushat e aplikimit rrjedhin nga kjo, por së pari ka 2 antimodele:

  • Tërheqje statike.

Fakti është se për momentin në i dërguar nuk ka mbështetje për ruajtjen e memories. Djemtë e Google po e provojnë këtë rregulloj. Ideja do të zbatohet një herë në i dërguar të gjitha hollësitë (titujt e kopshtit zoologjik) të pajtueshmërisë me RFC, dhe për implementime specifike bëni një ndërfaqe. Por tani për tani nuk është as alfa, arkitektura është në diskutim, PR hapur (ndërsa po shkruaja artikullin PR, PR ngriu, por kjo pikë është ende e rëndësishme).

Tani për tani, përdorni nginx për statikë.

  • Konfigurimi statik.

Mund ta përdorni, por i dërguar Nuk është ajo për të cilën është krijuar. Karakteristikat në një konfigurim statik nuk do të ekspozohen. Ka shumë momente:

Kur redaktoni konfigurimin në yaml, do të gaboni, do t'i qortoni zhvilluesit për folje dhe do të mendoni se konfigurimet nginx/haproxy, megjithëse më pak të strukturuara, janë më koncize. Kjo është pika. Konfigurimi i Nginx dhe Haproxy u krijua për redaktim me dorë, dhe i dërguar për gjenerim nga kodi. I gjithë konfigurimi përshkruhet në protobuf, gjenerimi i tij nga skedarët proto është shumë më i vështirë për të bërë një gabim.

Skenarët e vendosjes Canary, b/g dhe shumë më tepër zakonisht zbatohen vetëm në një konfigurim dinamik. Nuk po them që kjo nuk mund të bëhet në mënyrë statike, ne të gjithë e bëjmë. Por për këtë ju duhet të vendosni paterica, në cilindo nga balancuesit, në i dërguar përfshirë.

Detyrat për të cilat i Dërguari është i domosdoshëm:

  • Balancimi i trafikut në sisteme komplekse dhe dinamike. Kjo përfshin rrjetën e shërbimit, por nuk është domosdoshmërisht e vetmja.
  • Nevoja për funksionalitet të gjurmimit të shpërndarë, autorizim kompleks ose funksione të tjera që disponohen në i dërguar jashtë kutisë ose të zbatuara në mënyrë të përshtatshme, por në nginx/haproxy ju duhet të jeni të rrethuar nga lua dhe shtojca të dyshimta.

Të dyja, nëse është e nevojshme, ofrojnë performancë të lartë.

Si punon kjo

I dërguari shpërndahet në binare vetëm si imazh doker. Imazhi tashmë përmban një shembull të një konfigurimi statik. Por ne jemi të interesuar për të vetëm për të kuptuar strukturën.

envoy.yaml konfigurim statik

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

Konfigurimi dinamik

Për cilin problem po kërkojmë zgjidhje? Ju nuk mund të rifreskoni konfigurimin e balancuesit të ngarkesës vetëm nën ngarkesë; do të shfaqen probleme "të vogla":

  • Vleresimi i konfigurimit.

Konfigurimi mund të jetë i madh, mund të jetë shumë i madh, nëse e mbingarkojmë të gjithë menjëherë, gjasat për një gabim diku rriten.

  • Lidhjet jetëgjata.

Kur filloni një dëgjues të ri, duhet të kujdeseni për lidhjet që funksionojnë në atë të vjetër; nëse ndryshimet ndodhin shpesh dhe ka lidhje jetëgjata, do t'ju duhet të kërkoni një kompromis. Përshëndetje, kubernetes hyjnë në nginx.

  • Kontrolle aktive shëndetësore.

Nëse kemi kontrolle aktive shëndetësore, duhet t'i kontrollojmë të gjitha në konfigurimin e ri përpara se të dërgojmë trafikun. Nëse ka shumë rrjedha të sipërme, kjo kërkon kohë. Përshëndetje haproksi.

Si zgjidhet kjo në i dërguarDuke e ngarkuar konfigurimin në mënyrë dinamike, sipas modelit të pishinës, mund ta ndani atë në pjesë të veçanta dhe të mos rifilloni pjesën që nuk ka ndryshuar. Për shembull, një dëgjues, i cili është i shtrenjtë për t'u rifilluar dhe ndryshon rrallë.

konfiguracion i dërguar (nga skedari i mësipërm) ka këto entitete:

  • dëgjues — dëgjues i varur në një ip/port të caktuar
  • host virtual - host virtual sipas emrit të domenit
  • rrugë - rregull balancimi
  • grumbull — një grup i rrjedhave të sipërme me parametra balancues
  • pika e fundit - adresa e shembullit në rrjedhën e sipërme

Secila prej këtyre entiteteve plus disa të tjera mund të plotësohet në mënyrë dinamike; për këtë, konfigurimi specifikon adresën e shërbimit nga ku do të merret konfigurimi. Shërbimi mund të jetë REST ose gRPC, preferohet gRPC.

Shërbimet emërtohen përkatësisht: LDS, VHDS, RDS, CDS dhe EDS. Ju mund të kombinoni konfigurimin statik dhe dinamik, me kufizimin që një burim dinamik nuk mund të specifikohet në një statik.

Për shumicën e detyrave, mjafton të zbatohen tre shërbimet e fundit, ato quhen ADS (Shërbimi i Zbulimit të Përmbledhur), për Java dhe shkoni atje është një zbatim i gatshëm i planit të të dhënave gRPC në të cilin ju vetëm duhet të plotësoni objektet nga burimi juaj.

Konfigurimi merr formën e mëposhtme:

envoy.yaml konfigurim dinamik

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

Në fillimin i dërguar me këtë konfigurim, ai do të lidhet me planin e kontrollit dhe do të përpiqet të kërkojë konfigurimin RDS, CDS dhe EDS. Përshkruhet se si ndodh procesi i ndërveprimit këtu.

Shkurtimisht, i dërguar dërgon një kërkesë që tregon llojin e burimit që kërkohet, versionin dhe parametrat e nyjës. Si përgjigje, ai merr një burim dhe një version; nëse versioni në planin e kontrollit nuk ka ndryshuar, ai nuk përgjigjet.
Ekzistojnë 4 opsione ndërveprimi:

  • Një transmetim gRPC për të gjitha llojet e burimeve, statusi i plotë i burimit dërgohet.
  • Perrenj te ndare ne gjendje te plote.
  • Një rrjedhë, gjendje në rritje.
  • Rrjedhat e ndara, gjendja në rritje.

Incremental xDS ju lejon të reduktoni trafikun midis planit të kontrollit dhe i dërguar, kjo është e rëndësishme për konfigurime të mëdha. Por kjo e ndërlikon ndërveprimin; kërkesa përmban një listë të burimeve për çregjistrim dhe abonim.

Shembulli ynë përdor ADS - një transmetim për RDS, CDS, EDS dhe modalitetin jo në rritje. Për të aktivizuar modalitetin rritës, duhet të specifikoni api_type: DELTA_GRPC

Meqenëse kërkesa përmban parametra të nyjeve, ne mund të dërgojmë burime të ndryshme në planin e kontrollit për raste të ndryshme i dërguar, kjo është e përshtatshme për ndërtimin e një rrjetë shërbimi.

warmup

Mbi i dërguar në fillim ose kur merrni një konfigurim të ri nga rrafshi i kontrollit, fillon procesi i ngrohjes së burimit. Ndahet në ngrohjen e dëgjuesit dhe ngrohjen e grupit. E para lëshohet kur ka ndryshime në RDS/LDS, e dyta kur CDS/EDS. Kjo do të thotë që nëse ndryshojnë vetëm rrjedhat e sipërme, dëgjuesi nuk rikrijohet.

Gjatë procesit të ngrohjes, priten burime të varura nga rrafshi i kontrollit gjatë kohës së ndërprerjes. Nëse ndodh skadimi, inicializimi nuk do të jetë i suksesshëm dhe dëgjuesi i ri nuk do të fillojë të dëgjojë në portë.
Urdhri i inicializimit: EDS, CDS, kontroll shëndetësor aktiv, RDS, LDS. Me kontrollet shëndetësore aktive të aktivizuara, trafiku do të shkojë në rrjedhën e sipërme vetëm pas një kontrolli të suksesshëm shëndetësor.

Nëse dëgjuesi është rikrijuar, ai i vjetër kalon në gjendjen DRAIN dhe do të fshihet pasi të mbyllen të gjitha lidhjet ose të skadojë afati --drain-time-s, e paracaktuar 10 minuta.

Të vazhdohet.

Burimi: www.habr.com

Shto një koment