sugo. 1. Panimula

Pagbati! Ito ay isang maikling artikulo na sumasagot sa mga tanong: "ano ang sugo?", "bakit ito kailangan?" at "saan magsisimula?".

Ano ito?

Ang Envoy ay isang L4-L7 balancer na nakasulat sa C++, na nakatuon sa mataas na performance at availability. Sa isang banda, ito ay sa ilang paraan ay isang analogue ng nginx at haproxy, na maihahambing sa pagganap sa kanila. Sa kabilang banda, mas nakatuon ito sa arkitektura ng microservice at may functionality na hindi mas masahol kaysa sa java and go balancers, tulad ng zuul o traefik.

Talaan ng paghahambing ng haproxy/nginx/envoy, hindi nito inaangkin na ang ganap na katotohanan, ngunit nagbibigay ng pangkalahatang larawan.

nginx
haproxy
nagpadala
traefik

mga bituin sa github
11.2k/salamin
1.1k/salamin
12.4k
27.6k

nakasulat sa
C
C
C + +
go

API
hindi
socket lang/push
dataplane/pull
paghila

aktibong pagsusuri sa kalusugan
hindi
oo
oo
oo

Buksan ang pagsubaybay
panlabas na plugin
hindi
oo
oo

J.W.T.
panlabas na plugin
hindi
oo
hindi

palugit
Lua/C
Lua/C
Lua/C++
hindi

Ano para sa

Ito ay isang batang proyekto, maraming bagay ang nawawala, ang ilan ay nasa unang bahagi ng alpha. Pero nagpadala, dahil din sa kabataan nito, ay mabilis na umuunlad at mayroon nang maraming kawili-wiling mga tampok: dynamic na pagsasaayos, maraming handa na mga filter, isang simpleng interface para sa pagsulat ng iyong sariling mga filter.
Ang mga lugar ng aplikasyon ay sumusunod mula dito, ngunit una ay mayroong 2 antipattern:

  • Static recoil.

Ang katotohanan ay na sa sandaling ito sa nagpadala walang suporta sa pag-cache. Sinusubukan ito ng mga taong Google upang ayusin. Ang ideya ay ipapatupad sa sandaling pumasok nagpadala lahat ng subtleties (zoo header) ng RFC compliance, at para sa mga partikular na pagpapatupad ay gumawa ng interface. Ngunit sa ngayon ay hindi pa ito alpha, ang arkitektura ay pinag-uusapan, PR bukas (habang isinusulat ko ang artikulo sa PR, ang PR ay nagyelo, ngunit ang puntong ito ay may kaugnayan pa rin).

Sa ngayon, gumamit ng nginx para sa statics.

  • Static na pagsasaayos.

Maaari mong gamitin ito, ngunit nagpadala Hindi para saan ito nilikha. Hindi malalantad ang mga feature sa isang static na configuration. Mayroong maraming mga sandali:

Kapag nag-edit ng configuration sa yaml, magkakamali ka, pagalitan ang mga developer para sa verbosity at isipin na ang nginx/haproxy configs, kahit na hindi gaanong structured, ay mas maigsi. Iyon ang punto. Ang configuration ng Nginx at Haproxy ay nilikha para sa pag-edit sa pamamagitan ng kamay, at nagpadala para sa henerasyon mula sa code. Ang buong configuration ay inilarawan sa protobuf, ang pagbuo nito mula sa mga proto file ay mas mahirap magkamali.

Ang Canary, b/g deployment scenario at marami pang iba ay karaniwang ipinapatupad lamang sa isang dynamic na configuration. Hindi ko sinasabi na hindi ito maaaring gawin nang static, ginagawa nating lahat. Ngunit para dito kailangan mong ilagay sa saklay, sa alinman sa mga balancer, sa nagpadala kasama ang.

Mga gawain kung saan kailangang-kailangan ang Envoy:

  • Pagbalanse ng trapiko sa kumplikado at dynamic na mga sistema. Kabilang dito ang mesh ng serbisyo, ngunit hindi ito ang isa lamang.
  • Ang pangangailangan para sa distributed tracing functionality, complex authorization o iba pang functionality na available sa nagpadala out of the box o maginhawang ipinatupad, ngunit sa nginx/haproxy kailangan mong mapalibutan ng lua at kahina-hinalang mga plugin.

Pareho, kung kinakailangan, ay nagbibigay ng mataas na pagganap.

Как это Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚

Ang Envoy ay ipinamamahagi sa mga binary lamang bilang isang docker na imahe. Ang larawan ay naglalaman na ng isang halimbawa ng isang static na configuration. Ngunit interesado kami dito para lamang sa pag-unawa sa istraktura.

envoy.yaml static na configuration

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

Dynamic na pagsasaayos

Anong problema ang hinahanap nating solusyon? Hindi mo lang mai-reload ang configuration ng load balancer sa ilalim ng load; "maliit" na mga problema ay lilitaw:

  • Pagpapatunay ng configuration.

Ang config ay maaaring malaki, maaari itong maging napakalaki, kung labis nating i-overload ang lahat ng ito nang sabay-sabay, ang mga pagkakataon ng isang error sa isang lugar ay tumataas.

  • Mga pangmatagalang koneksyon.

Kapag nagpapasimula ng isang bagong tagapakinig, kailangan mong alagaan ang mga koneksyon na tumatakbo sa luma; kung ang mga pagbabago ay madalas mangyari at may mga pangmatagalang koneksyon, kailangan mong maghanap ng kompromiso. Hello, kubernetes ingress sa nginx.

  • Mga aktibong pagsusuri sa kalusugan.

