Zadig 面向開發者的自測聯調子環境技術方案詳解

語言: CN / TW / HK
 
Zadig 作為一款先進的開源雲原生軟體交付平臺,為開發者提供雲原生執行環境,支援開發者本地聯調、微服務並行構建和部署、整合測試等。
環境管理在日常的研發過程中基礎問題,開發自測、聯調均需在環境中進行。Zadig 針對環境管理,當前提供瞭如下能力:
  • 建立/銷燬環境
  • 複製環境
  • 託管環境
  • 自測模式(自 v1.11.0 版本推出)
通過建立/銷燬環境,開發者可以便利使用隔離的環境。
通過複製環境,開發者可以快速複製出存量環境,在隔離的相同環境中進行開發、聯調。
通過託管環境,開發者可以將已經存在的 namespace 及該 namespace 中的應用納入到 Zadig 中,通過 Zadig 的能力管理環境和應用。
通過自測模式,開發者之間可以共享同一套基準環境,低成本搭建子環境,在子環境中僅部署少量服務,並和基準服務互動實現開發、聯調。
 
下述將針對 Zadig 的自測模式進行詳細的技術解析,解密自測模式的技術實現:
基於擁有全量服務的基準環境,開發者可以低成本建立不同的子環境,在子環境中開發、變更目標服務,然後子環境與基準環境的服務互動來實現聯調。
 

服務形態

 
在分析技術實現前,先通過如下簡化的服務呼叫來回顧 Zadig 自測模式的使用體感:
 
在叢集中搭建一套基準環境,該環境擁有完整的服務呼叫鏈。沒有灰度標的請求會在基準環境中進行呼叫,呼叫鏈路為 A -> B -> C
當開發者需要進行開發、聯調時,比如涉及到到 A / C 兩個元件的變更,可以基於基準環境新建 dev1 子環境,該子環境中僅部署變更後的 A / C 元件,即 A' / C'。聯調時請求加上灰度標,如在 http header 中設定 x-env=dev1 的灰度標,此時請求會按照 A' -> B -> C' 進行。
同理,當開發、聯調時僅涉及到 B / C 兩個元件的變更時,可以基於基準環境新建 dev2 子環境,該子環境僅部署變更後的 B / C 元件,即 B'' / C''。聯調時加上灰度標 x-env=dev2,這樣請求按照 A -> B'' -> C'' 進行。
 
通過 Zadig 自測模式,叢集中每條業務線僅需一套完整的基準環境,變更的元件在隔離的子環境中開發、部署,然後通過灰度標控制請求在基準環境和子環境中流轉,從而滿足開發、聯調的需求,同時降低搭建新環境的複雜度和成本。
 
使用者操作流程圖如下:
 
上圖中,左側表示使用者操作階段,右側表示每個階段可做的操作的組合和次數。
 
在自測模式的生命週期中,使用者可針對存量環境開啟自測模式,將該環境轉變為基準環境。然後基於基準環境,為業務不同的需求或缺陷修復建立不同的子環境,在自環境中部署變更的服務,通過子環境和基準環境互動,來實現自測聯調。
 

模型

 
系統模型是產品設計和技術實現的基礎,可以整體理解複雜系統的核心。
 
Zadig 自測模式的模型如下:
 
系統層面:
  1. 一個 K8s 叢集,可以有多套自測環境
  2. 每個專案,可以有多套自測環境
  3. 每個自測環境中,擁有一個基準環境和 n 個子環境 (n≥0)
  4. 每個自測環境中,所有服務全部在一個 K8s 叢集,不能跨叢集部署
  5. 每個自測環境中,子環境僅能和基準環境互動,請求鏈至多經過一個子環境
  6. 每個自測環境中,不支援子環境間請求互動
  7. 服務在一個環境中,至多有一個版本
 
自測環境:
  1. 任意時刻,基準環境擁有全量服務
  2. 同步請求的服務間通過 K8s Service 訪問
  3. 同步請求的請求鏈通過 tracing 資訊串接
  4. 子環境中可操作 (新增/刪除/更新) 的服務是基準環境服務的子集
  5. 基準環境、子環境、直接訪問者需要在同一個 Mesh 中
 
通過模型可知,自測環境支援的是同步請求的呼叫鏈,且處於同步請求呼叫鏈上的服務之間通過 K8s Service 進行訪問。
故環境若要開啟自測模式,需要確保業務的同步請求呼叫鏈的服務均有相應的 K8s Service,確保服務間呼叫通過 K8s Service 進行。
 

實現原理

 
先定義關鍵問題:
  1. 鏈路上各個元件和服務能夠根據 請求流量特徵 進行 動態路由
  2. 需要識別出 不同的灰度流量
  3. 需要對流量進行 灰度標識
  4. 需要對服務下的所有節點進行分組,能夠 區分服務版本
 
