Envoy官網:https://www.envoyproxy.io/
正如微服務背景從業者很快意識到的那樣,轉移到分佈式體系結構時出現的大多數操作問題最終都基於兩個方面:網絡和可觀察性。與單個整體應用程序相比,網絡連接和調試一組交錯的分佈式服務僅是一個大數量級的問題。
Envoy最初是在Lyft上構建的,是一種高性能C ++分佈式代理,專爲單個服務和應用程序而設計,以及爲大型微服務“服務網格”架構設計的通信總線和“通用數據平面”。基於對NGINX,HAProxy,硬件負載平衡器和雲負載平衡器等解決方案的學習,Envoy與每個應用程序一起運行,並通過與平臺無關的方式提供通用功能來抽象化網絡。當基礎架構中的所有服務流量都通過Envoy網格流動時,通過一致的可觀察性,調整整體性能以及在單個位置添加基板功能,即可輕鬆可視化問題區域。
Envoy 本身可以做反向代理和負載均衡,它也是 Istio 數據平面中默認使用的 sidecar。在瞭解一門技術之前一開始就要了解其中的基本概念和術語,只有融入了該語境才能理解這門技術。本文將爲大家介紹 Envoy 中的基本術語和重點概念。
架構
下圖是 Envoy proxy 的架構圖,顯示了 host B 經過 Envoy 訪問 host A 的過程。每個 host 上都可能運行多個 service,Envoy 中也可能有多個 Listener,每個 Listener 中可能會有多個 filter 組成了 chain。
Envoy Proxy架構圖
其中的基本術語將在下面解釋。
基本術語
Host:能夠進行網絡通信的實體(在手機或服務器等上的應用程序)。在 Envoy 中主機是指邏輯網絡應用程序。只要每臺主機都可以獨立尋址,一塊物理硬件上就運行多個主機。
Downstream:下游(downstream)主機連接到 Envoy,發送請求並或獲得響應。
Upstream:上游(upstream)主機獲取來自 Envoy 的鏈接請求和響應。
Cluster: 集羣(cluster)是 Envoy 連接到的一組邏輯上相似的上游主機。Envoy 通過服務發現發現集羣中的成員。Envoy 可以通過主動運行狀況檢查來確定集羣成員的健康狀況。Envoy 如何將請求路由到集羣成員由負載均衡策略確定。
Mesh:一組互相協調以提供一致網絡拓撲的主機。Envoy mesh 是指一組 Envoy 代理,它們構成了由多種不同服務和應用程序平臺組成的分佈式系統的消息傳遞基礎。
運行時配置:與 Envoy 一起部署的帶外實時配置系統。可以在無需重啓 Envoy 或 更改 Envoy 主配置的情況下,通過更改設置來影響操作。
Listener: 偵聽器(listener)是可以由下游客戶端連接的命名網絡位置(例如,端口、unix域套接字等)。Envoy 公開一個或多個下游主機連接的偵聽器。一般是每臺主機運行一個 Envoy,使用單進程運行,但是每個進程中可以啓動任意數量的 Listener(監聽器),目前只監聽 TCP,每個監聽器都獨立配置一定數量的(L3/L4)網絡過濾器。Listenter 也可以通過 Listener Discovery Service(LDS)動態獲取。
Listener filter:Listener 使用 listener filter(監聽器過濾器)來操作鏈接的元數據。它的作用是在不更改 Envoy 的核心功能的情況下添加更多的集成功能。Listener filter 的 API 相對簡單,因爲這些過濾器最終是在新接受的套接字上運行。在鏈中可以互相銜接以支持更復雜的場景,例如調用速率限制。Envoy 已經包含了多個監聽器過濾器。
Http Route Table:HTTP 的路由規則,例如請求的域名,Path 符合什麼規則,轉發給哪個 Cluster。
Health checking:健康檢查會與SDS服務發現配合使用。但是,即使使用其他服務發現方式,也有相應需要進行主動健康檢查的情況。詳見 health checking。
xDS
xDS 是一個關鍵概念,它是一類發現服務的統稱,其包括如下幾類:
- CDS:Cluster Discovery Service
- EDS:Endpoint Discovery Service
- SDS:Service Discovery Service
- RDS:Route Discovery Service
- LDS:Listener Discovery Service
正是通過對 xDS 的請求來動態更新 Envoy 配置。
Envoy Mesh
Envoy Mesh 指的是由 envoy 做負載均衡和代理的 mesh。該 Mesh 中會包含兩類 envoy:
- Edge envoy:即流量進出 mesh 時候的 envoy,相當於 kubernetes 中的 ingress。
- Service envoy:服務 envoy 是跟每個 serivce 實例一起運行的,應用程序無感知的進程外工具,在 kubernetes 中會與應用容器以 sidecar 形式運行在同一個 pod 中。
Envoy 即可以單獨作爲 edge envoy,也可以僅做 service envoy 使用,也可以兩者同時使用。Mesh 中的所有 envoy 會共享路由信息。
Envoy 配置
Envoy 中的配置包括兩大類:listenner 配置和 cluster 配置。
Listener 配置
我們知道 Envoy 中可以配置一組 listener 以實現複雜的處理邏輯。Listener 中設置監聽的 TCP 端口,還有一組 filter 對這些端口上的數據流進行處理。如下所示,該示例來自使用Envoy 作爲前端代理。
listeners:
- address:
socket_address:
address: 0.0.0.0
port_value: 80
filter_chains:
- filters:
- name: envoy.http_connection_manager
config:
codec_type: auto
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: backend
domains:
- "*"
routes:
- match:
prefix: "/service/1"
route:
cluster: service1
- match:
prefix: "/service/2"
route:
cluster: service2
這是一個 http_connection_manager
例子,其中必須包含 virtual_hosts
配置,而 virtual_hosts
配置中必須包含以下幾項配置:
name
:服務名稱domains
:DNS 域名,必須能跟virtual_host
的 URL 匹配routes
:路由列表
每個路由中還可以包含以下配置:
prefix
:URL 路徑前綴cluster
:處理該請求的 envoy clustertimeout_ms
:當出錯時的超時時間
如上面的例子中,我們還需要定義 service1
cluster 和 service2
cluster。
Cluster 配置
Cluster 是一組邏輯相似的主機配置,定義哪些主機屬於一個服務,cluster 的配置中包含了服務發現和負載均衡方式配置。依然是參考使用Envoy 作爲前端代理中的配置:
clusters:
- name: service1
connect_timeout: 0.25s
type: strict_dns
lb_policy: round_robin
http2_protocol_options: {}
hosts:
- socket_address:
address: service1
port_value: 80
- name: service2
connect_timeout: 0.25s
type: strict_dns
lb_policy: round_robin
http2_protocol_options: {}
hosts:
- socket_address:
address: service2
port_value: 80
Cluster 的配置中至少包含以下信息:
name
:cluster 名稱,就是服務名稱type
:該 cluster 怎麼知道主機是否啓動?即服務發現類型,有以下方式:static
:監聽 cluster 中的所有主機strict_dns
:envoy 會監聽 DNS,每個匹配的 A 記錄都會認定爲有效logical_dns
:envoy 將使用 DNS 來增加主機,如果 DNS 不再返回該主機也不會刪除這些主機信息sds
:即 Serivce Discovery Serivce,envoy 訪問外部的 REST 獲取 cluster 成員信息
lb_type
:cluster 的負載均衡類型,有以下方式:round_robin
:輪詢主機weighted_least_request
:最近獲得最少請求的主機random
:隨機
hosts
:能夠定義 cluster 中主機的 URL 地址,通常是tcp://
URL