Kung mayroon kaming mga aktibong pagsusuri sa kalusugan, kailangan naming i-double-check ang lahat ng ito sa bagong config bago magpadala ng trapiko. Kung mayroong maraming upstream, ito ay tumatagal ng oras. Hello haproxy.

Paano ito naresolba sa nagpadalaSa pamamagitan ng pabago-bagong paglo-load ng config, ayon sa modelo ng pool, maaari mong hatiin ito sa magkakahiwalay na bahagi at hindi muling simulan ang bahaging hindi nagbago. Halimbawa, ang isang tagapakinig, na mahal upang muling simulan at bihirang magbago.

Configuration nagpadala (mula sa file sa itaas) ay may mga sumusunod na entity:

  • nakikinig β€” tagapakinig na nakabitin sa isang partikular na ip/port
  • virtual host - virtual host sa pamamagitan ng domain name
  • ruta - panuntunan sa pagbabalanse
  • kumpol β€” isang pangkat ng mga upstream na may mga parameter ng pagbabalanse
  • endpoint β€” upstream na instance address

Ang bawat isa sa mga entity na ito at ilang iba pa ay maaaring punan nang dynamic; para dito, tinutukoy ng configuration ang address ng serbisyo kung saan matatanggap ang config. Ang serbisyo ay maaaring REST o gRPC, mas gusto ang gRPC.

Ang mga serbisyo ay pinangalanan ayon sa pagkakabanggit: LDS, VHDS, RDS, CDS at EDS. Maaari mong pagsamahin ang static at dynamic na configuration, na may limitasyon na hindi maaaring tukuyin ang isang dynamic na mapagkukunan sa isang static.

Para sa karamihan ng mga gawain, sapat na upang ipatupad ang huling tatlong serbisyo, ang mga ito ay tinatawag na ADS (Aggregated Discovery Service), para sa Dyaba at pumunta doon ay isang handa na pagpapatupad ng gRPC dataplane kung saan kailangan mo lamang na punan ang mga bagay mula sa iyong pinagmulan.

Ang pagsasaayos ay tumatagal ng sumusunod na anyo:

envoy.yaml dynamic na configuration

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

Sa pagsisimula nagpadala gamit ang config na ito, ito ay kumonekta sa control-plane at subukang humiling ng RDS, CDS at EDS configuration. Inilalarawan kung paano nangyayari ang proseso ng pakikipag-ugnayan dito.

Sa madaling salita, nagpadala nagpapadala ng kahilingan na nagsasaad ng uri ng resource na hinihiling, ang bersyon at mga parameter ng node. Bilang tugon, tumatanggap ito ng mapagkukunan at isang bersyon; kung ang bersyon sa control-plane ay hindi nagbago, hindi ito tumutugon.
Mayroong 4 na opsyon sa pakikipag-ugnayan:

  • Isang stream ng gRPC para sa lahat ng uri ng mga mapagkukunan, ang buong katayuan ng mapagkukunan ay ipinadala.
  • Hiwalay na mga batis, buong kondisyon.
  • Isang stream, incremental na estado.
  • Hiwalay na mga stream, incremental na estado.

Ang Incremental xDS ay nagpapahintulot sa iyo na bawasan ang trapiko sa pagitan ng control-plane at nagpadala, ito ay may kaugnayan para sa malalaking configuration. Ngunit ginagawa nitong kumplikado ang pakikipag-ugnayan; ang kahilingan ay naglalaman ng isang listahan ng mga mapagkukunan para sa pag-unsubscribe at pag-subscribe.

Gumagamit ang aming halimbawa ng ADS - isang stream para sa RDS, CDS, EDS at non-incremental mode. Upang paganahin ang incremental mode, kailangan mong tukuyin api_type: DELTA_GRPC

Dahil ang kahilingan ay naglalaman ng mga parameter ng node, maaari kaming magpadala ng iba't ibang mga mapagkukunan sa control-plane para sa iba't ibang mga pagkakataon nagpadala, ito ay maginhawa para sa pagbuo ng isang service mesh.

Pag-init

Sa nagpadala sa startup o kapag tumatanggap ng bagong configuration mula sa control-plane, inilulunsad ang resource warmup process. Nahahati ito sa listener warmup at cluster warmup. Ang una ay inilunsad kapag may mga pagbabago sa RDS/LDS, ang pangalawa kapag CDS/EDS. Nangangahulugan ito na kung ang mga upstream lamang ang nagbabago, ang nakikinig ay hindi muling nilikha.

Sa panahon ng proseso ng warm-up, ang mga umaasa na mapagkukunan ay inaasahan mula sa control-plane sa panahon ng timeout. Kung nangyari ang timeout, hindi magiging matagumpay ang pagsisimula at hindi magsisimulang makinig ang bagong tagapakinig sa port.
Order ng pagsisimula: EDS, CDS, aktibong pagsusuri sa kalusugan, RDS, LDS. Kapag naka-enable ang mga aktibong pagsusuri sa kalusugan, aakyat lang ang trapiko pagkatapos ng isang matagumpay na pagsusuri sa kalusugan.

Kung muling ginawa ang tagapakinig, ang luma ay mapupunta sa DRAIN na estado at tatanggalin pagkatapos maisara ang lahat ng koneksyon o mag-expire ang timeout --drain-time-s, default na 10 minuto.

Upang magpatuloy.

Pinagmulan: www.habr.com

Magdagdag ng komento