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 使用手冊


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM