2 分鐘把握 Envoy 的脈絡,適應新場景的 envoy 有哪些不同?能做什麼?

本篇目錄

說明

在梳理開源的 API 網關和 ServiceMesh 項目時,最常遇到的一個詞是 Envoy,Ambassador、Contour、Gloo、Istio 等項目的數據平面都選用了 Envoy。Envoy 何德何能受到衆多項目的青睞? 掌握 Envoy 的脈絡只需 2 分鐘。

響應了時代號召的 Envoy

Envoy 是一個具有反向代理和負載均衡功能的單機軟件,和 Nginx、Haproxy 屬於同一類軟件。與 Nginx 和 Haproxy 相比,Envoy 有一個的重要特色是:自帶配置 API

以 Nginx、Haproxy 爲代表的負載均衡軟件,在過去很多年的實際應用中,很少會在軟件運行的時候更改配置,即使偶爾要修改配置文件,使用 reload 等命令重新加載就能滿足需要。

以 Kubernetes 爲代表的 PaaS 或者容器管理系統出現後,IT 系統沿着“分工專業化、更少的人做更多同質事情”的路線演進,在當前的演進過程中,反向代理與負載均衡的能力被集中管理、統一提供。

這一演進在 Kubernetes 中體現爲作爲集羣出口的 ingress 代理集羣內所有服務,在以 istio 爲代表的 ServiceMesh 中體現爲分散在各處的代理軟件在同一個中心的控制下流轉流量。 無論是作爲 Kubernetes 的出口,還是作爲 Mesh 中的一個節點,承擔流量轉發功能的組件都需要完成一個挑戰: 在運行過程中頻繁的更新配置

新場景中的更新的頻率是每秒 N 次,遠遠超過以往的場景中以周、月乃至年爲週期的更新頻率。這種情形下,熱加載配置文件的方式明顯遲緩笨重,有一些項目通過開發一個帶有 API 功能的組件,實現生成配置文件、觸發熱加載的功能,以此賦予 Nginx、Haproxy 等傳統負載均衡軟件高頻更新配置的能力。

但是,如果有一個軟件原生帶有配置 API,且專注於數據平面,它作爲可靠的第三方存在,能夠讓控制平面專心於規則管理,那麼它是不是會很受歡迎呢?

Envoy 就是這樣一款軟件。注意,這裏只是在交代背景,不爲 envoy 吹票,nginx、haproxy 等都在更新演進以適應場景的變化。

Cluster、Listener 與 Filter

Envoy 的功能和使用細節繁雜,但只要搞清楚了 Cluster、Listener 和 Filter 的用途,就把握住了大方向。

Cluster 就是一組 IP,相當於 Nginx 中 upstream,負載均衡策略在 cluster 中設置,cluster 中可以是 IP 也可以是域名:

envoy的cluster

Listener 就是監聽地址和轉發規則:

envoy的listener

難啃的配置文件

Envoy 的配置文件是從零開始瞭解 Envoy 時遇到的最大困難,它的配置比較繁雜,而且缺少系統的介紹。

配置文件在 envoy 啓動時,用 -c 指定,內容分爲以下幾個部分:

{
  "node": {
    "id": "...",
    "cluster": "...",
    "metadata": "{...}",
    "locality": "{...}",
    "build_version": "..."
  },
  "static_resources": {
    "listeners": [],
    "clusters": [],
    "secrets": []
  },
  "dynamic_resources": {
    "lds_config": "{...}",
    "cds_config": "{...}",
    "ads_config": "{...}"
  },
  "cluster_manager": {
    "local_cluster_name": "...",
    "outlier_detection": "{...}",
    "upstream_bind_config": "{...}",
    "load_stats_config": "{...}"
  },
  "hds_config": {
    "api_type": "...",
    "cluster_names": [],
    "grpc_services": [],
    "refresh_delay": "{...}",
    "request_timeout": "{...}",
    "rate_limit_settings": "{...}"
  },
  "flags_path": "...",
  "stats_sinks": [
    {
      "name": "...",
      "config": "{...}"
    }
  ],
  "stats_config": {
    "stats_tags": [],
    "use_all_default_tags": "{...}",
    "stats_matcher": "{...}"
  },
  "stats_flush_interval": "{...}",
  "watchdog": {
    "miss_timeout": "{...}",
    "megamiss_timeout": "{...}",
    "kill_timeout": "{...}",
    "multikill_timeout": "{...}"
  },
  "tracing": {
    "http": "{...}"
  },
  "rate_limit_service": {
    "grpc_service": "{...}"
  },
  "runtime": {
    "symlink_root": "...",
    "subdirectory": "...",
    "override_subdirectory": "..."
  },
  "admin": {
    "access_log_path": "...",
    "profile_path": "...",
    "address": "{...}"
  },
  "overload_manager": {
    "refresh_interval": "{...}",
    "resource_monitors": [],
    "actions": []
  }
}

查看 envoy 容器中的默認配置文件,有助於建立感性認識,內容如下:

admin:
  access_log_path: /tmp/admin_access.log
  address:
    socket_address:
      protocol: TCP
      address: 127.0.0.1
      port_value: 9901
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
    tls_context:
      sni: www.google.com

掌握 envoy 的配置文件,是把握住這款軟件的關鍵一步,如何才能掌握 envoy 的配置呢?把它所有的配置細節記住當然算是掌握了,但是大多數時候我們並不需要如此,只需要知道實時反應配置文件全部細節的文檔在哪裏就足夠了,剩下的交給時間和好奇心:

envoy的配置文件詳解

挑大樑的 filter

幾乎可以這樣說,在實際應用中最常提及的 envoy 功能都是 filter 提供的, filter 是流量在 envoy 內流轉時經歷的一個又一個處理環節,每個環節都會解讀一些信息、作出一些判斷,影響下一個環節的處理。

Cluster 和 Listener 中都有 filter 的位置,有的 filter 比較複雜還實現了 子 filter,例如專門處理 http 協議的 HttpConnectionManager。 Filter 的數量實在太多,知道到哪裏找到所有 filter 的說明和配置方法比記住個別 filter 的用法更重要:

envoy listener filter

envoy network filter

這些 filter 的名稱很好的展示了 envoy 能夠做的事情,http、thrift、dubbo、zookeeper、mysql、mongo、redis,看起來是不是挺誘人的?

動態配置到底怎麼回事?

envoy 的一大賣點就是自帶配置 API,但要把它自帶的 API 用起來還挺周折。envoy 率先提出使用統一的 data-plane-api ,定義了一套 API 標準,並期待能夠得到廣泛的認同和採納,從新起的 Api 網關和 ServiceMesh 開源項目的選擇來看,這一策略是有效的。

date-plane-api

go-controller-plane 是 envoy 提出的 data-plane-api 的 go 語言實現,可以用它向 envoy 下發配置,這個庫的使用方法三言兩語說不清楚,先弄清楚下面三個項目的關係: envoy 就是單機軟件 envoy,data-plane-api 是 API 接口標準,go-control-plane 是 API 接口標準的實現。

envoy network filter

動手實踐一下

自帶配置 API 支持動態更新,Cluster、Listener、Filter 構成了 Envoy 的功能骨架,如果看完上面的介紹,依舊感覺朦朦朧朧如霧裏看花,想要看的更清楚一些,沒有比照敲一遍 Envoy 使用手冊 中的操作更快捷的方法了:

點擊查看: Envoy 使用手冊

envoy 使用手冊

參考

  1. 李佶澳的博客
  2. Envoy 使用手冊
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章