使者。 一、簡介

問候! 這是一篇簡短的文章,回答了以下問題:“什麼是 Envoy?”、“為什麼需要它?” 和“從哪裡開始?”。

這是什麼

Envoy 是一個用 C++ 編寫的 L4-L7 平衡器,專注於高效能和可用性。 一方面,這在某種程度上類似於 nginx 和 haproxy,在性能上與它們相當。 另一方面,它更面向微服務架構,功能不比java和go的平衡器差,例如zuul或traefik。

haproxy/nginx/envoy 的對比表,它並不聲稱是絕對真實的,但給出了一個大致的情況。

nginx的
HAProxy的
發送
特拉菲克

github 上的星星
11.2k/鏡像
1.1k/鏡像
12.4k
27.6k

寫在
C
C
C + +中
go

API
沒有
僅套接字/推送
資料平面/拉動

主動健康檢查
沒有
是的
是的
是的

開放追蹤
外部插件
沒有
是的
是的

智威湯遜
外部插件
沒有
是的
沒有

延期
盧阿/C
盧阿/C
盧阿/C++
沒有

為了什麼

這是一個年輕的項目,有很多東西缺失,有些還處於早期 alpha 階段。 但 發送也由於它很年輕,正在迅速發展,並且已經擁有許多有趣的功能:動態配置、許多現成的過濾器、用於編寫自己的過濾器的簡單介面。
應用領域由此而來,但首先有 2 個反模式:

  • 靜態反沖。

事實是,此刻在 發送 沒有緩存支援。 谷歌的人正在嘗試這個 解決。 這個想法將在一次實施 發送 RFC 合規性的所有微妙之處(zoo 標頭),並為特定實作建立一個介面。 但現在還不是 alpha,架構正在討論中, PR 打開(當我寫PR文章時,PR凍結了,但這仍然相關)。

現在,使用 nginx 進行靜態分析。

  • 靜態配置。

你可以使用它,但是 發送 這不是它創建的目的。 靜態配置中的功能不會被公開。 有很多時刻:

在 yaml 中編輯配置時,你會犯錯,責罵開發人員冗長,並認為 nginx/haproxy 配置雖然不太結構化,但更簡潔。 這才是重點。 Nginx 和 Haproxy 的設定是為了手動編輯而建立的,並且 發送 用於從代碼生成。 整個配置描述於 原蟲,從 proto 檔案生成它更難犯錯。

Canary、b/g 部署場景等通常僅在動態配置中實作。 我並不是說這不能靜態完成,我們都這樣做。 但為此,您需要在任何平衡器中使用拐杖,在 發送 包括。

Envoy 不可或缺的任務:

  • 複雜動態系統中的流量平衡。 這包括服務網格,但它不一定是唯一的。
  • 對分散式追蹤功能、複雜授權或其他可用功能的需求 發送 開箱即用或方便實現,但在 nginx/haproxy 中,您需要被 lua 和可疑插件包圍。

如有必要,兩者都可以提供高性能。

Какэтоработает

Envoy 僅以 docker 映像以二進位檔案形式分發。 該圖像已包含靜態配置的範例。 但我們對它感興趣只是為了了解其結構。

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

動態配置

我們正在尋找解決什麼問題的方法? 您不能只是在負載下重新加載負載平衡器配置;將會出現“小”問題:

  • 配置驗證。

配置可以很大,可以非常大,如果我們一次超載所有配置,某處出錯的可能性就會增加。

  • 長久的連結。

初始化新偵聽器時,您需要照顧舊偵聽器上運行的連接;如果更改頻繁發生並且存在長期連接,則您將不得不尋找折衷方案。 你好,nginx 上的 kubernetes 入口。

  • 積極的健康檢查。

如果我們有主動的健康檢查,我們需要在發送流量之前在新配置中仔細檢查它們。 如果有很多上游,這需要時間。 你好。

這是如何解決的 發送透過動態載入配置,根據池模型,您可以將其劃分為單獨的部分,並且無需重新初始化未變更的部分。 例如,偵聽器的重新初始化成本很高且很少更改。

組態 發送 (來自上面的文件)具有以下實體:

  • 聽眾 — 偵聽器掛在特定的 ip/連接埠上
  • 虛擬主機 - 按網域名稱的虛擬主機
  • 路線 - 平衡規則
  • — 一組具有平衡參數的上游
  • 端點 — 上游實例地址

這些實體中的每一個以及其他一些實體都可以動態填入;為此,配置指定將從中接收配置的服務的位址。 服務可以是REST或gRPC,gRPC是更好的選擇。

這些服務分別命名為:LDS、VHDS、RDS、CDS 和 EDS。 您可以將靜態和動態配置結合起來,但限制是不能在靜態資源中指定動態資源。

對於大多數任務來說,實現後三個服務就足夠了,它們被稱為ADS(聚合發現服務),用於 Java的 那裡有一個現成的 gRPC 資料平面實現,您只需在其中填充來源中的物件即可。

配置採用以下形式:

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

跑步時 發送 使用此配置,它將連接到控制平面並嘗試請求 RDS、CDS 和 EDS 配置。 描述了互動過程如何發生 這裡.

簡而言之, 發送 發送請求,指示所請求的資源類型、節點的版本和參數。 作為回應,它接收資源和版本;如果控制平面上的版本沒有更改,則它不會回應。
有 4 個互動選項:

  • 適用於所有類型資源的一個 gRPC 流,發送資源的完整狀態。
  • 獨立的溪流,狀況齊全。
  • 一個流,增量狀態。
  • 單獨的流,增量狀態。

增量 xDS 可讓您減少控制平面和 發送,這與大型配置相關。 但這使得互動變得複雜;請求包含用於取消訂閱和訂閱的資源清單。

我們的範例使用 ADS - 用於 RDS、CDS、EDS 和非增量模式的一個流。 若要啟用增量模式,您需要指定 api_type: DELTA_GRPC

由於請求包含節點參數,因此我們可以針對不同實例向控制平面發送不同的資源 發送,這方便建立服務網格。

暖身

發送 在啟動時或從控制平面接收新配置時,將啟動資源預熱過程。 分為監聽器預熱和集群預熱。 第一個在 RDS/LDS 改變時啟動,第二個在 CDS/EDS 改變時啟動。 這表示如果只有上游發生變化,則不會重新建立偵聽器。

在預熱過程中,在逾時期間預期控制平面會提供相關資源。 如果逾時,初始化將不會成功,新的偵聽器將不會開始偵聽該連接埠。
初始化順序:EDS、CDS、主動健康檢查、RDS、LDS。 啟用主動運轉狀況檢查後,只有在一次成功的運轉狀況檢查後,流量才會上行。

如果重新建立偵聽器,則舊偵聽器將進入 DRAIN 狀態,並在所有連線關閉或逾時到期後將刪除 --drain-time-s,預設10分鐘。

要繼續進行下去。

來源: www.habr.com

添加評論