下一代微服務框架 Service Mesh

本文出自于ADDOPS團隊,該文章的譯者霍明明參與了360 HULK云平臺容器化及虛擬化平臺相關服務建設,對微服務有著獨到的見解。今天的主角Istio是Google/IBM/Lyft聯合開發的開源項目,估計很多同學在此之前可能完全沒有聽過這個名字,請不必介意,因為Istio出世也才五個月而已。讓我們跟著作者一起揭開Service Mesh的神秘面紗。

PS:豐富的一線技術、多元化的表現形式,盡在“HULK一線技術雜談”,點關注哦!

前言

有人將 Service Mesh 看成是一次 "Network Application Revolution",我還是非常認同的,所以也就有了進一步了解和學習Service Mesh的動力。

在看本文章前,強烈建議先看一下這兩篇文章《深度剖析Service Mesh服務網格新生代Istio》,《從分布式到微服務,深挖Service Mesh》,了解一下Service Mesh的歷史。

1

Envoy 簡介

在 Service Mesh 模式中,每個服務都配備了一個代理“sidecar”,用于服務之間的通信。這些代理通常與應用程序代碼一起部署,并且它不會被應用程序所感知。Service Mesh 將這些代理組織起來形成了一個輕量級網絡代理矩陣,也就是服務網格。這些代理不再是孤立的組件,它們本身是一個有價值的網絡。其部署模式如圖所示:

綠色部分代表應用程序

藍色部分則是sidecar

服務網格是用于處理服務到服務通信的“專用基礎設施層”。它通過這些代理來管理復雜的服務拓撲,可靠地傳遞服務之間的請求。 從某種程度上說,這些代理接管了應用程序的網絡通信層。

Envoy是 Service Mesh 中一個非常優秀的 sidecar 的開源實現。我們就來看看 Envoy 都是做些什么工作。

2

Envoy 用到的幾個術語

Host: 通常我們將 Host 看做是一個具備網絡通信功能的實體(可以是一臺物理機,也可以是一臺移動設備等等) 。在 Envoy 中,host 是一個邏輯網絡中的應用. 可能運行在由有多個主機組成的底層硬件,只要它們各自獨立尋址。

Downstream: 請求發起者(服務請求方)。

Upstream: 請求接收者(服務提供方)。

Listener: 服務(程序)監聽者。就是真正干活的。 envoy 會暴露一個或者多個listener監聽downstream的請求。

Cluster: upstream 集群。Envoy 通過服務發現定位集群成員并獲取服務。具體請求到哪個集群成員是由負載均衡策略決定。通過健康檢查服務來對集群成員服務狀態進行檢查。

Mesh: 在本文中 "Envoy mesh" 指的是由一組 Envoy 代理組成的,為不同服務之間可靠傳遞請求的服務網格。

Runtime configuration: Envoy 配置是熱更新的,無需重啟。

Filter: 過濾器。在 Envoy 中指的是一些“可插拔”和可組合的邏輯處理層。是 Envoy 核心邏輯處理單元。

3

Envoy 基礎概念

線程模型

Envoy 使用單進程多線程模式。一個主線程,多個工作線程。主線程協調和管理這多個線程來工作。每個線程都獨立監聽服務,并對請求進行過濾和數據的轉發等。

一個連接建立后,這個線程將會管理該連接的整個生命周期。通常 Envoy 是非阻塞的,對于大多數情況建議每個 Envoy 配置的工作線程數等于機器的 CPU 線程數。

Listeners

Envoy 中真正干活的(通常是一個監聽服務端口的工作線程)。

Envoy 會啟動一個或者多個listener,監聽來自 downstream 的請求。當 listener 接收到新的請求時,會根據關聯的filters模板初始化配置這些 filters,并根據這些 filters 鏈對這些請求做出處理(例如:限速、TLS 認證、HTTP 連接管理、MongoDB 嗅探、TCP 代理等等)。

Envoy 是多線程模型,支持單個進程配置任意數量的 listeners。通常建議一個機器上運行一個 Envoy 進程,而不關心配置了多少個listerners(如上:大多數情況listener數量等于機器的CPU線程數)。

