Elçi. 1. Giriş

Selamlar! “Elçi nedir?”, “Neden gereklidir?” sorularına cevap veren kısa bir yazıdır. ve "nereden başlamalı?".

Bu ne

Envoy, C++ ile yazılmış, yüksek performans ve kullanılabilirliğe odaklanan bir L4-L7 dengeleyicidir. Bir yandan, bu bir şekilde nginx ve haproxy'nin bir analoğudur ve performans açısından onlarla karşılaştırılabilir. Öte yandan, daha çok mikro hizmet mimarisine yöneliktir ve zuul veya traefik gibi java ve go dengeleyicilerden daha kötü bir işlevselliğe sahip değildir.

haproxy/nginx/envoy karşılaştırma tablosu, mutlak gerçek olduğunu iddia etmez ancak genel bir resim verir.

nginx
haproksi
gönderilen
Traefik

github'daki yıldızlar
11.2k/ayna
1.1k/ayna
12.4k
27.6k

yazılmış
C
C
C + +
go

API
hayır
yalnızca soket/itme
veri düzlemi/çekme
Çek

aktif sağlık kontrolü
hayır
evet
evet
evet

İzlemeyi aç
harici eklenti
hayır
evet
evet

J.W.T.
harici eklenti
hayır
evet
hayır

uzatma
Lua/C
Lua/C
Lua/C++
hayır

Neden

Bu genç bir proje, pek çok şey eksik, bazıları erken alfa aşamasında. Ancak gönderilen, ayrıca gençliğinden dolayı hızla gelişiyor ve halihazırda birçok ilginç özelliğe sahip: dinamik yapılandırma, birçok hazır filtre, kendi filtrelerinizi yazmak için basit bir arayüz.
Uygulama alanları bundan sonra gelir, ancak ilk önce 2 anti-model vardır:

  • Statik geri tepme.

Gerçek şu ki, şu anda gönderilen önbellekleme desteği yok. Google adamları bunu deniyor исправить. Fikir bir kez hayata geçirilecek gönderilen RFC uyumluluğunun tüm inceliklerini (hayvanat bahçesi başlıkları) ve belirli uygulamalar için bir arayüz oluşturur. Ama şimdilik alfa bile değil, mimarisi tartışılıyor. PR açık (PR makalesini yazarken PR dondu, ancak bu nokta hala geçerli).

Şimdilik statik için nginx'i kullanın.

  • Statik konfigürasyon.

Kullanabilirsin ama gönderilen Bunun için yaratılmadı. Statik yapılandırmadaki özellikler gösterilmez. Pek çok an var:

Yaml'de yapılandırmayı düzenlerken yanılacak, geliştiricileri ayrıntılardan dolayı azarlayacak ve nginx/haproxy yapılandırmalarının daha az yapılandırılmış olmasına rağmen daha kısa olduğunu düşüneceksiniz. Önemli olan bu. Nginx ve Haproxy'nin yapılandırması elle düzenleme için oluşturuldu ve gönderilen koddan nesil için. Yapılandırmanın tamamı şurada açıklanmıştır: Protobuf, onu protokol dosyalarından oluştururken hata yapmak çok daha zordur.

Canary, b/g dağıtım senaryoları ve çok daha fazlası normalde yalnızca dinamik bir yapılandırmada uygulanır. Bunun statik olarak yapılamayacağını söylemiyorum, hepimiz yapıyoruz. Ancak bunun için herhangi bir dengeleyiciye koltuk değneği takmanız gerekir. gönderilen dahil.

Elçinin vazgeçilmez olduğu görevler:

  • Karmaşık ve dinamik sistemlerde trafik dengeleme. Buna servis ağı da dahildir ancak tek ağ olması şart değildir.
  • Dağıtılmış izleme işlevine, karmaşık yetkilendirmeye veya mevcut diğer işlevlere duyulan ihtiyaç gönderilen kutudan çıktığı gibi veya uygun bir şekilde uygulanmış, ancak nginx/haproxy'de lua ve şüpheli eklentilerle çevrili olmanız gerekir.

Gerektiğinde her ikisi de yüksek performans sağlar.

Bu nasıl çalışıyor

Elçi ikili dosyalar halinde yalnızca liman işçisi görüntüsü olarak dağıtılır. Resim zaten statik bir konfigürasyonun bir örneğini içeriyor. Ancak biz onunla yalnızca yapıyı anlamak için ilgileniyoruz.

envoy.yaml statik yapılandırması

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

Dinamik konfigürasyon

Hangi soruna çözüm arıyoruz? Yük dengeleyici yapılandırmasını yük altında yeniden yükleyemezsiniz; "küçük" sorunlar ortaya çıkacaktır:

  • Yapılandırma doğrulaması.

Config büyük olabilir, çok büyük olabilir, hepsini bir anda aşırı yüklersek bir yerde hata yapma ihtimali artar.

  • Uzun ömürlü bağlantılar.

