Inviatu. 1. Introduzione

Saluti ! Questu hè un brevi articulu chì risponde à e dumande: "chì hè l'inviatu?", "Perchè hè necessariu?" è "induve principià?".

Cumu hè questu

Envoy hè un equilibratore L4-L7 scrittu in C ++, focu annantu à un altu rendiment è dispunibilità. Da una banda, questu hè in qualchì modu un analogu di nginx è haproxy, paragunabili in rendiment à elli. Per d 'altra banda, hè più orientatu versu l'architettura di microserviziu è hà una funziunalità micca peggiu di java and go balancers, cum'è zuul o traefik.

Tavola di paragone di haproxy/nginx/envoy, ùn pretende micca esse a verità assoluta, ma dà una stampa generale.

nginx
haproxy
mandatu
traefic

stelle nantu à github
11.2 k / specchiu
1.1 k / specchiu
12.4k
27.6k

scrittu in
C
C
C ++
go

API
micca
presa solu / push
dataplane / pull
pull

cuntrollu di salute attivu
micca


Apertura traccia
plugin esternu
micca

J.W.T.
plugin esternu
micca

micca

allargamentu
Lua/C
Lua/C
Lua/C++
micca

Perchè!

Questu hè un prughjettu ghjovanu, ci sò parechje cose chì mancanu, alcune in l'alfa iniziale. Ma mandatu, ancu per via di a so ghjuventù, si sviluppa rapidamente è hà digià parechje caratteristiche interessanti: cunfigurazione dinamica, parechji filtri pronti, una interfaccia simplice per scrive i vostri filtri.
I campi d'applicazione seguitanu da questu, ma prima ci sò 2 antipatterns:

  • Recul staticu.