目前 Envoy 只支持 TCP 類型的 listeners。每個 listener 都可以獨立配置一些L3/L4層的 filters。

Listener 還可以通過 listener 發現服務來動態獲取。

Network (L3/L4) filters

network (L3/L4) filters 構成了Envoy連接處理的核心。 在 listener 部分我們介紹過, 每個 listener 可以組合使用多個 filters 來處理連接數據。

目前有三種類型的 network (L3/L4) filters:

Read: 當 Envoy 接收來自下游服務請求數據時被調用。

Write: 當 Envoy 向上游服務發送數據時被調用。

Read/Write: 上面兩種fileter都是單向控制,Read/Write filters 在接收來自下游服務請求數據和向上游服務發送數據時被調用,是雙向控制。

這些 filter 通過分析原始字節流和少量連接事件(例如,TLS握手完成,本地或遠程連接斷開等)對連接進行處理。

Network Filter(L7)/HTTP Filter

HTTP 協議是當前許多服務構建的基礎協議,作為核心組件,Envoy 內置了 HTTP 連接管理 filter。 該 filter 將原始數據字節轉換成 HTTP 協議類型數據(比如: headers、body、trailers等)。它還會處理一些通用的問題(比如:request日志、request ID生成和request追蹤、請求/響應頭控制、路由表管理和狀態數據統計等)。

HTTP 連接管理提供了三種類型的filter:

HTTP 協議是當前許多服務構建的基礎協議,作為核心組件,Envoy 內置了 HTTP 連接管理 filter。 該 filter 將原始數據字節轉換成 HTTP 協議類型數據(比如: headers、body、trailers等)。它還會處理一些通用的問題(比如:request日志、request ID生成和request追蹤、請求/響應頭控制、路由表管理和狀態數據統計等)。

HTTP 連接管理提供了三種類型的filter:

Decoder: 解析請求數據流時(headers,body,trailers等)調用,屬于入口單方向控制。

Encoder: 編碼響應數據流時(headers, body, and trailers)調用,屬于出口單方向控制.

Decoder/Encoder: Decoder/Encoder 用于入/出口雙向控制.

HTTP Filters

