Zadig 面向開發者的自測聯調子環境技術方案詳解
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 自測模式的模型如下:
系統層面:
- 一個 K8s 叢集,可以有多套自測環境
- 每個專案,可以有多套自測環境
- 每個自測環境中,擁有一個基準環境和 n 個子環境 (n≥0)
- 每個自測環境中,所有服務全部在一個 K8s 叢集,不能跨叢集部署
- 每個自測環境中,子環境僅能和基準環境互動,請求鏈至多經過一個子環境
- 每個自測環境中,不支援子環境間請求互動
- 服務在一個環境中,至多有一個版本
自測環境:
- 任意時刻,基準環境擁有全量服務
- 同步請求的服務間通過 K8s Service 訪問
- 同步請求的請求鏈通過 tracing 資訊串接
- 子環境中可操作 (新增/刪除/更新) 的服務是基準環境服務的子集
- 基準環境、子環境、直接訪問者需要在同一個 Mesh 中
通過模型可知,自測環境支援的是同步請求的呼叫鏈,且處於同步請求呼叫鏈上的服務之間通過 K8s Service 進行訪問。
故環境若要開啟自測模式,需要確保業務的同步請求呼叫鏈的服務均有相應的 K8s Service,確保服務間呼叫通過 K8s Service 進行。
實現原理
先定義關鍵問題:
- 鏈路上各個元件和服務能夠根據 請求流量特徵 進行 動態路由
- 需要識別出 不同的灰度流量
- 需要對流量進行 灰度標識
- 需要對服務下的所有節點進行分組,能夠 區分服務版本
為此,實現的一般思路為:
- 所有流量都經過流量管理元件 --- 根據流量特徵進行動態路由
- 可在流量管理元件層面配置路由規則 --- 可控灰度標
- 經過流量管理元件的流量保持特殊標記 --- 灰度標可全鏈路傳遞
- 流量管理元件能夠根據流量標記,選擇出對應的服務例項 --- 由業務無關元件執行 動態路由/服務發現
- 不同版本的服務可部署在不同的環境中 -- 區分服務版本
通過上述實現一般思路可知,關鍵的技術實現在於
流量管理元件,通常可以考慮使用
閘道器 或
代理。
而在使用者的技術棧中,流量與閘道器的關係通常會有如下兩種場景:
- 所有 (南北/東西) 流量均經過閘道器
- 部分東西流量不經過閘道器
考慮到流量經過服務時必須均要經過一個流量管理元件,由於不能要求使用者改動業務來處理流量路徑,如服務呼叫均經過閘道器,故閘道器無法滿足要求,因此選擇代理作為流量管理的元件。
目前業界基於代理的流量管理服務比較成熟的是 ServiceMesh,根據上述需求,對 ServiceMesh 實現方案有如下技術要求:
- 可以基於 http header 等動態路由流量
- 基於 K8s Service 做服務發現
- proxy 支援 header propagation
Istio 和 Linkerd 均是當前主流的 ServiceMesh 開源專案,可以考慮選擇一種作為 ServiceMesh 實現方案。
經調研,截止 Zadig 自測模式實現時,Linkerd 在如下功能層面暫不滿足:
- 暫不支援 SMI TrafficSplit v1alpha3/v1alpha4,即不支援基於 http header 等做動態路由,issue 參見 link
- 暫不支援 header propagation,issue 參見 link
Istio 均滿足上述需求,同時社群活躍,故採用 Istio 作為 Zadig 自測模式的 ServiceMesh 實現方案。
技術實現
流量管理
Istio 實現自測模式,主要依賴於如下 2 個 CRD:
- VirtualService
- EnvoyFilter
VirtualService 定義路由規則,控制流量路由到服務上的行為,基於部署平臺的能力實現服務發現,如 K8s Service。
EnvoyFilter 管理每個服務流量經過的 Envoy 配置,可被用來動態調整流量特徵。
在 Zadig 自測模式中的使用如下:
備註:
- DestinationRule 也是 Istio 中常用的資源,在 VirtualSerivce 路由生效後,控制流量實際匯入的服務
- 但通過 Zadig 自測模式的模型可知,一個環境僅會部署服務至多一個版本,可通過環境區分服務版本,故無需藉助 DestinationRule 來區分一個環境中同一類服務的不同版本
灰度標傳遞
灰度標的傳遞在自測模式中是關鍵問題,有三種解決方案:
- 應用自身對於入請求引發的出請求,主動傳遞對應的灰度標
- 集成了 tracing 能力的應用,會通過 tracing sdk 等通過 trace id 等串聯請求,Istio 可在服務接收到請求時記錄 trace id 和灰度標的關係,然後服務發出請求時根據 trace id 自動增加灰度標
- 對於 Java 語言,可通過 Java Agent 劫持程式執行時流量,根據入請求引發的出請求,自動新增灰度標
方案 1 需要應用少量修改。
方案 2 依賴應用已經整合 tracing 能力。
方案 3 會限制應用開發語言,同時需要在 Java Agent 中實現類似 Istio 中的服務發現和流量動態路由的能力。
Zadig 自測模式不限制使用者使用的開發語言,同時又希望儘量減少對使用者現有應用的侵入,故採用方案 2。
簡化後的方案如下:
Zadig 在系統層面提供一個 Cache 服務:
- 當請求進入服務時,Envoy 會請求 Cache 服務記錄 trace id 和 灰度標 的對應關係
- 當請求流出服務時,Envoy 會根據請求中的 trace id,查詢 Cache 服務獲取 灰度標,配置在出請求
使用者操作實現
對於使用者操作,下圖整理了平臺層面對應的操作實現:
使用者對自測環境的操作,在平臺層面會涉及對子環境、基準環境、Istio 環境的變更,具體的操作如上所示,不再贅述。
核心程式碼:
- K8s 專案:
- 後端:http://github.com/koderover/zadig/pull/1214
- 前端:http://github.com/koderover/zadig-portal/pull/660
- Helm 專案:
- 後端:http://github.com/koderover/zadig/pull/1425
- 前端:http://github.com/koderover/zadig-portal/pull/791
展望
開發者常用的開發工具是 IDE,隨著 Zadig v1.12.0 的重磅釋出,已推出面向 VScode IDE 的外掛,結合自測模式的能力,使得開發者之間在一個工作介面中就可以輕鬆進行遠端開發和聯調,進一步提升開發者的生產力。
自測模式是降低環境管理複雜度和部署成本的重要能力,Zadig 將會持續迭代,在產品層面給使用者帶來更好的環境管理體驗。
Zadig,讓工程師更專注創造!
歡迎加入 開源吐槽群🔥
「其他文章」
- 基於 Zadig 的 GitOps 實踐
- 極速 Zadig 構建效率是這樣煉成的
- 主機基礎設施如何使用 Zadig 做持續交付
- Zadig 環境負載均衡:0 人工干預,極速部署
- 打通了!Jira Zadig 實現需求與研發過程追蹤
- 雲原生 DevOps 現狀調研問卷徵集:KodeRover 聯合 OSCHINA 推出
- Zadig v1.13.0 相信開放的力量,工作流連通一切價值
- 飛書影片會議端到端整合測試工程實踐經驗總結 - Zadig 應用案例
- 在解決了 2961 個使用者反饋後,我做出了這樣的改變...
- 基於 Ingress Controller 在叢集外訪問 Zadig 自測環境(最佳實踐)
- iMile 利用 Zadig 多雲環境周部署千次,跨雲跨地域持續交付全球業務
- 穩!上千微服務接入 Zadig 的最佳姿勢(Helm Chart 篇)
- 穩!上千微服務接入 Zadig 的最佳姿勢(K8s YAML 篇)
- Zadig 洞態 IAST:讓安全溶於持續交付
- TT 語音落地 Zadig:開源共創 Helm 接入場景,環境治理搞得定!
- 00後雲工程師用 Zadig 為企業研發開源節流
- Zadig 構建究竟有何強大?一起來實踐
- 妙盈科技全面實施 Zadig 擁抱雲原生
- Zadig SonarQube,為開發過程安全保駕
- Zadig v1.12.0 推出 VS Code 外掛,全面支援 GitOps ,好工具就要到最後一公里