U fattu hè chì in u mumentu in mandatu senza supportu di cache. I ragazzi di Google stanu pruvatu questu di riparà. L'idea serà implementata una volta in mandatu tutte e suttilità (intestazioni di zoo) di a conformità RFC, è per implementazioni specifiche facenu una interfaccia. Ma per avà ùn hè mancu alfa, l'architettura hè in discussione, PR apertu (mentre scrivu l'articulu PR, u PR si congelava, ma questu puntu hè sempre pertinente).

Per avà, utilizate nginx per statics.

  • Cunfigurazione statica.

Pudete aduprà, ma mandatu Ùn hè micca per quessa hè statu creatu. E caratteristiche in una cunfigurazione statica ùn saranu micca esposti. Ci sò parechji mumenti:

Quandu editate a cunfigurazione in yaml, vi sbagliate, scold the developers for verbosity and think that the nginx/haproxy configs, ancu s'ellu hè menu strutturatu, sò più cuncisi. Hè u puntu. A cunfigurazione di Nginx è Haproxy hè stata creata per edità a manu, è mandatu per a generazione da u codice. Tutta a cunfigurazione hè descritta in protobuf, generà da i schedarii proto hè assai più difficiule di fà un sbagliu.

I scenarii di implementazione di Canary, b / g è assai di più sò generalmente implementati solu in una cunfigurazione dinamica. Ùn dicu micca chì questu ùn pò micca esse fattu staticamente, tutti facemu. Ma per questu avete bisognu di mette in crutches, in qualsiasi di i balancers, in mandatu cumpresi.

Compiti per i quali Envoy hè indispensabile:

  • Bilanciamentu di u trafficu in sistemi cumplessi è dinamichi. Questu include a rete di serviziu, ma ùn hè micca necessariamente l'unicu.
  • A necessità di funziunalità di traccia distribuita, l'autorizazione cumplessa o altre funziunalità chì hè dispunibule in mandatu fora di a scatula o cunvene implementatu, ma in nginx/haproxy avete bisognu à esse circundatu da lua è plugins dubbiosi.

Tutti dui, se ne necessariu, furnisce un altu rendiment.

Cumu serà ch'ella ùn stu travagliu

Envoy hè distribuitu in binari solu cum'è una maghjina docker. L'imaghjini cuntene digià un esempiu di una cunfigurazione statica. Ma ci interessa solu per capiscenu a struttura.

cunfigurazione statica envoy.yaml

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

Cunfigurazione dinamica

À quale prublema circhemu una suluzione ? Ùn pudete micca solu ricaricà a cunfigurazione di l'equilibriu di carica sottu carica; "picculi" prublemi sorgiranu:

  • Validazione di cunfigurazione.

A cunfigurazione pò esse grande, pò esse assai grande, s'ellu ci sopracarcà tuttu in una volta, e probabilità di un errore in qualchì locu aumentanu.

  • Cunnessioni longu.

Quandu si inizializza un novu ascultore, avete bisognu di piglià cura di e cunnessione chì currenu nantu à u vechju; se i cambiamenti accadenu spessu è ci sò cunnessione longu, vi tuccherà à circà un cumprumissu. Hola, kubernetes ingress in nginx.

  • Cuntrolli di salute attivi.

Se avemu cuntrolli di salute attivi, avemu bisognu di verificà tutti in a nova cunfigurazione prima di mandà u trafficu. Se ci sò assai upstreams, questu richiede u tempu. Ciao haproxy.

Cumu si risolve questu in mandatuCaricà a cunfigurazione dinamicamente, secondu u mudellu di piscina, pudete dividisce in parte separata è micca re-initialize a parte chì ùn hà micca cambiatu. Per esempiu, un listener, chì hè caru per reinizializà è raramente cambia.

Cunfigurazione mandatu (da u schedariu sopra) hà e seguenti entità:

  • ascultadore - listener appiccicatu à un IP / portu specificu
  • host virtuale - host virtuale per nome di duminiu
  • a strada - regula d'equilibriu
  • intrecciu - un gruppu di upstreams cù paràmetri di equilibriu
  • endpoint - indirizzu di l'istanza upstream

Ciascuna di queste entità più alcune altre pò esse cumpletu dinamicamente; per questu, a cunfigurazione specifica l'indirizzu di u serviziu da induve a cunfigurazione serà ricevuta. U serviziu pò esse REST o gRPC, gRPC hè preferibile.

I servizii sò chjamati rispettivamente: LDS, VHDS, RDS, CDS è EDS. Pudete combine cunfigurazione statica è dinamica, cù a limitazione chì una risorsa dinamica ùn pò micca esse specificata in una statica.

Per a maiò parte di i travaglii, hè abbastanza per implementà l'ultimi trè servizii, sò chjamati ADS (Aggregated Discovery Service), per java è andate ci hè una implementazione pronta di gRPC dataplane in quale avete bisognu di riempie l'uggetti da a vostra fonte.

A cunfigurazione piglia a forma seguente:

cunfigurazione dinamica envoy.yaml

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

À l'iniziu mandatu cù sta cunfigurazione, hà da cunnette à u pianu di cuntrollu è pruvate à dumandà a cunfigurazione RDS, CDS è EDS. Cume u prucessu di interazzione hè descrittu ccà.

In breve, mandatu manda una dumanda indicà u tipu di risorsa chì hè dumandatu, a versione è i paràmetri di u node. In risposta, riceve una risorsa è una versione; se a versione in u pianu di cuntrollu ùn hè micca cambiatu, ùn risponde micca.
Ci sò 4 opzioni di interazione:

  • Un flussu gRPC per tutti i tipi di risorse, u statu sanu di a risorsa hè mandatu.
  • Flussi separati, cundizione piena.
  • Un flussu, statu incrementale.
  • Flussi separati, statu incrementale.

Incremental xDS permette di riduce u trafficu trà u pianu di cuntrollu è mandatu, questu hè pertinente per cunfigurazioni grandi. Ma complica l'interazzione; a dumanda cuntene una lista di risorse per annullamentu è abbonamentu.

U nostru esempiu usa ADS - un flussu per RDS, CDS, EDS è modalità non incrementali. Per attivà u modu incrementale, avete bisognu di specificà api_type: DELTA_GRPC

Siccomu a dumanda cuntene parametri di node, pudemu mandà diverse risorse à u pianu di cuntrollu per diverse istanze mandatu, questu hè convenientu per custruisce una rete di serviziu.

Riscaldà

nantu mandatu à l'iniziu o quandu riceve una nova cunfigurazione da u pianu di cuntrollu, u prucessu di riscaldamentu di risorse hè lanciatu. Hè divisu in u riscaldamentu di l'ascoltatore è u riscaldamentu di cluster. U primu hè lanciatu quandu ci sò cambiamenti in RDS / LDS, u sicondu quandu CDS / EDS. Questu significa chì s'ellu cambia solu upstreams, l'ascultore ùn hè micca ricreatu.

Duranti u prucessu di warm-up, i risorsi dipendenti sò previsti da u pianu di cuntrollu durante u timeout. Se u timeout si verifica, l'inizializazione ùn serà micca successu è u novu listener ùn principia micca à sente in u portu.
Ordine di inizializazione: EDS, CDS, cuntrollu di salute attiva, RDS, LDS. Cù i cuntrolli di salute attivi attivati, u trafficu andarà a monte solu dopu un cuntrollu di salute successu.

Se l'ascoltatore hè statu ricreatu, u vechju passa in u statu DRAIN è serà sguassatu dopu chì tutte e cunnessione sò chjuse o u timeout scade. --drain-time-s, default 10 minuti.

Per esse continuatu.

Source: www.habr.com

Add a comment