(https://envoyproxy.github.io/envoy/configuration/http_filters/http_filters.html#config-http-filters)

HTTP protocols

Envoy HTTP 連接管理原生支持HTTP/1.1, WebSockets 和 HTTP/2,暫不支持 SPDY。

Envoy 對 HTTP 的支持在設計之初就是一個HTTP/2的多路復用代理。對于 HTTP/1.1 類型連接,編解碼器將 HTTP/1.1 的數據轉換為類似于 HTTP/2 或者更高層的抽象處理。這意味著大多數代碼不用關心底層連接使用的是 HTTP/1.1 還是 HTTP/2。

access log

HTTP 連接管理支持 access log,可以記錄訪問日志,且可以靈活的配置。

HTTP 路由

Envoy 包含了一個 HTTP router filter,該 filter 可以用來實現更高級的路由功能。它可以用來處理邊緣流量/請求(類似傳統的反向代理),同時也可以構建一個服務與服務之間的 Envoy 網格(典型的是通過對HTTP header等的處理實現到特定服務集群的轉發)。

每個HTTP連接管理 filter 都會關聯一個路由表。每個路由表會包含對 HTTP 頭、虛擬主機等的配置信息。

{

? "cluster": "...",

? "route_config_name": "route_config_example",

? "refresh_delay_ms": "3000"

}

route_config_example:

{

? "validate_clusters": "example",

? "virtual_hosts": [

? ? ? ? {

? ? ? ? ? "name": "vh01",

? ? ? ? ? "domains": ["test.foo.cn"],

? ? ? ? ? "routes": [],

? ? ? ? ? "require_ssl": "...",?

? ? ? ? ? "virtual_clusters": [],?

? ? ? ? ? "rate_limits":?

? ? ? ? ? "request_headers_to_add": [

? ? ? ? ? ? ? ? ? {"key": "header1", "value": "value1"},

? ? ? ? ? ? ? ? ? {"key": "header2", "value": "value2"}

? ? ? ? ? ]

? ? ? ? },

? ],

? "internal_only_headers": [],

? "response_headers_to_add": [],

? "response_headers_to_remove": [],

? "request_headers_to_add": [

? ]

}

路由表有兩種配置方式:

靜態配置文件。

通過RDS(Route discovery service) API動態配置。

RDS 是一組API用來動態獲取變更后的路由配置。

router filter 支持如下功能:

支持 Virtual hosts。映射 domains/authorities 到一系列的路由規則上。[和nginx等一樣]。

基于前綴和精確path的規則匹配(有的對大小寫既敏感,有的不敏感)。 由于 Regex/slug 會使得用程序來判定路由規則是否與其它規則沖突很困難, 所以,目前暫不支持。由于這個原因,我們不建議在反向代理層面使用基于regex/slug的路由, 當然了,未來我們會根據需求添加對它的支持。

Virual host 層面的 TLS 重定向。 分兩類:

all: 所有請求都必須使用TLS。如果請求沒有使用TLS,返回302。

external_only: 只要求外網請求使用TLS。如果來自外網的請求沒有使用TLS。 如果,改參數沒有配置,該virtual host將不會對TLS有要求。

路由層面對 Path/host 重定向。

host重寫。 支持兩種重寫方式:

1. 固定值。host_rewrite參數配置。

2. 動態配置。根據upstream 主機的 DNS 類型動態配置。 具體的值是由cluster manager從upstream中選出來的,其主機名作為重寫的值。 這種方式只用在route的目的集群是 strict_dns or logical_dns 類型的場景。其它集群類型不起作用。 將 auto_host_rewrite 設置true即可。這兩個參數不能同時使用。

前綴重寫(prefix)。

路由層面對 Websocket upgrades. 配置該規則后,來自 HTTP/1.1 客戶端到該路由規則的連接都會被轉換成 WebSocket 的連接。 如果配置為 true, Envoy 對于該路由的第一個請求需帶 WebSocket upgrade headers。如果沒有添加該header,請求江北拒絕。如果設置了, Envoy 將會在client和upstream server之間設置TCP代理 。upstream 負責斷開該連接,否則 Envoy 任然會轉發數據到該upstream server。

請求重試和超時設置 Envoy 有兩種方式來設置請求重試。

1. 通過route設置。

2. 通過request header設置。 支持的配置項有: 2.1 最大重試次數: 每次重試之間會使用指數退避算法.另外,所有重試都包含在整體請求超時之內。這避免了由于大量重試而需要較長的請求時間。 2.2 重試條件: 可以根據應用的需求配置觸發重試的條件。例如: 網絡錯誤, 5xx 返回碼, 冪等的4xx返回碼, 等等。

運行時對來自上下游數據的嗅探。

使用基于 weight/percentage-based 的路由,對來自多個上游的數據進行拆分。

任意 HTTP 頭匹配路由規則。

支持虛擬集群。

基于路由的優先級。

基于路由的 hash 負載均衡。需要在 header 中設置 hash 使用的策略。

對于非 TLS 的轉發支持絕對 urls。

其中:重定向、超時、重試對于 websocket upgrades 是不支持的。

Connection pooling

對于 HTTP 類型,Envoy 提供了對連接池的抽象,連接池屏蔽底層協議類型(HTTP/1.1、HTTP/2),向上層提供統一的接口。用戶不用關心底層是基于HTTP/1.1的多線程還是基于HTTP/2的多路復用方式實現細節。

TCP proxy

TCP 代理,L3/L4層連接的轉發。這應該是 Envoy 最基礎的功能。一般是作為 downstream 客戶端與 upstream 服務集群之間的連接代理。TCP 代理既可以單獨使用,也可以與其它 filter 組合使用,例如( MongoDB filter 或者 限速filter)。

在 TCP 代理層還可以配置 route 策略,比如: 允許哪些IP段和哪些端口進來的請求訪問,允許訪問哪些IP段和哪些端口的服務。

TCP 代理配置如下:

{

? "name": "tcp_proxy",

? "config": {

? ? "stat_prefix": "...",

? ? "route_config": "{...}"

? }

}

stat_prefix: 統計數據前綴,主要是用于區分統計數據。

route_config: filter 的路由表。

例如:

{

? "name": "tcp_proxy",

? "config": {

? ? "stat_prefix": "...",

? ? "route_config": "{

? ? ? "routes": [

? ? ? ? {

? ? ? ? ? ? "cluster": "...",

? ? ? ? ? ? "destination_ip_list": [

? ? ? ? ? ? ? ? ? "192.168.3.0/24",

? ? ? ? ? ? ? ? ? "50.1.2.3/32",

? ? ? ? ? ? ? ? ? "10.15.0.0/16",

? ? ? ? ? ? ? ? ? "2001:abcd::/64"

? ? ? ? ? ? ],

? ? ? ? ? ? "destination_ports": "1-1024,2048-4096,12345",

? ? ? ? ? ? "source_ip_list": [

? ? ? ? ? ? ? ? ? "192.168.3.0/24",

? ? ? ? ? ? ? ? ? "50.1.2.3/32",

? ? ? ? ? ? ? ? ? "10.15.0.0/16",

? ? ? ? ? ? ? ? ? "2001:abcd::/64"

? ? ? ? ? ? ],

? ? ? ? ? ? "source_ports": "1-1024,2048-4096,12345"

? ? ? ? },

? ? ? ]

? ? }"

? }

}

