本篇內(nèi)容介紹了“生產(chǎn)環(huán)境的 ServiceMesh 流量劫持怎么搞”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
李滄網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)公司,李滄網(wǎng)站設(shè)計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為李滄近1000家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)公司要多少錢,請找那個售后服務(wù)好的李滄做網(wǎng)站的公司定做!
ServiceMesh 社區(qū)使用 iptables 實現(xiàn)流量劫持,這個機制在百度生產(chǎn)環(huán)境使用會遇到一些問題,因此,我們探索了其他的流量劫持方式,如基于服務(wù)發(fā)現(xiàn)的流量劫持機制、基于 SDK 的流量劫持機制、基于固定 Virutal IP 的流量劫持機制等。
本文主要介紹基于服務(wù)發(fā)現(xiàn)的流量劫持機制,這個機制是在服務(wù)發(fā)現(xiàn)步驟 "偽造" 地址來完成流量劫持。
我們先簡單的看看社區(qū)的流量劫持方案,首先看下 Inbound 流量劫持,如圖1 所示:
所有入站流量都會經(jīng)過 iptables;
iptables 忽略非 TCP 以及訪問 istio 管理端口的流量,將其他入站流量轉(zhuǎn)發(fā)給 Envoy;
Envoy 處理完后再將流量轉(zhuǎn)發(fā)給 App;
上述流量又一次經(jīng)過 iptables 規(guī)則匹配,iptables 將具備以下特點的流量當(dāng)做 Envoy 發(fā)出的流量直接轉(zhuǎn)發(fā)給目的地:
Envoy 發(fā)出的;
輸出設(shè)備時 lo;
目的地時127.0.0.1。
至此 iptables 完成了 Envoy 對 Inbound 流量的劫持和轉(zhuǎn)發(fā)。
圖1 iptables 流量劫持
接下來咱們再來看看 Outbound 流量劫持,如圖2所示:
App 給 Server 發(fā)送流量;
iptables 將滿足以下條件的流量轉(zhuǎn)發(fā)給 Envoy:
不是 Envoy 發(fā)出的;
輸出設(shè)備不是 lo;
目的地址不是 localhost。
Envoy 處理完后,選定 Server 的一個 endpoint 轉(zhuǎn)發(fā)流量;
iptables 將滿足以下條件的流量直接發(fā)給目的地,也就是 Server:
Envoy 發(fā)出的;
輸出設(shè)備不是 lo。
圖2 iptables 劫持 outbound 流量
至此,iptables 完成了 inbound 和 outbound 的流量劫持,該機制的好處在于可以透明的劫持業(yè)務(wù)流量,但是在百度生產(chǎn)環(huán)境使用時存在一些問題:
可管控性差,內(nèi)網(wǎng)各容器網(wǎng)絡(luò)沒有隔離,iptables 是全局工具,可被其它用戶修改,導(dǎo)致流量劫持異常;它作為單機流量管理工具,沒有成熟的平臺/產(chǎn)品進(jìn)行統(tǒng)一的管理。
大并發(fā)場景下存在一定的轉(zhuǎn)發(fā)性能問題;規(guī)則數(shù)過多時變更時延大。
因此我們探索了其他的劫持機制,接下來我來介紹下百度生產(chǎn)環(huán)境正在使用的流量劫持機制——基于服務(wù)發(fā)現(xiàn)的流量劫持機制。
先來看下該機制的設(shè)計思路,服務(wù)流量根據(jù)方向的不同,可以分為 Outbound 和 Inbound。如圖3 所示,有兩個服務(wù):Client 和 Server,Client 的 Envoy 記為 EnvoyC,Server的 Envoy 記為 EnvoyS(本質(zhì)是一樣的,只不過為了表述方便取了不同的名字)。EnvoyC 要劫持的流量是來自在相同機器上的 Client 發(fā)出的 Outbound 流量,而 EnvoyS 要劫持的流量大部分是來自不同機器上的服務(wù)發(fā)給 Server 的流量。
這兩種流量的劫持機制可以分開設(shè)計,考慮到 ServiceMesh 常用的策略都在 EnvoyC 上生效,因此我們先設(shè)計了 EnvoyC 劫持 Outbound 流量的方案。
圖3 ServiceMesh 流量劫持
一個完整的請求大概要經(jīng)歷域名解析(或者是服務(wù)發(fā)現(xiàn))、建立連接、發(fā)送請求這幾個步驟,現(xiàn)在 iptables 用不了,其他依賴 Kernel 的劫持方案暫時也用不了,我們將目光轉(zhuǎn)向第一步——服務(wù)發(fā)現(xiàn)。百度生產(chǎn)環(huán)境的服務(wù)基本都依賴 Naming 系統(tǒng)來解析服務(wù)真實的 ip 列表,我們只需要讓 Naming 系統(tǒng)返回 Envoy 的 ip 地址,就能將服務(wù)的 Outbound 流量劫持到 Envoy。
如圖4 所示,Naming Agent 是單機上負(fù)責(zé)服務(wù)發(fā)現(xiàn)的 Agent。Client 在發(fā)送請求前,會先去 Naming Agent 問:我想給 Server 發(fā)個請求,請給我他的地址。這時候 Naming Agent 就會把 Envoy 的地址當(dāng)成 Server 的地址告訴 Client。接下來 Client 就會乖乖的把請求發(fā)給 Envoy,Envoy 再根據(jù)一系列的策略把請求轉(zhuǎn)發(fā)給 Server。
圖4 Outbound 流量劫持
這種劫持機制的好處在于改造事項集中在 Naming 系統(tǒng),使用該 Naming 系統(tǒng)的服務(wù)都能通過該方案透明的完成 Outbound 流量劫持。
另外,基于 Naming 系統(tǒng)的流量劫持機制可以動態(tài)回傳流量治理參數(shù)給業(yè)務(wù)服務(wù),如超時、重試等。這種能力的其中一個用途是可以避免 Mesh 劫持后的多級重試導(dǎo)致服務(wù)雪崩,具體做法如圖5 所示,當(dāng)業(yè)務(wù)流量被 Envoy 劫持后,Envoy 會通過 Naming Agent 將業(yè)務(wù)服務(wù)的重試次數(shù)置為0。
圖5 動態(tài)回傳流量治理配置
此外,為了降低數(shù)據(jù)面(Envoy)故障時對業(yè)務(wù)服務(wù)的影響,我們還增加了數(shù)據(jù)面自動容災(zāi)、主動關(guān)閉 Mesh 等能力:
數(shù)據(jù)面故障自動容災(zāi)能力:當(dāng) Envoy 異常時,Naming Agent 會自動返回 Server 實際的實例列表,此時,Client 會自動回退為非 Mesh 劫持模式。
主動關(guān)閉 Mesh 劫持:用戶也可以主動關(guān)閉 Mesh 劫持,此時,Client 也會自動回退為非 Mesh 劫持模式。
至此,Envoy 能夠劫持 Outbound 流量,但是,只有 Outbound 流量劫持能力的 Envoy 是不完整的,對于入口限流等功能,還需要具備 Inbound 流量劫持的能力。
Inbound 流量主要來自其他機器,我們無法再依賴單機的 Naming Agent 偽造地址,得另尋出路。還是基于 Naming 系統(tǒng)的思路,EnvoyS 和 Server 是同機部署的,他們對外提供的地址,唯一的區(qū)別在于端口,因此,只要我們能更換 EnvoyC 訪問 Server 時的端口,就能將 Inbound 流量劫持到 EnvoyS。
如圖4 所示,EgressPort 接收 Outbound 流量,IngressPort 接收 Inbound 流量。
控制面(Istio)將 EnvoyS 的 IngressPort 作為 Server 的端口下發(fā)給 EnvoyC;
EnvoyC 將訪問 Server 的流量轉(zhuǎn)發(fā)到 IngressPort,被 EnvoyS 收到。
EnvoyS 再將流量轉(zhuǎn)發(fā)到 Server 服務(wù)端口 NamedPort。
至此,Envoy 具備了部分 Inbound 流量劫持能力,為什么說是部分呢,因為這種機制無法劫持入口服務(wù)的流量。入口服務(wù)的上游(Client)是外部服務(wù),它的配置不受 Istio 控制,也就無法采用該機制完成流量劫持,后續(xù)需進(jìn)一步完善該能力。
除了上面提到的問題,Inbound 流量劫持還存在一些坑。我們發(fā)現(xiàn)當(dāng) EnvoyS 劫持了 Inbound 流量后,L3/L4 層通信協(xié)議的部分健康檢查機制失效。
L3/L4 層通信協(xié)議的主動健康檢查部分功能失效
原因:L3/L4 層通信協(xié)議的主動健康檢查默認(rèn)是檢查端口存活,當(dāng)流量被劫持到 EnvoyS 后,該功能實際檢查的是 EnvoyS 的 IngressPort 端口存活,也就無法反饋 Server NamedPort 端口存活情況。
我們目前采用的解決方案是采用兩段式主動健康檢查機制,兩段分別是:
Envoy 間健康檢查:EnvoyC 對 EnvoyS 的健康檢查,該健康檢查能夠反饋 EnvoyS 和 Server 的狀態(tài)。
Envoy 和本地 Service 間健康檢查:EnvoyS 檢查 Server 端口存活情況,檢查結(jié)果由 EnvoyS 反饋給 EnvoyC。
L3/L4 層通信 協(xié)議的異常點驅(qū)逐(被動健康檢查)功能失效
原因:L3/L4 層通信協(xié)議的異常點驅(qū)逐條件是連接異常,當(dāng)流量被劫持到 EnvoyS 后,該功能實際上檢查的是 EnvoyC 能否正常的跟 EnvoyS 建立連接,而不是 Server。
我們目前采用的解決方案是完善L3/L4 層通信協(xié)議的驅(qū)逐條件,增加訪問超時作為驅(qū)逐條件。因此,當(dāng) Server 異常時,EnvoyC 會因為一直無法得到應(yīng)答,而將該下游標(biāo)記為異常。
最后簡單的對比下上述兩種方案:
基于服務(wù)發(fā)現(xiàn)的流量劫持機制目前已應(yīng)用在百度App、信息流、百度地圖等業(yè)務(wù)線的數(shù)百個服務(wù)、數(shù)萬個實例上。這種流量劫持機制能夠減少轉(zhuǎn)發(fā)性能的損耗,具備數(shù)據(jù)面故障自動容災(zāi)能力,能夠動態(tài)回傳流量治理參數(shù)。但是該機制也缺失一些能力:無法劫持入口服務(wù)的流量,后續(xù)我們將進(jìn)一步補齊該能力。
“生產(chǎn)環(huán)境的 ServiceMesh 流量劫持怎么搞”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!