Envoy基礎知識
Envoy是與HAProxy和ngin一樣,都是同一領域中的新型網路代理/網路伺服器。
關於任何軟體,你可能會有幾種問題:
- 怎麼用?
- 為什麼有用?
- 它在內部如何工作?
什麼是Envoy
它是一個網路代理。你編譯以後把它放在你的伺服器上,告訴它使用哪個配置檔案,然後就可以了!
下面可能是使用Envoy最簡單的例子。配置檔案見這裡。此案例在埠7777上啟動一個Web伺服器,該伺服器其實代理另外一個埠為8000的HTTP伺服器。
如果您有Docker,可以立即嘗試 - 只需下載配置,啟動Envoy docker映象,然後離開!
python -mSimpleHTTPServer & # Start a HTTP server on port 8000 wget https://gist.githubusercontent.com/jvns/340e4d20c83b16576c02efc08487ed54/raw/1ddc3038ed11c31ddc70be038fd23dddfa13f5d3/envoy_config.json docker run --rm --net host -v=$PWD:/config envoyproxy/envoy /usr/local/bin/envoy -c /config/envoy_config.json
以上命令將啟動Envoy HTTP伺服器,然後你就可以向Envoy發出請求!
curl localhost:7777
它會代理你的請求轉發到localhost:8000。
Envoy基本概念:叢集,監聽器,路由和過濾器
我們剛剛執行的這個小小的 envoy_config.json包含了所有基本的Envoy概念!
首先,有一個監聽器。這告訴Envoy繫結到一個埠,在本例中為7777:
"listeners": [{ "address": { "socket_address": { "address": "127.0.0.1", "port_value": 7777 } |
接下來,監聽器有一個過濾器。過濾器告訴監聽器如何處理它收到的請求,併為Envoy提供一系列過濾器。如果您需要做一些複雜的事情,那麼要對每個請求使用幾個過濾器。
有幾種不同型別的過濾器(請參閱TCP過濾器列表),但最重要的過濾器可能是envoy.http_connection_manager過濾器,它用於代理HTTP請求。HTTP連線管理器還有一個適用的HTTP過濾器列表(請參閱HTTP過濾器列表)。其中最重要的是將envoy.router的請求路由到後端的過濾器。
在我們的示例中,有一個TCP過濾器(envoy.http_connection_manager)和1個HTTP過濾器(envoy.router):
"filters": [ { "name": "envoy.http_connection_manager", "config": { "stat_prefix": "ingress_http", "http_filters": [{ "name": "envoy.router", "config": {} }], |
接下來,我們來談談路由。您可能會注意到,到目前為止,我們還沒有告訴envoy.router過濾器如何處理它收到的請求,應該在哪裡代理這些請求?它應該匹配哪些路徑?在我們的例子中,答案將是“代理對localhost:8000的所有請求”。
envoy.router過濾器被配置為路由的陣列。在我們的例子中,只有一條路由規則。
"route_config": { "virtual_hosts": [ { "name": "blah", "domains": "*", "routes": [ { "match": { "prefix": "/" }, "route": { "cluster": "banana" } |
這裡定義了要匹配的域列表(這些域與請求主機頭匹配)。如果我們更換"domains": "*"到"domains": "my.cool.service",那麼我們就需要傳遞頭部資訊“Host: my.cool.service”才行。
你會注意到我們案例中被代理的埠 8000未在任何地方定義過。只是有"cluster": "banana"。什麼是叢集?
好吧,叢集是一個服務後端的地址(IP地址/埠)集合。例如,如果您有8臺機器執行同一種HTTP服務,那麼這個群集中可以有8臺host主機集合。每個服務都需要自己的叢集。這裡示例叢集非常簡單:它只是一個在localhost上執行的IP /埠。
"clusters":[ { "name": "banana", "type": "STRICT_DNS", "connect_timeout": "1s", "hosts": [ { "socket_address": { "address": "127.0.0.1", "port_value": 8000 } } ] } ] |
手動編寫Envoy配置的提示
從頭開始編寫Envoy配置非常耗時 - 在Envoy儲存庫(https://github.com/envoyproxy/envoy)中有一些例子,但即使使用Envoy一年後,這個基本配置實際上還是花了我近45分鐘,以下是一些提示:
- Envoy有兩種不同的API:v1和v2 API。許多較新的功能僅在v2 API中可用,我發現它的文件更容易導航,因為它是從protocol buffers自動生成的。(例如,叢集文件是從cds.proto生成的)
- Envoy API文件中的一些好的起點:監聽器,叢集,過濾器,虛擬主機。要獲得所需的所有資訊,您需要點選很多資料(例如,檢視如何為需要從“虛擬主機”啟動的路由配置群集,然後單擊route_config - > virtual_hosts - > routes - > route - > cluster ),但按照它這樣做還是奏效的。
- 這個體系結構概述文件是有用的,並給出一些Envoy是如何配置的全面解釋。
- 可以使用json或yaml配置Envoy。上面我使用了JSON。
使用伺服器配置Envoy
儘管我們從磁碟上的配置檔案開始,但使用Envoy與HAProxy或nginx完全不同的一點是,Envoy通常不是透過配置檔案配置的。相反,可以使用一個或多個動態的配置伺服器去更改配置Envoy 。
假設您正在使用Envoy將請求載入到50個後端伺服器,這些伺服器是您定期輪換出來的EC2例項。因此 http://your-website.com請求轉到Envoy,並被路由到Envoy 群集,該群集需要是這些伺服器的50個IP地址和埠的列表。
但是,如果隨著時間的推移, 也許你正在推出新的伺服器或者它們中一些會被終止。您可以透過定期更改Envoy配置檔案並重新啟動Envoy來處理此問題。要麼!!可以設定“群集發現服務”(或“CDS”),例如,可以查詢AWS API並將後端伺服器的所有IP返回給Envoy。
我不打算詳細介紹如何配置發現服務,但基本上它看起來像這樣(來自這個模板)。您可以告訴它重新整理的頻率以及伺服器的地址。
dynamic_resources: cds_config: api_config_source: cluster_names: - cds_cluster refresh_delay: 30s ... - name: cds_cluster connect_timeout: 0.25s type: STRICT_DNS lb_policy: ROUND_ROBIN hosts: - socket_address: protocol: TCP address: cds.yourcompany.net port_value: 80 |
4種Envoy發現服務
有四種資源可以為Envoy設定發現服務 - 路由(“叢集應該請求這個HTTP頭轉到什麼地方”),叢集(“這個服務有哪些後端?”),監聽器(過濾器用於埠)和端點。這些分別稱為RDS,CDS,LDS和EDS。XDS是整體協議。
從頭開始編寫發現服務的最簡單方法可能是在Go中使用 go-control-plane庫。
從頭開始編寫Envoy配置服務絕對是可能的,但還有一些其他開源專案可以實現Envoy發現服務。以下是我所知道的,但我確信還有更多:
- 有一個叫做rotor開源Envoy發現服務看起來很有趣。建造它的公司幾周前就關閉了。
- Istio(據我所知)基本上是一個Envoy發現服務,它使用來自Kubernetes API的資訊(例如叢集中的服務)來配置Envoy叢集/路由。它有自己的配置語言。
- consul可能會增加對Envoy的支援(請參閱此部落格文章),但我並不完全瞭解那裡的狀態
什麼是服務網格?
我聽到的另一個術語是“服務網格”。基本上,“服務網格”是先安裝Envoy,並透過Envoy代理所有網路請求。它可以讓您更輕鬆地控制一堆不同的應用程式(可能用不同的程式語言編寫)如何相互通訊。
如果您的所有網路流量都是透過Envoy代理的,並且可從中央伺服器控制所有Envoy配置,那麼您可以:
無需在任何地方更改任何應用程式程式碼。基本上它是一個非常強大/靈活的分散式負載均衡器。
顯然,設定一堆發現服務並執行它們和使用它們,這種以複雜的方式配置內部網路基礎架構比單獨“編寫一個nginx配置檔案”要複雜得多,對大多數人來說。我不打算告訴你誰應該或不應該使用Envoy,但我的經驗是,像Kubernetes一樣,它既非常強大又非常複雜。
超時標題和指標衡量
我真正喜歡Envoy的一個原因是你可以傳遞一個HTTP標頭來告訴它如何重試/超時你的請求!這是驚人的,因為每種程式語言正確實現超時/重試邏輯的工作方式不同,人們總是弄錯。因此能夠傳遞如何測量指標就非常棒。
超時和重試頭都記錄在這裡,這裡是我的最愛:
- x-envoy-max-retries:重試次數
- x-envoy-retry-on:哪些失敗重試(例如5xx或connect-failure)
- x-envoy-upstream-rq-timeout-ms:總超時
- x-envoy-upstream-rq-per-try-timeout-ms:每次重試超時
相關文章
- 基礎知識
- DockerFile基礎知識Docker
- Webpack 基礎知識Web
- js基礎知識JS
- React基礎知識React
- 程式基礎知識
- Docker基礎知識Docker
- qml基礎知識
- Mybatis基礎知識MyBatis
- python基礎知識Python
- Hadoop基礎知識Hadoop
- webpack基礎知識Web
- AI 基礎知識AI
- JSP基礎知識JS
- Dart基礎知識Dart
- RabbitMQ基礎知識MQ
- Android基礎知識Android
- 1、基礎知識
- 前端基礎知識前端
- Camera基礎知識
- Kafka 基礎知識Kafka
- Vue基礎知識Vue
- java基礎知識Java
- linux基礎知識Linux
- PRML 基礎知識
- SpringCloud 基礎知識SpringGCCloud
- javascript基礎知識JavaScript
- python 基礎知識Python
- Laravel基礎知識Laravel
- BGP基礎知識
- Redis基礎知識Redis
- CSS基礎知識CSS
- ThinkPHP基礎知識PHP
- PHP基礎知識PHP
- Nginx基礎知識Nginx
- CSS 基礎知識 初識CSS
- LUA的基礎知識
- DDD基礎知識1