為此,實現的一般思路為:
  1. 所有流量都經過流量管理元件 --- 根據流量特徵進行動態路由
  2. 可在流量管理元件層面配置路由規則 --- 可控灰度標
  3. 經過流量管理元件的流量保持特殊標記 --- 灰度標可全鏈路傳遞
  4. 流量管理元件能夠根據流量標記,選擇出對應的服務例項 --- 由業務無關元件執行 動態路由/服務發現
  5. 不同版本的服務可部署在不同的環境中 -- 區分服務版本
 
通過上述實現一般思路可知,關鍵的技術實現在於 流量管理元件,通常可以考慮使用 閘道器代理。
而在使用者的技術棧中,流量與閘道器的關係通常會有如下兩種場景:
  1. 所有 (南北/東西) 流量均經過閘道器
  2. 部分東西流量不經過閘道器
 
考慮到流量經過服務時必須均要經過一個流量管理元件,由於不能要求使用者改動業務來處理流量路徑,如服務呼叫均經過閘道器,故閘道器無法滿足要求,因此選擇代理作為流量管理的元件。
 
目前業界基於代理的流量管理服務比較成熟的是 ServiceMesh,根據上述需求,對 ServiceMesh 實現方案有如下技術要求:
  1. 可以基於 http header 等動態路由流量
  2. 基於 K8s Service 做服務發現
  3. proxy 支援 header propagation
 
Istio 和 Linkerd 均是當前主流的 ServiceMesh 開源專案,可以考慮選擇一種作為 ServiceMesh 實現方案。
經調研,截止 Zadig 自測模式實現時,Linkerd 在如下功能層面暫不滿足:
  1. 暫不支援 SMI TrafficSplit v1alpha3/v1alpha4,即不支援基於 http header 等做動態路由,issue 參見 link
  2. 暫不支援 header propagation,issue 參見 link
 
Istio 均滿足上述需求,同時社群活躍,故採用 Istio 作為 Zadig 自測模式的 ServiceMesh 實現方案。
 

技術實現

流量管理

Istio 實現自測模式,主要依賴於如下 2 個 CRD:
  • VirtualService
  • EnvoyFilter
 
VirtualService 定義路由規則,控制流量路由到服務上的行為,基於部署平臺的能力實現服務發現,如 K8s Service。
EnvoyFilter 管理每個服務流量經過的 Envoy 配置,可被用來動態調整流量特徵。
 
在 Zadig 自測模式中的使用如下:
 
備註:
  • DestinationRule 也是 Istio 中常用的資源,在 VirtualSerivce 路由生效後,控制流量實際匯入的服務
  • 但通過 Zadig 自測模式的模型可知,一個環境僅會部署服務至多一個版本,可通過環境區分服務版本,故無需藉助 DestinationRule 來區分一個環境中同一類服務的不同版本
 

灰度標傳遞

灰度標的傳遞在自測模式中是關鍵問題,有三種解決方案:
  1. 應用自身對於入請求引發的出請求,主動傳遞對應的灰度標
  2. 集成了 tracing 能力的應用,會通過 tracing sdk 等通過 trace id 等串聯請求,Istio 可在服務接收到請求時記錄 trace id 和灰度標的關係,然後服務發出請求時根據 trace id 自動增加灰度標
  3. 對於 Java 語言,可通過 Java Agent 劫持程式執行時流量,根據入請求引發的出請求,自動新增灰度標
 
方案 1 需要應用少量修改。
方案 2 依賴應用已經整合 tracing 能力。
方案 3 會限制應用開發語言,同時需要在 Java Agent 中實現類似 Istio 中的服務發現和流量動態路由的能力。
 
Zadig 自測模式不限制使用者使用的開發語言,同時又希望儘量減少對使用者現有應用的侵入,故採用方案 2。
簡化後的方案如下:
 
Zadig 在系統層面提供一個 Cache 服務:
  • 當請求進入服務時,Envoy 會請求 Cache 服務記錄 trace id 和 灰度標 的對應關係
  • 當請求流出服務時,Envoy 會根據請求中的 trace id,查詢 Cache 服務獲取 灰度標,配置在出請求
 

使用者操作實現

對於使用者操作,下圖整理了平臺層面對應的操作實現:
 
使用者對自測環境的操作,在平臺層面會涉及對子環境、基準環境、Istio 環境的變更,具體的操作如上所示,不再贅述。
 
核心程式碼:
  • K8s 專案:
    • 後端:https://github.com/koderover/zadig/pull/1214
    • 前端:https://github.com/koderover/zadig-portal/pull/660
  • Helm 專案:
    • 後端:https://github.com/koderover/zadig/pull/1425
    • 前端:https://github.com/koderover/zadig-portal/pull/791
 

展望

開發者常用的開發工具是 IDE,隨著 Zadig v1.12.0 的重磅釋出,已推出面向 VScode IDE 的外掛,結合自測模式的能力,使得開發者之間在一個工作介面中就可以輕鬆進行遠端開發和聯調,進一步提升開發者的生產力。

自測模式是降低環境管理複雜度和部署成本的重要能力,Zadig 將會持續迭代,在產品層面給使用者帶來更好的環境管理體驗。

Zadig,讓工程師更專注創造!

 

歡迎加入 開源吐槽群🔥

Zadig on Github

Zadig on Gitee