簡單說,就是上下游服務的訪問控制。

TPC 代理支持的一些統計數據:

downstream_cx_total 處理的連接總數.

downstream_cx_no_route 不匹配route的總數.

downstream_cx_tx_bytes_total 發送給下游的總字節數

downstream_cx_tx_bytes_buffered Gauge 當前為下游服務緩存的字節數

downstream_flow_control_paused_reading_total 被流控暫停從下游服務讀取數據的次數

downstream_flow_control_resumed_reading_total 被流控控制重新從下游服務讀取數據的次數

gRPC 的支持

Envoy 在傳輸層和應用層兩個層給予gRPC的高度支持。

Envoy 是當前極少數能同時正確支持HTTP/2 trailers和傳輸gRPC請求和響應的的HTTP代理。

gRPC 運行時對于一些語言而言還是不太成熟。為此,Envoy 支持一個叫 gRPC bridge 的 filter,它允許gRPC請求能夠通過HTTP/1.1發送給Envoy。 Envoy 會將該請求轉換成HTTP/2傳輸到目的server。響應會被轉換成 HTTP/1.1 返回。

當裝了bridge filter后, bridge filter 除了收集全局HTTP統計之外,橋接過濾器還收集每個RPC統計信息。

gRPC-Web is supported by a filter that allows a gRPC-Web client to send requests to Envoy over HTTP/1.1 and get proxied to a gRPC server. It’s under active development and is expected to be the successor to the gRPC bridge filter.

支持 gRPC-web。通過 filter 能夠將使用 HTTP/1.1 發送到Envoy 的 gRPC-Web 客戶端請求代理到 gRPC server。該 feature 正在開發階段。

JSON 轉換器支持基于 JSON 的 RESTFUL 客戶端通過 HTTP 發送請求給 Envoy 并代理給 gRPC 服務.

WebSocket 的支持

Envoy 支持HTTP/1.1連接到WebSocket連接的切換(默認是支持的)。

條件:

client 需要顯示添加 upgrade headers 。

HTTP 路由規則中顯示的設置了對 websocket的支持(use_websocket)。

因為 Envoy 將 WebSocket connections 作為 TCP connection 來處理,因此,一些HTTP的特性它不支持,例如: 重定向、超時、重試、限速、 shadowing . 但是, prefix 重寫, host 重寫, traffic shifting and splitting 都是支持的.

Envoy對WebSocket的代理是TCP層,它理解不了WebSocket層的語義,所以對于連接斷開應該由upstream的client來主動關閉。

Envoy對WebSocket的支持與nginx對WebSocket的支持是相同的。

關于 Envoy 對 WebSocket 的支持可以參考 nginx 對 WebSocket 的支持。

