Zadig 面向開發(fā)者的自測聯(lián)調(diào)子環(huán)境技術(shù)方案詳解
Zadig 作為一款先進(jìn)的開源云原生軟件交付平臺,為開發(fā)者提供云原生運(yùn)行環(huán)境,支持開發(fā)者本地聯(lián)調(diào)、微服務(wù)并行構(gòu)建和部署、集成測試等。
環(huán)境管理在日常的研發(fā)過程中基礎(chǔ)問題,開發(fā)自測、聯(lián)調(diào)均需在環(huán)境中進(jìn)行。Zadig 針對環(huán)境管理,當(dāng)前提供了如下能力:
- 創(chuàng)建/銷毀環(huán)境
- 復(fù)制環(huán)境
- 托管環(huán)境
- 自測模式(自 v1.11.0 版本推出)
通過創(chuàng)建/銷毀環(huán)境,開發(fā)者可以便利使用隔離的環(huán)境。
通過復(fù)制環(huán)境,開發(fā)者可以快速復(fù)制出存量環(huán)境,在隔離的相同環(huán)境中進(jìn)行開發(fā)、聯(lián)調(diào)。
通過托管環(huán)境,開發(fā)者可以將已經(jīng)存在的 namespace 及該 namespace 中的應(yīng)用納入到 Zadig 中,通過 Zadig 的能力管理環(huán)境和應(yīng)用。
通過自測模式,開發(fā)者之間可以共享同一套基準(zhǔn)環(huán)境,低成本搭建子環(huán)境,在子環(huán)境中僅部署少量服務(wù),并和基準(zhǔn)服務(wù)交互實(shí)現(xiàn)開發(fā)、聯(lián)調(diào)。
下述將針對 Zadig 的自測模式進(jìn)行詳細(xì)的技術(shù)解析,解密自測模式的技術(shù)實(shí)現(xiàn):
基于擁有全量服務(wù)的基準(zhǔn)環(huán)境,開發(fā)者可以低成本建立不同的子環(huán)境,在子環(huán)境中開發(fā)、變更目標(biāo)服務(wù),然后子環(huán)境與基準(zhǔn)環(huán)境的服務(wù)交互來實(shí)現(xiàn)聯(lián)調(diào)。
服務(wù)形態(tài)
在分析技術(shù)實(shí)現(xiàn)前,先通過如下簡化的服務(wù)調(diào)用來回顧 Zadig 自測模式的使用體感:
在集群中搭建一套基準(zhǔn)環(huán)境,該環(huán)境擁有完整的服務(wù)調(diào)用鏈。沒有灰度標(biāo)的請求會在基準(zhǔn)環(huán)境中進(jìn)行調(diào)用,調(diào)用鏈路為 A -> B -> C
當(dāng)開發(fā)者需要進(jìn)行開發(fā)、聯(lián)調(diào)時(shí),比如涉及到到 A / C 兩個(gè)組件的變更,可以基于基準(zhǔn)環(huán)境新建 dev1 子環(huán)境,該子環(huán)境中僅部署變更后的 A / C 組件,即 A' / C'。聯(lián)調(diào)時(shí)請求加上灰度標(biāo),如在 http header 中設(shè)定 x-env=dev1 的灰度標(biāo),此時(shí)請求會按照 A' -> B -> C' 進(jìn)行。
同理,當(dāng)開發(fā)、聯(lián)調(diào)時(shí)僅涉及到 B / C 兩個(gè)組件的變更時(shí),可以基于基準(zhǔn)環(huán)境新建 dev2 子環(huán)境,該子環(huán)境僅部署變更后的 B / C 組件,即 B'' / C''。聯(lián)調(diào)時(shí)加上灰度標(biāo) x-env=dev2 ,這樣請求按照 A -> B'' -> C'' 進(jìn)行。
通過 Zadig 自測模式,集群中每條業(yè)務(wù)線僅需一套完整的基準(zhǔn)環(huán)境,變更的組件在隔離的子環(huán)境中開發(fā)、部署,然后通過灰度標(biāo)控制請求在基準(zhǔn)環(huán)境和子環(huán)境中流轉(zhuǎn),從而滿足開發(fā)、聯(lián)調(diào)的需求,同時(shí)降低搭建新環(huán)境的復(fù)雜度和成本。
用戶操作流程圖如下:
上圖中,左側(cè)表示用戶操作階段,右側(cè)表示每個(gè)階段可做的操作的組合和次數(shù)。
在自測模式的生命周期中,用戶可針對存量環(huán)境開啟自測模式,將該環(huán)境轉(zhuǎn)變?yōu)榛鶞?zhǔn)環(huán)境。然后基于基準(zhǔn)環(huán)境,為業(yè)務(wù)不同的需求或缺陷修復(fù)創(chuàng)建不同的子環(huán)境,在自環(huán)境中部署變更的服務(wù),通過子環(huán)境和基準(zhǔn)環(huán)境交互,來實(shí)現(xiàn)自測聯(lián)調(diào)。
模型
系統(tǒng)模型是產(chǎn)品設(shè)計(jì)和技術(shù)實(shí)現(xiàn)的基礎(chǔ),可以整體理解復(fù)雜系統(tǒng)的核心。
Zadig 自測模式的模型如下:
系統(tǒng)層面:
- 一個(gè) K8s 集群,可以有多套自測環(huán)境
- 每個(gè)項(xiàng)目,可以有多套自測環(huán)境
- 每個(gè)自測環(huán)境中,擁有一個(gè)基準(zhǔn)環(huán)境和 n 個(gè)子環(huán)境 (n≥0)
- 每個(gè)自測環(huán)境中,所有服務(wù)全部在一個(gè) K8s 集群,不能跨集群部署
- 每個(gè)自測環(huán)境中,子環(huán)境僅能和基準(zhǔn)環(huán)境交互,請求鏈至多經(jīng)過一個(gè)子環(huán)境
- 每個(gè)自測環(huán)境中,不支持子環(huán)境間請求交互
- 服務(wù)在一個(gè)環(huán)境中,至多有一個(gè)版本
自測環(huán)境:
- 任意時(shí)刻,基準(zhǔn)環(huán)境擁有全量服務(wù)
- 同步請求的服務(wù)間通過 K8s Service 訪問
- 同步請求的請求鏈通過 tracing 信息串接
- 子環(huán)境中可操作 (新增/刪除/更新) 的服務(wù)是基準(zhǔn)環(huán)境服務(wù)的子集
- 基準(zhǔn)環(huán)境、子環(huán)境、直接訪問者需要在同一個(gè) Mesh 中
通過模型可知,自測環(huán)境支持的是同步請求的調(diào)用鏈,且處于同步請求調(diào)用鏈上的服務(wù)之間通過 K8s Service 進(jìn)行訪問。
故環(huán)境若要開啟自測模式,需要確保業(yè)務(wù)的同步請求調(diào)用鏈的服務(wù)均有相應(yīng)的 K8s Service,確保服務(wù)間調(diào)用通過 K8s Service 進(jìn)行。
實(shí)現(xiàn)原理
先定義關(guān)鍵問題:
- 鏈路上各個(gè)組件和服務(wù)能夠根據(jù) 請求流量特征 進(jìn)行 動(dòng)態(tài)路由
- 需要識別出 不同的灰度流量
- 需要對流量進(jìn)行 灰度標(biāo)識
- 需要對服務(wù)下的所有節(jié)點(diǎn)進(jìn)行分組,能夠 區(qū)分服務(wù)版本
為此,實(shí)現(xiàn)的一般思路為:
- 所有流量都經(jīng)過流量管理組件 --- 根據(jù)流量特征進(jìn)行動(dòng)態(tài)路由
- 可在流量管理組件層面配置路由規(guī)則 --- 可控灰度標(biāo)
經(jīng)過流量管理組件的流量保持特殊標(biāo)記 --- 灰度標(biāo)可全鏈路傳遞
流量管理組件能夠根據(jù)流量標(biāo)記,選擇出對應(yīng)的服務(wù)實(shí)例 --- 由業(yè)務(wù)無關(guān)組件執(zhí)行 動(dòng)態(tài)路由/服務(wù)發(fā)現(xiàn)
不同版本的服務(wù)可部署在不同的環(huán)境中 -- 區(qū)分服務(wù)版本
通過上述實(shí)現(xiàn)一般思路可知,關(guān)鍵的技術(shù)實(shí)現(xiàn)在于 流量管理組件,通常可以考慮使用 網(wǎng)關(guān) 或 代理。
而在用戶的技術(shù)棧中,流量與網(wǎng)關(guān)的關(guān)系通常會有如下兩種場景:
所有 (南北/東西) 流量均經(jīng)過網(wǎng)關(guān)
部分東西流量不經(jīng)過網(wǎng)關(guān)
考慮到流量經(jīng)過服務(wù)時(shí)必須均要經(jīng)過一個(gè)流量管理組件,由于不能要求用戶改動(dòng)業(yè)務(wù)來處理流量路徑,如服務(wù)調(diào)用均經(jīng)過網(wǎng)關(guān),故網(wǎng)關(guān)無法滿足要求,因此選擇代理作為流量管理的組件。
目前業(yè)界基于代理的流量管理服務(wù)比較成熟的是 ServiceMesh,根據(jù)上述需求,對 ServiceMesh 實(shí)現(xiàn)方案有如下技術(shù)要求:
- 可以基于 http header 等動(dòng)態(tài)路由流量
- 基于 K8s Service 做服務(wù)發(fā)現(xiàn)
- proxy 支持 header propagation
Istio 和 Linkerd 均是當(dāng)前主流的 ServiceMesh 開源項(xiàng)目,可以考慮選擇一種作為 ServiceMesh 實(shí)現(xiàn)方案。經(jīng)調(diào)研,截止 Zadig 自測模式實(shí)現(xiàn)時(shí),Linkerd 在如下功能層面暫不滿足:
暫不支持 SMI TrafficSplit v1alpha3/v1alpha4,即不支持基于 http header 等做動(dòng)態(tài)路由,issue 參見 link[1]
暫不支持 header propagation,issue 參見 link[2]
Istio 均滿足上述需求,同時(shí)社區(qū)活躍,故采用 Istio 作為 Zadig 自測模式的 ServiceMesh 實(shí)現(xiàn)方案。
技術(shù)實(shí)現(xiàn)
流量管理
VirtualService 定義路由規(guī)則,控制流量路由到服務(wù)上的行為,基于部署平臺的能力實(shí)現(xiàn)服務(wù)發(fā)現(xiàn),如 K8s Service。
EnvoyFilter 管理每個(gè)服務(wù)流量經(jīng)過的 Envoy 配置,可被用來動(dòng)態(tài)調(diào)整流量特征。
在 Zadig 自測模式中的使用如下:
備注:
- DestinationRule 也是 Istio 中常用的資源,在 VirtualSerivce 路由生效后,控制流量實(shí)際導(dǎo)入的服務(wù)
- 但通過 Zadig 自測模式的模型可知,一個(gè)環(huán)境僅會部署服務(wù)至多一個(gè)版本,可通過環(huán)境區(qū)分服務(wù)版本,故無需借助 DestinationRule 來區(qū)分一個(gè)環(huán)境中同一類服務(wù)的不同版本
灰度標(biāo)傳遞
灰度標(biāo)的傳遞在自測模式中是關(guān)鍵問題,有三種解決方案:
- 應(yīng)用自身對于入請求引發(fā)的出請求,主動(dòng)傳遞對應(yīng)的灰度標(biāo)
- 集成了 tracing 能力的應(yīng)用,會通過 tracing sdk 等通過 trace id 等串聯(lián)請求,Istio 可在服務(wù)接收到請求時(shí)記錄 trace id 和灰度標(biāo)的關(guān)系,然后服務(wù)發(fā)出請求時(shí)根據(jù) trace id 自動(dòng)增加灰度標(biāo)
- 對于 Java 語言,可通過 Java Agent 劫持程序運(yùn)行時(shí)流量,根據(jù)入請求引發(fā)的出請求,自動(dòng)添加灰度標(biāo)
方案 1 需要應(yīng)用少量修改。
方案 2 依賴應(yīng)用已經(jīng)集成 tracing 能力。
方案 3 會限制應(yīng)用開發(fā)語言,同時(shí)需要在 Java Agent 中實(shí)現(xiàn)類似 Istio 中的服務(wù)發(fā)現(xiàn)和流量動(dòng)態(tài)路由的能力。
Zadig 自測模式不限制用戶使用的開發(fā)語言,同時(shí)又希望盡量減少對用戶現(xiàn)有應(yīng)用的侵入,故采用方案 2。
簡化后的方案如下:
Zadig 在系統(tǒng)層面提供一個(gè) Cache 服務(wù):
- 當(dāng)請求進(jìn)入服務(wù)時(shí),Envoy 會請求 Cache 服務(wù)記錄 trace id 和 灰度標(biāo) 的對應(yīng)關(guān)系
- 當(dāng)請求流出服務(wù)時(shí),Envoy 會根據(jù)請求中的 trace id,查詢 Cache 服務(wù)獲取 灰度標(biāo),配置在出請求
用戶操作實(shí)現(xiàn)
對于用戶操作,下圖整理了平臺層面對應(yīng)的操作實(shí)現(xiàn):
用戶對自測環(huán)境的操作,在平臺層面會涉及對子環(huán)境、基準(zhǔn)環(huán)境、Istio 環(huán)境的變更,具體的操作如上所示,不再贅述。
核心代碼:
K8s 項(xiàng)目:
- 后端:https://github.com/koderover/zadig/pull/1214
- 前端:https://github.com/koderover/zadig-portal/pull/660
Helm 項(xiàng)目:
- 后端:https://github.com/koderover/zadig/pull/1425
- 前端:https://github.com/koderover/zadig-portal/pull/791
展望
開發(fā)者常用的開發(fā)工具是 IDE,隨著 Zadig v1.12.0 的重磅發(fā)布,已推出面向 VScode IDE 的插件,結(jié)合自測模式的能力,使得開發(fā)者之間在一個(gè)工作界面中就可以輕松進(jìn)行遠(yuǎn)程開發(fā)和聯(lián)調(diào),進(jìn)一步提升開發(fā)者的生產(chǎn)力。
自測模式是降低環(huán)境管理復(fù)雜度和部署成本的重要能力,Zadig 將會持續(xù)迭代,在產(chǎn)品層面給用戶帶來更好的環(huán)境管理體驗(yàn)。
官網(wǎng):https://koderover.com/
github: https://github.com/koderover/zadig
參考鏈接:
[1] https://github.com/linkerd/linkerd2/issues/7155
[2] https://github.com/linkerd/linkerd2/issues/4219