Yeni bir dinleyiciyi başlatırken, eskisinde çalışan bağlantılara dikkat etmeniz gerekir; eğer değişiklikler sık ​​​​sık oluyorsa ve uzun ömürlü bağlantılar varsa, bir uzlaşma aramanız gerekecektir. Merhaba, Kubernetes'in nginx'e girişi.

  • Aktif sağlık kontrolleri.

Etkin sağlık kontrollerimiz varsa, trafiği göndermeden önce yeni yapılandırmada hepsini tekrar kontrol etmemiz gerekir. Çok fazla yukarı akış varsa, bu zaman alır. Merhaba haproxy.

Bu nasıl çözülür? gönderilenYapılandırmayı havuz modeline göre dinamik olarak yükleyerek ayrı parçalara bölebilir ve değişmeyen kısmı yeniden başlatamazsınız. Örneğin, yeniden başlatılması pahalı olan ve nadiren değişen bir dinleyici.

Yapılandırma gönderilen (yukarıdaki dosyadan) aşağıdaki varlıklara sahiptir:

  • dinleyici — belirli bir IP/bağlantı noktasında asılı kalan dinleyici
  • sanal ana bilgisayar - alan adına göre sanal konak
  • degistirebilirsin. - dengeleme kuralı
  • küme — dengeleme parametrelerine sahip bir grup yukarı akış
  • Son nokta — yukarı akış örnek adresi

Bu varlıkların her biri ve diğerleri dinamik olarak doldurulabilir; bunun için konfigürasyon, konfigürasyonun alınacağı servisin adresini belirtir. Hizmet REST veya gRPC olabilir, gRPC tercih edilir.

Hizmetler sırasıyla LDS, VHDS, RDS, CDS ve EDS olarak adlandırılır. Statik ve dinamik yapılandırmayı, dinamik bir kaynağın statik bir kaynakta belirtilmemesi sınırlamasıyla birleştirebilirsiniz.

Çoğu görev için, ADS (Toplu Keşif Hizmeti) olarak adlandırılan son üç hizmeti uygulamak yeterlidir. Java ve sadece kaynağınızdaki nesneleri doldurmanız gereken hazır bir gRPC veri düzlemi uygulaması var.

Yapılandırma aşağıdaki formu alır:

envoy.yaml dinamik yapılandırması

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

Başlangıçta gönderilen bu yapılandırmayla kontrol düzlemine bağlanacak ve RDS, CDS ve EDS yapılandırmasını istemeye çalışacaktır. Etkileşim sürecinin nasıl gerçekleştiği anlatılıyor burada.

Kısacası gönderilen talep edilen kaynağın türünü, düğümün sürümünü ve parametrelerini belirten bir istek gönderir. Yanıt olarak bir kaynak ve sürüm alır; kontrol düzlemindeki sürüm değişmediyse yanıt vermez.
4 etkileşim seçeneği vardır:

  • Tüm kaynak türleri için tek bir gRPC akışı, kaynağın tam durumu gönderilir.
  • Ayrı akışlar, tam durum.
  • Tek akış, artımlı durum.
  • Ayrı akışlar, artımlı durum.

Artımlı xDS, kontrol düzlemi ile kontrol düzlemi arasındaki trafiği azaltmanıza olanak tanır. gönderilen, bu büyük konfigürasyonlar için geçerlidir. Ancak bu etkileşimi karmaşıklaştırır; istek, abonelikten çıkma ve abone olma için kaynakların bir listesini içerir.

Örneğimiz ADS'yi kullanıyor - RDS, CDS, EDS ve artımlı olmayan mod için tek akış. Artımlı modu etkinleştirmek için belirtmeniz gerekir api_type: DELTA_GRPC

İstek düğüm parametreleri içerdiğinden, farklı örnekler için kontrol düzlemine farklı kaynaklar gönderebiliriz. gönderilen, bu bir servis ağı oluşturmak için uygundur.

Isınmak

Üzerinde gönderilen Başlangıçta veya kontrol düzleminden yeni bir konfigürasyon alındığında kaynak ısınma süreci başlatılır. Dinleyici ısınması ve küme ısınması olarak ikiye ayrılır. Birincisi RDS/LDS'de değişiklik olduğunda, ikincisi CDS/EDS'de değişiklik olduğunda başlatılır. Bu, yalnızca yukarı akışlar değişirse dinleyicinin yeniden oluşturulmayacağı anlamına gelir.

Isınma sürecinde zaman aşımı sırasında kontrol düzleminden bağımlı kaynaklar beklenir. Zaman aşımı gerçekleşirse, başlatma başarılı olmayacak ve yeni dinleyici bağlantı noktasında dinlemeye başlamayacaktır.
Başlatma sırası: EDS, CDS, aktif sağlık kontrolü, RDS, LDS. Aktif durum kontrolleri etkinleştirildiğinde, trafik yalnızca bir başarılı durum kontrolünden sonra yukarı doğru ilerleyecektir.

Dinleyici yeniden oluşturulduysa eskisi DRAIN durumuna geçer ve tüm bağlantılar kapatıldıktan veya zaman aşımı süresi dolduktan sonra silinir. --drain-time-s, varsayılan 10 dakikadır.

Devam edecek.

Kaynak: habr.com

Yorum ekle