(http://www.itfanwan.com/xinwen/6385)

4

高級概念

集群管理器(Cluster manager)

Envoy 集群管理器管理所有 upstream 集群節點。

upstream 集群節點都由一些列 L3/L4/L7 層 filter 鏈組成,它們可用于任意數量的不同代理服務。

集群管理器向 filter 鏈暴露一組API,這組API允許 filters 獲取發往 upstream 集群的L3/L4層的連接或抽象的 HTTP 連接池的數據。在 filter 處理階段通過對原始字節流的分析確定是一個連接是 L3/L4 層的連接還是一個新的 HTTP 流。

除了基本的連接類型分析外,集群管理器還要處理一些列的復雜工作,例如:知道哪些主機可用和健康,負載均衡,網絡連接數據的本地存儲,連接類型(TCP/IP, UDS),協議類型(HTTP/1.1,HTTP/2)等。

集群管理器支持兩種方式獲取它管理的集群節點:

通過靜態的配置文件

通過動態的集群發現API(CDS)。

CDS:Cluster discovery service,是一個可選的API,Envoy用它來動態的獲取cluster manager的成員。

集群管理器配置項如下:

{

? "clusters": [],?

? "sds": "{...}",

? "local_cluster_name": "...",

? "outlier_detection": "{...}",

? "cds": "{...}"

}

Service discovery(SDS)

服務發現有幾種方式:

靜態配置。通過配置文件配置(IP/PORT、unix domain socket等)。

基于DNS的服務發現。

Original destination

Service discovery service (SDS)

On eventually consistent service discovery

更多服務發現內容

(https://envoyproxy.github.io/envoy/intro/arch_overview/service_discovery.html)

主動健康檢查

根據配置的不同, Envoy 支持3種健康檢查方式。

基于 HTTP

Envoy 向 upstream 節點發送一個 HTTP 請求,返回 200 代表健康, 返回 503 代表該host不再接收請求/流量。

基于 HTTP 的健康檢查支持3種策略:

1.1 No pass through

這種模式 Envoy 不會將健康檢查的請求轉發給本地的服務,而是根據當前節點是否被 draining 返回 200 或者 503.

1.2 Pass through

與第一種模式不同,這種模式 Envoy 會將健康檢查的請求轉發給本地服務,調用本地服務的健康檢查接口,返回 200 或 503.

1.3 Pass through with caching

這種模式是前兩種模式的高級版,第一種方案數據不一定準,第二種請求太頻繁會對性能有影響。

該模式加了個緩存的支持,在緩存周期內結果直接從緩存中取,緩存失效后再請求一次本地服務加載到緩存中。

這是推薦的一種模式。 健康檢查時 Envoy 與 Envoy之間是長連接,他們不會消耗太大性能;對于 upstream 節點而言,則是新請求新連接。

基于 HTTP 的健康檢查支持身份認證。

如果你在云平臺中用了最終一致性的服務發現服務或者容器環境中,趕上服務水平擴展,這個時候其中一個節點掛掉后又"回到平臺"且使用的是同一個 IP 是有可能的,但是確是不同的服務(在容器服務中尤為明顯)。一種解決方案是,對不同的服務使用不同的健康檢查URL,但是這種配置復雜度非常高。Envoy 采用的方案是在 header 中添加一個 service_name 選項來支持。如果設置了該選項,在健康檢查時會對比 header 中的 x-envoy-upstream-healthchecked-cluster 是否和該選項值匹配,如果不匹配則會忽略該請求。

L3/L4

基于L3/L4層的健康檢查, Envoy 向 upstream 節點發送定義好的一個字符串. 如果 upstream 節點返回該值,則代表健康, 否則不健康。

Redis

Envoy 向 Redis 發送一個 PING 命令, 返回 PONG 代表健康, 其它的代表不健康。

Passive health checking(鈍態檢查)

Envoy 通過 Outlier detection 進行鈍態(實在是找不出太合適的詞)檢查

Outlier detection,用來檢查某些集群成員在給定范圍內是否“正常”,不正常則將其從負載均衡列表中移除。

有時候一個節點雖然在進行主動健康檢查是是正常的,但是會存在某些不正常的狀態被遺漏的情況,而 Outlier detection 則是彌補這個“漏洞”的 。它通過跟高級的一些算法來判定該節點是否是正常的。

Outlier detection 有兩種檢查類型:

基于連續的 5xx 錯誤碼

upstream 成員連續N次返回5xx錯誤碼, N默認為5(可配置)。

基于成功率

基于成功率的檢查在兩種情況下是不處理的:

針對集群中單個節點

單個節點的請求數量在聚合區間內少于outlier_detection.success_rate_request_volume值時(默認100)。

集群級別

集群中 outlier_detection.success_rate_minimum_hosts 個節點在檢查周期內請求量都小于 outlier_detection.success_rate_request_volume 時。

配置項:

? {

? "consecutive_5xx": "...",

? "interval_ms": "...",

? "base_ejection_time_ms": "...",

? "max_ejection_percent": "...",

? "enforcing_consecutive_5xx" : "...",

? "enforcing_success_rate" : "...",

? "success_rate_minimum_hosts" : "...",

? "success_rate_request_volume" : "...",

? "success_rate_stdev_factor" : "..."

}

主動健康檢查和鈍態檢查可以配合使用,也可以單獨使用。

Circuit breaking(斷路器)

斷路器是一種分布式的限速機制,它針對每個upstream的host設置,有時候也需要針對整個cluster進行限制, 這個時候全局的限速就非常有必要了。Envoy支持全局限速(L3/L4、HTTP 都支持),它有一個集中的限速服務, 對于到達該集群的每個連接,都會從限速服務那里查詢全局限速進行判斷。 Envoy 是通過一個全局的gRPC限速服務來實現全局限速。通過redis來做后端存儲。

Envoy 的斷路器可以控制 envoy 與 downstream 節點的最大連接數、集群最大支持的 pending 請求數、集群最大支持的請求數(適用HTTP/2)、集群存活最大探測次數。

斷路器配置:

{

? "max_connections": "...",?

? "max_pending_requests": "...", # 默認 1024

? "max_requests": "...", # 默認? 1024

? "max_retries": "...", 默認 3

}

max_connections:Envoy 與 upstream 集群所有節點能夠建立的最大連接數量。該參數適用于HTTP/1.1,因為HTTP/2是使用單個連接與每個host建連,連接復用(默認1024)。

max_pending_requests: 等待線程池有可用連接時的最大排隊請求數量。該參數適用于HTTP/1.1,HTTP/2采用多路復用方式,無需排隊請求(默認 1024)。

max_requests: 給定時間內最大請求數,該參數適用于HTTP/2,HTTP/1.1 通過max_connections來限制。(默認 1024)。

max_retries: 給定時間內Envoy與請求upstream集群時的最大重試次數,該值不宜設置過大,重試過多可能會帶來更多其它的級聯故障,甚至導致雪崩。(默認 3)。

熱更新

簡化操作是Envoy一個非常重要的設計目標。除了強大的統計和本地管理接口, Envoy還具備自身熱重啟的功能。 這意味著 Envoy 能夠全自動的更新自己(包括代碼和配置的變更),而不會丟失任何連接。

看下熱更新的過程:

統計數據和一些lock都放到了共享內存中。進程在重啟時這些數據是持久的,不會丟失。

新舊進程通過RPC協議進行通信。

新的進程在接管舊進程的unix domain socket前,先完成一系列的初始化(比如:加載配置, 初始化服務發現和健康檢查, 其它)。然后,新的進程開始監聽服務,并告訴老的Envoy進程進入驅逐階段。

在舊進程驅逐階段, 舊的進程嘗試平滑的關閉已存在的連接。具體如何做要依賴于配置的filters。 --drain-time-s 配置項用來配置等待平滑退出的時間。如果平滑退出花費的時間超過了這個值,進程會強制關閉和回收。

驅逐過程結束后, 新的Envoy進程告訴舊的Envoy進程關閉自己。參數 --parent-shutdown-time-s 用來配置關閉自己的超時時間。

Envoy 的熱重啟的設計支持新老進程同時存在時也能正常工作。新舊進程之間的通信只能是通過unix domain socket。

5

Envoy 部署方式

這一塊是大家關注的重點,也就是應用程序如何與 Envoy 結合來使用的、請求是如何轉到 Envoy 的等等。

根據不同的使用場景,Envoy有不同的部署方式。

Service to service only

這是最簡單的部署和使用方式,在這種方式中 Envoy 作為內部與外部服務通信的總線。Envoy 啟動多個 listeners 用于本地流量轉發和服務與服務之間的流量轉發。

上圖展示了最簡單的 Envoy 部署方式。在這種部署方式中 Envoy 承擔的是SOA服務內部流量的消息總線角色。在這種場景中, Envoy 會暴露一些 listeners 用于本地流量或者本地服務與遠端服務之間流量的轉發。

listener 類型:

Service to service egress listener

本地服務到遠端服務的出口 listener。該類型 listener 會監聽在某個指定的端口上,所有內部應用出去的請求都重定向到該端口上,由該 listener 處理并轉發到目的服務集群節點。

例如:http://localhost:9001?或 tcp://localhost:9001。 HTTP 和 gRPC 類型請求使用 host header,HTTP/2使用 authority header 來指定訪問的遠端服務集群。 在數據流經 Envoy 過程中會進行服務發現、負載均衡、限速等處理。

本地 Services 只需要知道本地的Envoy,無需關心它們自己所處的網絡拓撲及環境。

Service to service ingress listener

本地服務到遠端服務的入口 listener。該 listener 提供遠端 Envoy 調用本地 Envoy 的端口。

例如:http://localhost:9211。?進入本地 Envoy 的請求都被路由/重定向到本地 service 的監聽端口。根據需要,本地的Envoy 會進行一些緩存、斷路檢查等處理。

Optional external service egress listeners

有時,需要訪問外部的服務,此時需要提供一個端口提供訪問。因為,有些外部服務SDK不支持host header的重寫來支持標準的HTTP反向代理行為。

例如:http://localhost:9250?might be allocated for connections destined for DynamoDB.我們建議為所有外部服務使用本地端口路由,而不是使用主機路由和專用本地端口路由

Discovery service integration

集成外部服務發現組件來提供服務到服務的發現功能。

service to service 模式配置模板

(https://github.com/envoyproxy/envoy/blob/master/configs/envoy_service_to_service.template.json)

Service to service plus front proxy

上圖展示了在 service to service 模式前增加 Envoy 集群作為7層反向代理的部署模式。

該部署模式有以下特點:

TLS 卸載

同時支持 HTTP/1.1 和 HTTP/2

完整的 HTTP 7層路由支持

前端的 Envoy 代理集群使用標準的 ingress 端口與后端的 service to service 集群通信。對于后端服務集群節點使用服務發現方式獲取。前端的 Envoy 集群節點是完全對等的提供服務,沒有任何差異。

這種方式和 service to service 方式相比多出了 前端七層代理的部分。可以適配更多的使用場景。

Service to service plus front proxy 配置模板

(https://github.com/envoyproxy/envoy/blob/master/configs/envoy_front_proxy.template.json)

Service to service, front proxy, and double proxy

雙代理模式

雙代理模式的設計理念是: 更加高效的卸載TLS、更快速的與client端建立連接(更短的TLS握手時間,更快的TCP擁塞窗口調整,更少的丟包等等)。 這些在雙代理上卸載TLS后的連接最終都會復用 已經與數據中心完成連接建立的 HTTP/2 連接。

Service to service, front proxy, and double proxy 配置模板

(https://github.com/envoyproxy/envoy/blob/master/configs/envoy_double_proxy.template.json)

總結

以上就是ServiceMesh 數據面板 Envoy

的基本介紹。如果大家對 Istio 感興趣,可以之后自行瀏覽 Istio 的官方網站,我也預期會在之后閱讀其源碼,更深入的了解 Envoy 工作原理,并會陸續給出Istio相關的文章和分享。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容