在2019年5月,CNCF 籌建通用數據平面 API 工做組(Universal Data Plane API Working Group / UDPA-WG),以制定數據平面的標準 API。git
當時我寫了一個博客文章 「CNCF 正在籌建通用數據平面 API 工做組,以制定數據平面的標準 API」 對此進行了介紹。當時 UDPA 還處於很是早期的籌備階段,信息很是的少。github
如今9個月過去了,我最近收集並整理了一下 UDPA 目前的狀況和信息,給你們介紹一下 UDPA 目前最新的進展(截止2020年2月24日)。express
另外螞蟻金服開源的雲原生網絡代理 MOSN 目前已經支持 xDS v2 API,後面也會逐步向着 UDPA 的方向去演進,兼容標準 Istio,感興趣的讀者能夠去了解下。後端
MOSN:github.com/mosn/monapi
首先快速介紹一下什麼是 UDPA:緩存
UDPA 的目標,援引自 github.com/cncf/udpa 的描述:安全
通用數據平面 API 工做組(UDPA-WG)的目標是召集對數據平面代理和負載均衡器的通用控制和配置 API 感興趣的業界人士。bash
UDPA 的願景,一樣援引:服務器
通用數據平面 API(UDPA)的願景在 blog.envoyproxy.io/the-univers… 中闡明。咱們將尋求一組 API,它們爲 L4/L7 數據平面配置提供事實上的標準,相似於 SDN 中 L2/L3/L4 的 OpenFlow 所扮演的角色。 這些 API 將在 proto3 中規範定義,並經過定義良好的、穩定 API 版本控制策略,從現有的 Envoy xDS API 逐步演進。API 將涵蓋服務發現、負載均衡分配、路由發現、監聽器配置、安全發現、負載報告、運行情況檢查委託等。 咱們將對 API 進行改進和成型,以支持客戶端 lookaside 負載均衡(例如 gRPC-LB),Envoy 以外的數據平面代理,硬件 LB,移動客戶端以及其餘範圍。咱們將努力盡量與供應商和實現無關,同時堅持支持已投入生產的 UDPA 的項目(到目前爲止,Envoy 和 gRPC-LB)。網絡
對 UDPA 感興趣的同窗,能夠經過如下兩個途徑進一步深刻了解:
在展開 UDPA 的細節以前,有必要先解釋清楚 UDPA 和 xDS 的關係,由於這對理解 UDPA 會有很大幫助。
在2019年11月的 EnvoyCon 上,Envoy 的開發者,也是目前 UDPA 最主要的負責人之一,來自 Google 的 Harvey Tuch,有一個演講很是詳細而清晰的解答了這個問題,這個演講的標題是:「The Universal Dataplane API (UDPA): Envoy’s Next Generation APIs」。
備註:這裏我直接援引這份演講的部份內容,如下兩張圖片均出自 [這份演講的PPT](static.sched.com/hosted_file… UDPA 2019.pdf) 。鳴謝 Harvey。
下圖展現了近年來 xDS 協議的演進歷程和將來規劃:
簡單總結說:xDS 將逐漸向 UDPA 靠攏,將來將基於 UDPA 。
下圖則展現了 Envoy 在 xDS 版本支持上的時間線:
目前看這個計劃在執行時稍微有一點點延誤,原計劃於2019年年末推出的 v3 的 stable 版本其實是在1月中定稿的。(備註:具體可參考 Envoy PR api: freeze v3 API )。而後目前正在普遍使用的 v2 API 將被標記爲 depreated。並且在2020年末,v3 API 預計被 v4 API 取代(注意 v4 API 將會是基於 UDPA),而目前咱們最熟悉的 v2 API 將計劃在2020年末移除,再也不支持!
上圖也展現了將來 xDS 協議的大版本演進和更替的方式,總的來講規律是這樣:
所謂 「長江後浪推前浪,前浪死在沙灘上」,又或者說,「江山代有新版出,各領風騷12個月」。
備註:Envoy 具體的穩定 API 版本控制策略,能夠參見 Envoy 的設計文檔 「Stable Envoy API versioning」 ,不過這個文檔長的有點過度,嫌長的同窗能夠直接看這個文檔的縮減版本 API versioning guidelines。
言歸正傳,咱們來看一下 UDPA 目前的最新進展。從 github.com/cncf/udpa ,能夠看到目前 UDPA 中已經定義好的部分 API 內容:
目前只定義了一個類型 TypedStruct。
TypedStruct 包含任意 JSON 序列化後的 protocol buffer 消息以及一個描述序列化消息類型的URL。這與 google.protobuf.Any 很是類似,它使用 google.protobuf.Struct 做爲值,而不是使用 protocol buffer 二進制。
message TypedStruct {
// 用於惟一標識序列化 protocol buffer 消息的類型的URL
// 這與 google.protobuf.Any 中描述的語義和格式相同:
// https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto
string type_url = 1;
// 上述指定類型的JSON表示形式。
google.protobuf.Struct value = 2;
}
複製代碼
TypedStruct 定義的背景是:如何在 protocol buffer 的靜態類型報文中嵌入一個不透明的配置。這是一個廣泛需求,涉及 google.protobuf.Any 和 google.protobuf.Struct 的差異和權衡使用。具體內容請見我以前翻譯的博客文章 「[譯] 動態可擴展性和Protocol Buffer」,對此作了很是好的介紹和分析討論。
TypedStruct 能夠說是到目前爲止對此需求的最佳實踐,算是爲這一話題正式畫上了句號。
數據定義也只定義了一個數據 OrcaLoadReport。
其中 ORCA 是 Open Request Cost Aggregation 的縮寫,OrcaLoadReport 用於提交請求開銷彙總的負載報告。
ORCA 的簡短介紹:
現在,在 Envoy 中,能夠經過考慮後端負載(例如 CPU)的本地或全局知識來作出簡單的負載均衡決策。更復雜的負載均衡決策可能須要藉助特定於應用的知識,例如隊列深度,或組合多個指標。 這對於可能在多個維度上受到資源限制的服務(例如,CPU 和內存均可能成爲瓶頸,取決於所應用的負載和執行環境,沒法肯定是哪一個先觸及瓶頸)以及這些維度不在預約類別中的位置時頗有用(例如,資源多是「池中的可用線程數」,磁盤 IOPS 等)。
有關 Orca 的更詳細的信息,請見設計文檔 Open Request Cost Aggregation (ORCA) 。
目前 Envoy 正在實現對 ORCA 的支持,而後這個特性被做爲 UPDA 標準的一部分直接在 UDPA API 中定義。 如下爲 OrcaLoadReport 定義,能夠看到包含有 CPU/內存的利用率和 RPS 信息:
message OrcaLoadReport {
// CPU利用率表示爲可用CPU資源的一部分。 應該來自最新的樣本或測量。
double cpu_utilization = 1 [(validate.rules).double.gte = 0, (validate.rules).double.lte = 1];
// 內存利用率表示爲可用內存資源的一部分。 應該來自最新的樣本或測量。
double mem_utilization = 2 [(validate.rules).double.gte = 0, (validate.rules).double.lte = 1];
// 端點已服務的總RPS。 應該涵蓋端點負責的全部服務。
uint64 rps = 3;
...
}
複製代碼
服務定義依然也只定義了一個服務 OpenRcaService。
OpenRcaService 是一個帶外(Out-of-band/OOB)負載報告服務,它不在請求路徑上。OpenRcaService 按期以足夠的頻率對報告進行採樣,以提供與請求的關聯。OOB 報告彌補了帶內(in-band)報告的侷限性。
service OpenRcaService {
rpc StreamCoreMetrics(OrcaLoadReportRequest) returns (stream udpa.data.orca.v1.OrcaLoadReport);
}
複製代碼
UDPA 目前定義了四個註解(Annotation):
還有一個 ProtodocAnnotation 在提出設計後,存在分歧,暫時尚未正式加入 UDPA。這個註解的目的是標記當前還沒有實現的 UDPA 消息;
從上面列出的 UDPA API 列表能夠看到,目前 UDPA 中正式推出的 API 內容很是的少,也就:
考慮到 UDPA 推出的時間是 2019年5月份,迄今有9個月的時間,這個進展有些出乎意料。
翻了一遍 github.com/cncf/udpa 上的內容,包括全部的 commit 和 PR ,發現活躍的開發者主要是兩位同窗:Google 的 htuch 和 Tetrate公司的 Lizan。而後 cncf/UDPA 項目的 star 數量也很是低,才 55 個 star,能夠認爲社區基本上沒什麼人關注。
可是,稍後當我看到 UDPA 的設計文檔時,才發現原來 UDPA 的精華都在設計中,只是進度緣由還未能正式出成型的 API。
咱們來重點看一下 UDPA 的設計,主要的設計文檔有兩份:
UDPA 對此的解釋是:
Envoy v2 xDS API 當前正在轉向通用數據平面 API(Universal Dataplane API/UDPA)。重點是傳輸協議與數據模型的關注點分離。
關於傳輸協議與數據模型的關注點分離,一個典型的例子是「集裝箱運輸機制」(類比 UDPA-TP )和 「集裝箱中標準規格」(類比 UDPA-DM)。在 UDPA 的設計中,數據模型的定義和傳輸協議的實現是分離的,這意味着只要設計不一樣的數據模型,就能夠重用一套統一的傳輸協議。所以,UDPA 的可擴展性就變得很是強大。
對此,我我的有些驚喜,由於去年年末我和彥林同窗在商討經過 MCP/xDS/UDPA 協議融合註冊中心和控制平面時,就發現這三者的工做機制很是相似。考慮到後續可能會有各類不一樣的資源須要定義並在這個工做機制上作資源同步和分發,當時有過相似的想法,但願能把底層這套資源同步機制標準化,以便重用:
目前看來,UDPA-TP 已經在朝這個目標邁出了堅實的步伐。固然若是能再往前邁進一步就更好了:這個底層資源同步的工做機制,沒有必要限制在 UDPA 的範疇,徹底能夠變成一個用途更加普遍的通用機制。
下面來詳細看一下 UDPA-TP 和 UDPA-DM 的設計,如下內容來自 UDPA 的兩份設計文檔以及我的的解讀。
UDPA-TP 的設計文檔,在開始部分列出了 UDPA-TP 的關鍵設計動機,具體包括:
如下是 UDPA 的術語,對於後面理解 UDPA 很是有幫助:
而後是和聯邦相關的術語:
下圖能夠幫助理解這些術語:
(備註:圖中可能有誤,simple UDPA management server 和 Advanced UDPA management server 之間應該是 「UDPA-TP」, 而不該該是 「UDPA-Fed-TP」。)
UDPA-TP 傳輸協議提供了在管理服務器和 DPLB 客戶端之間傳輸命名和版本化資源的方法,咱們稱這些實體爲 UDPA-TP 端點。UDPA-TP 端點能夠是客戶端和管理服務器,也能夠是兩個管理服務器(例如,在聯邦配置時)。上圖說明了使用 UDPA 在 UDPA-TP 端點之間傳送資源的各類方式。
其中,UDPA管理服務器分爲兩種:
而對應的 DPLB 客戶端也分爲兩種:
簡單 DPLB 雖然只能鏈接一臺管理服務器,可是也是能夠實現聯邦的:簡單 DPLB 鏈接的管理服務器能夠實現聯邦,而後爲 DPLB 實現了間接聯邦(備註:上圖中的簡單 DPLB 就是例子,兩個 Advanced UDPA management server 之間作了聯邦)。
在解讀 UDPA-TP 的設計以前,咱們回顧一下 Istio 經典的組件和架構圖,下面分別是 Istio 1.0 和 Istio 1.1 的架構圖:
考慮到 Mixer 和 Citadel 兩個組件和 UDPA 的關係相比沒那麼大, 咱們重點看 Proxy / Pilot / Galley:
對照 UDPA-TP 的設計:
UDPA-TP 的設計目前應該尚未對應具體的實現產品,並且我也尚未找到 UDPA-Fed-TP 詳細的 API 設計。資料來源太少,因此只能簡單的作一些我的的初步解讀:
首先,Simple UDPA management server 的引入是一大亮點,功能足夠簡單並且專一,聚焦在將數據(在 UDPA 中體現爲資源)分發給 DPLB (如你們熟悉的數據平面)。毫無疑問,Simple UDPA management server 的重點必然會在諸如容量 / 性能 / 下發效率 / 穩定性等關鍵性能指標,彌補目前 Istio 設計中 Pilot 下發性能贏弱的短板。從這個角度說,我傾向於將 Simple UDPA management server 理解爲一個新的組件,介於 DPLB 和 Pilot 之間。 小結:解決容量和性能問題。
其次,Advanced UDPA management server 引入了聯邦的概念, 上面的圖片顯示是爲了在兩個不一樣的雲供應商(Cloud Provider X 和 Cloud Provider Y)和本地(On-premise)之間進行聯邦,這是典型的混合雲的場景。而個人理解是,聯邦不只僅用於多雲,也能夠用於多數據來源,好比打通多個不一樣的註冊中心,解決異構互通問題。 小結:解決多數據來源的全局聚合問題。
而後,比較費解的是引入了 Advanced DPLB 的概念,並且從圖上看,使用場景還很是複雜:1. 第一個 DPLB 是間接聯邦的典型場景,還比較簡單 2. 第二個 DPLB 除了以一樣的方式作了間接聯邦,還直接經過 UDPA-Fed-TP 協議和 On-Premise 的 Advanced UDPA management server 鏈接,實現了直接聯邦 3. 第三個 DPLB 則更復雜,作了三個 management server 的聯邦 。 小結:複雜的場景必然帶來複雜的機制,背後推進力待查。
對於 UDPA-TP 的設計,我我的有些不太理解,主要是對於聯邦的使用場景上,個人疑慮在於:真的有這麼複雜的場景嗎?尤爲是將聯邦的功能引入到 DPLB,這必然會使得 xDS/UDPA 協議不得不爲此提供聯邦 API 支持,而 Envoy/MOSN 等的實現難度也要大爲提高。所以,除非有特別強烈的需求和場景推進,不然最好能在複雜度和功能性之間作好平衡。
我我的更傾向於相似下面的設計:
總之,我我的更傾向於讓 DPLB 和 Simple UDPA management server 保持簡單和高性能,而將複雜功能交給 Advanced UDPA management server 。後續我會重點關注 UDPA 在聯邦功能的實現,若有新進展儘可能及時撰文分享。
在 UDPA-TP 的設計中,根據資源的來源,資源被劃分爲兩類類型:
資源在定義時,將有三個重要屬性:
如下是資源定義的實例(只是示意,暫時還沒正式成爲 UDPA API 的內容):
message Resource {
// 資源的名稱,以區別於其餘同類型的資源。
// 遵循反向DNS格式,例如 com.acme.foo/listener-a
string name = 1;
// 資源級別版本
string version = 2;
// 資源有效負載。
// 經過 Any 的 type URL 指定資源類型
google.protobuf.Any resource = 3;
// 資源的TTL。
// 此時間段後,資源將在DPLB上失效。
// 當管理服務器的鏈接丟失時,將支持資源的優雅降級,例如端點分配。
// 使用新的TTL接收到相同的資源 name/version/type 將不會致使除了刷新TTL以外的任何狀態更改。
// 按需資源可能被容許過時,而且可能在TTL過時時被從新獲取。
// TTL刷新消息中的resource字段可能爲空,name/version/type用於標識要刷新的資源。
google.protobuf.Duration ttl = 4;
// 資源的出處(全部權,來源和完整性)。
Provenance origin_info = 5;
}
複製代碼
UDPA-TP 設計中的其餘內容,如安全 / 錯誤處理 / 傳輸 / 用戶故事 等,就不一一展開了,這些設計目前看離正式成爲 API 還有點遠。若有興趣能夠直接翻閱 UDPA-TP 的設計文檔。
UDPA 設計的一個核心內容就是將傳輸(TransPort)與數據模型(Date Model)的關注點分離,前面介紹了 UDPA-TP 的設計,能夠說目前還在進行中,並未徹底定型。
而 UDPA-DM 的設計,感受進度上比 UDPA-TP 還要更早期,這多少有點出乎意料:原覺得 UDPA 會基於 xDS 現有的成熟 API 定義,快速推出一套覆蓋常見通用功能的 API ,甚至直接把 xDS 中的部份內容清理乾淨以後搬過來。但事實是:目前 UDPA-DM 中已經定義的 API 內容很是少,僅有 L7 Routing ,並且還在設計中,其餘你們熟悉的 Listener / Cluster / Endpoint / Security / RatingLimit 等API都尚未看到。
而 UDPA-DM 的設計和實現方式,也由於資料較少而有些不夠明朗。在 UDPA-DM 的設計文檔的開頭,有以下一段描述:
As a starting point, we recognize that the UDPA-DM is not required to be as expressive as any given DPLB client’s full set of capabilities, instead it should be possible to translate from UDPA-DM to various DPLB native configuration formats. We envisage UDPA-DM as a lingua franca that captures a large amount of useful functionality that a DPLB may provide, making it possible to build common control planes and ecosystems around UDPA capable DPLBs. 首先,咱們認識到 UDPA-DM 不須要像任何已有的 DPLB 客戶端那樣,所有能力都具有表現力,而是應該能夠從 UDPA-DM 轉換爲各類 DPLB 原生配置格式。咱們將 UDPA-DM 設想爲一種通用語言,它具有大量 DPLB 應該提供的有用的功能,從而有可能在支持 UDPA 的 DPLB 周圍構建通用的控制平面和生態系統。 The UDPA-DM will be a living standard. We anticipate that it will initially cover some obvious common capabilities shared by DPLBs, while leaving other behaviors to proxy specific API fields. Over time, we expect that the UDPA-DM will evolves via a stable API versioning policy to accommodate functionalities as we negotiate a common representation. UDPA-DM 將成爲事實標準。咱們指望它最初將涵蓋 DPLB 共有的一些顯而易見的通用功能,同時將其餘行爲留給代理特定的API字段。隨着時間的推移,咱們指望 UDPA-DM 將經過穩定的API版本控制策略來發展,以容納各類功能,而咱們將協商通用的表示形式。
對這兩段文字描述的理解,我是有一些困惑的,主要在清楚解 UDPA-DM 的定義和具體的 DPLB 原生實現(典型如 Envoy 的 xDS)之間的關係。下面這張圖是我畫的:
前面談到 xDS 的演進路線, v3 / v4 會逐漸向 UDPA 靠攏,尤爲 v4 會基於 UDPA 來。目前因爲 UDPA API 遠未成型,而 xDS v3 中對 UDPA API 的使用很是少(基本只用到了 annotation 定義),所以目前究竟是哪一個方案尚不明朗。
如下是 UDPA-DM 設計文檔中描述的 UDPA-DM 的關鍵設計:
下面重點看 L7 Routing 的設計。
Routing API 中有三個術語:
在 UDPA-DM 的 Routing API 設計中,針對請求匹配的方式,相比 xDS 作了重大的改動,主要體如今除了線性匹配以外,還支持分層匹配。
這裏先解釋一下線性匹配和分層匹配這兩種路由時須要用到的請求匹配方式:
目前 xDS v2 API 使用的是線性匹配方式,而 UDPA-DM 的 Routing API 會引入分層匹配,造成線性-分層的混合匹配方式,以下圖所示:
設計文檔對這個混合匹配模型有以下說明:
The model does not map directly to any given DPLB today but borrows from some Envoy concepts and should have an efficient realization. It may be possible to use HAproxy ACLs to model this topology. 目前該模型並無直接映射到任何給定的 DPLB,而是借鑑了 Envoy 的一些概念,這個模型應該會有一個有效的實現。可能會使用 HAproxy ACL 對這種拓撲進行建模。
因爲目前 Routing API 並無完成設計,也沒有正式成爲 UDPA 的 API,而在最新剛定稿的 xDS v3 協議中,RoutesDiscoveryService 和 ScopedRoutesDiscoveryService 也都沒有引入這個新的模型,所以預期這個模型將在2020年繼續完成設計和定稿,可能在年末的 xDS v4 中會有所體現。而後,UDPA-DM 和 xDS 之間到底會是轉換模型,仍是子集模型,屆時就清楚了。
因爲 Routing API 還沒有設計完成,因此這裏不詳細展開 Routing API 的定義了。Routing API 的相關資料以下,有興趣的同窗能夠關注(然而已經很長時間沒有新的進展了):
UDPA 目前還處於早期設計階段,關鍵的 UDPA-TP 和 UDPA-DM 的設計有推出草稿可是遠未完成,內容也和咱們指望的一個完整的通用數據平面 API 有很長的距離。並且項目進展並不理想,感受重視程度和人力投入都有限。
最近由於想了解一下 UDPA 的進展,因此作了 UDPA 的調研和學習,比較遺憾的是 UDPA 的資料很是匱乏,除了我本文列出來的幾個官方網站和設計文檔以外,基本就只有 Harvey 的演講。
調研完成以後發現 UDPA 的進展不如人意,尤爲是最近的工做幾乎停滯,關鍵的 UDPA-TP 和 UDPA-DM 的設計未能完稿,xDS v3 中也只引用了極少的 UDPA API 定義。這篇總結文章差點所以難產,由於未知/待定/未完成的內容太多,並且因爲缺少資料輸入,不少信息也只是我我的的理解和想法,按說這不是一個嚴謹的深度介紹文章應有的態度。
但考慮到目前 UDPA 的資料實在是太少,本着「有比沒有好」的想法,我硬着頭皮完成了這篇文章。後續若是有新的輸入,我會及時完善或者修訂本文,也歡迎對 UDPA 有興趣和了解的同窗聯繫我討論和指導。
公衆號:金融級分佈式架構(Antfin_SOFA)