UDPA 介绍
-
UDPA :“Universal Data Plane API”的缩写, “通用数据平面 API”; -
UDPA-WG:”Universal Data Plane API Working Group”的缩写,这是 CNCF 下的一个工作组,负责制定 UDPA;
通用数据平面 API 工作组(UDPA-WG)的目标是召集对数据平面代理和负载均衡器的通用控制和配置 API 感兴趣的业界人士。
通用数据平面 API(UDPA)的愿景在 https://blog.envoyproxy.io/the-universal-data-plane-api-d15cec7a 中阐明。我们将寻求一组 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 @ GitHub:UDPA 在 github 上的项目,UDPA API 定义的代码都在这里; -
Universal Data Plane API Working Group (UDPA-WG):CNCF 的 UDPA 工作组,可以通过加入工作组的方式了解更多信息;
UDPA 和 xDS 的关系
备注:这里我直接援引这份演讲的部分内容,以下两张图片均出自 这份演讲的PPT ,鸣谢 Harvey。

-
2017年,xDS v2 引入 proto3 和 gRPC,同年 Istio 项目启动; -
2018和2019年,xDS v2 API 继续发展,陆续引入了新的 API 定义,如 HDS / LRS / SDS 等,尤其是为了改进 Pilot 下发性能,开始引入增量推送机制; -
xDS v3 API 原计划于2019年年底推出,但目前看技术推迟,目前 v3 还是 alpha1 状态,预计在即将发布的 Istio 1.5 中会有更多的 v3 API 引入。同时 v3 API 也引入了 UDPA 的部分内容,但是由于 UDPA 目前进展缓慢,对 xDS 的影响并不大,主要还是 xDS 自身的发展,比如对 API 和技术债务的清理; -
但在2020年,预计 UDPA 会有很大的进展,尤其是下面我们将会展开的 UDPA-TP 和 UDPA-DM 的设计开始正式制定为 API 之后。而 xDS v4 预计将基于 UDPA ,因此 xDS v4 可能会迎来比较大的变动;

一年一个大版本:2019 v2 -> 2020 v3 -> 2021 v4 ->2022 v5;
每个大版本都要经历 alpha -> stable -> deprecated -> removed 四个阶段,每个阶段历时一年;
稳定后 Envoy 会同时存在三个 API 大版本:正在使用的稳定版本,已经弃用的上一个稳定版本,准备开发的新的下一个大版本(但只会是Alpha);
发布一个新的 stable 的大版本,就一定会 deprecated 上一个稳定的大版本,同时 remove 更前一个已经 deprecated 的大版本;
备注:Envoy 具体的稳定 API 版本控制策略,可以参见 Envoy 的设计文档 “Stable Envoy API versioning” ,不过这个文档长的有点过分,嫌长的同学可以直接看这个文档的缩减版本 API versioning guidelines。
UDPA API 进展
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;
}
其中 ORCA 是 Open Request Cost Aggregation 的缩写,OrcaLoadReport 用于提交请求开销汇总的负载报告。
ORCA 的简短介绍:
如今,在 Envoy 中,可以通过考虑后端负载(例如 CPU)的本地或全局知识来做出简单的负载均衡决策。更复杂的负载均衡决策可能需要借助特定于应用的知识,例如队列深度,或组合多个指标。这对于可能在多个维度上受到资源限制的服务(例如,CPU 和内存都可能成为瓶颈,取决于所应用的负载和执行环境,无法确定是哪个先触及瓶颈)以及这些维度不在预定类别中的位置时很有用(例如,资源可能是“池中的可用线程数”,磁盘 IOPS 等)。
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;
...
}
service OpenRcaService {
rpc StreamCoreMetrics(OrcaLoadReportRequest) returns (stream udpa.data.orca.v1.OrcaLoadReport);
}
注解定义
-
MigrateAnnotation:用于标记在前后版本中的和迁移相关的 API 变更,包括 rename / oneofpromotion / moveto_package 等多种语义; -
SensitiveAnnotation:将某个字段标记为“敏感”字段,例如个人身份信息,密码或私钥; -
StatusAnnotation:标记状态,比如将某个文件标记为“workinprogress/进行中”; -
VersioningAnnotation:用于记录版本信息,比如通过 previousmessagetype 表示当前 message 在上一个版本中的类型;
-
一个 TypedStruct 类型定义; -
一个 OpenRcaService 服务定义和配套的 OracLoadReport 数据定义; -
4个注解;
UDPA 设计
-
UDPA-TP strawman: UDPA 设计之传输协议(TransPort),是用于 UDPA 的下一代传输协议; -
UDPA-DM: L7 routing strawman: UDPA 设计之数据模型(Data Model),是对通过 UDPA-TP 传输的资源定义;
Envoy v2 xDS API 当前正在转向通用数据平面 API(Universal Dataplane API/UDPA)。重点是传输协议与数据模型的关注点分离。

-
在保留 Core v2 xDS 中存在的概念性 pub-sub 模型的同时,还支持高级功能,例如 LRS/HDS; -
支持 Envoy Mobile 和其他 DPLB 客户端的大规模扩展; -
简单的客户端和简单的管理服务器实现; -
使增量更新资源高效而简单(备注:增量更新是目前 Istio/Envoy 正在努力实现的重点特性); -
支持资源联邦(备注:和我之前构想的通过 MCP 协议聚合多个注册中心/配置中心的思路一致,当现实中存在多个资源的来源时,就必须提供机制来聚合这些资源并提供一个全局的视图); -
使 API 资源的子资源变得简单且实现成本低,并且使其可以增量更新和可联合; -
维护对一致性模型的支持; -
消除 v2 xDS 奇怪之处; -
ACK/NACK 与订阅消息的合并。在 v2 xDS 中,DiscoveryRequest 既是订阅请求,又是对先前消息的潜在确认。这导致了一些复杂的实现和调试体验(备注:这会造成 UDPA 交互模式和 xDS 的不同); -
CDS/LDS 是与 EDS/RDS 不同的 API 层。在 v2 xDS 中,EDS/RDS 是准增量的,而 CDS/LDS 是最新状态; -
从概念上讲,在 Envoy v2 xDS API 基础上小范围变更。我们不希望对 UDPA 管理服务器实现者造成重大的概念和实现开销(备注:个人理解,这应该是目前 UDPA 没有大张旗鼓的制定各种 API 的原因,UDPA 和 xDS,包括和 xDS 的实际实现者 Envoy 的关系过于紧密,因此需要考虑从 xDS 到 UDPA 的过渡,不能简单的推出一套全新的 API);
-
DPLB:data plane load balancer 的缩写。涵盖诸如代理(例如 Envoy)或客户端 RPC 库(例如 gRPC 和 Envoy Mobile)的用例。DPLB 是 UDPA 客户端。他们负责启动到管理服务器的 UDPA 流(备注:注意,DPLB 不仅仅包含以 Envoy 为代表的 service mesh sidecar,也包括了以 SDK 形式存在的类库如 gRPC,而 gRPC 目前已经在实现对 xDS 接口的支持); -
Management server/管理服务器:能够提供 UDPA 服务的实体,管理服务器可以仅是 UDPA 服务器,也可以是 UDPA 客户端和服务器(在联邦的情况下); -
UDPA:通用数据平面 API,其中包括数据模型(UDPA-DM)和传输协议(UDPA-TP); -
UDPA-TP:UDPA API 的基准传输协议; -
UDPA-DM:UDPA API 的数据模型; -
UaaS:UDPA-as-a-service,云托管的 UDPA 管理服务(备注:Google 在 GCP 上提供的 Google Traffic Director 和 AWS 提供的 App Mesh,可以视为就是 UaaS 雏形);
-
Federation/联邦:多个 UDPA 管理服务器的互操作以生成 UDPA 配置资源; -
Direct federation/直接联邦:当 DPLB 直接连接到多个 UDPA 管理服务器并能够从这些流中合成其配置资源时; -
Indirect federation/间接联邦:当 DPLB 一次最多连接一个 UDPA 管理服务器(对于某些给定的资源类型),并且 UDPA 管理服务器执行所有与联邦有关的工作时; -
Advanced DPLB/高级 DPLB:支持直接联邦的 DPLB(需要 UDPA-Fed-TP); -
Simple DPLB/简单 DPLB:不支持直接联邦的 DPLB,即仅基线 UDPA-TP; -
UDPA-Fed-DM:UDPA-DM 的超集,具有用于联邦的其他资源类型; -
UDPA-Fed-TP:支持联邦的 UDPA-TP 的超集;

-
简单(simple):实际上只是对不透明资源的缓存(几乎不了解 UDPA-DM),主要功能是从上游高级 UDPA 管理服务器获取资源,并分发资源给 DPLB,自身不产生资源; -
高级(advanced):对 UDPA-DM 有感知,通常是用来获取信息并转换为标准化的资源(典型如 Istio 中的 Pilot)。可以直接分发资源给到 DPLB,也可以发送资源给简单 UDPA 管理服务器,然后由简单 UDPA 管理服务器再分发给 DPLB;
-
简单(simple):对于任何配置源,简单的 DPLB 在任何时间点最多只能与一台管理服务器进行对话; -
高级(advanced):将实现对 UDPA-Fed-TP 的支持,并能够直接作为联邦端点参与;

-
Proxy在 Istio 中就是 Envoy(我们的 MOSN 正在努力成为候选方案),直接对等 UDPA 中的 DPLB 的概念。但是 Istio 中的 Proxy,功能上只和上图中的 Simple DPLB 对齐。相比之下,UDPA-TP 设计中增加了一个能够连接多个 UDPA management server 进行联邦的 Advanced DPLB; -
Pilot 和 Galley,从和 DPLB 的连接关系看,分别对应着 UDPA-TP 设计中的 Simple UDPA management server 和 Advanced UDPA management server。但从实际实现的功能看,目前 Pilot 的职责远远超过了 Simple UDPA management server 的设计,而 Galley 的功能则远远少于 Advanced UDPA management server。如果未来 Istio 的架构和组件要向 UDPA 的设计靠拢,则显然 Pilot 和 Galley 的职责要发生巨大调整; -
最大的差异还是在于 UDPA-TP 中引入了联邦的概念,而且同时支持在 DPLB 和 Advanced UDPA management server 上做联邦。尤其是 DPLB 要实现联邦功能,则必然会让 DPLB 的功能大为增加,相应的 DPLB 和 UDPA management server 的通讯协议 (目前是 xDS)也将为联邦的实现增加大量内容;

-
首先,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 的联邦 。 小结:复杂的场景必然带来复杂的机制,背后推动力待查。

-
维持 DPLB 和 Simple UDPA management server 的简单性; -
DPLB 只对接 Simple UDPA management server,协议固定为 UDPA-TP,联邦对 DPLB 透明(只实现间接联邦); -
Simple UDPA management server 重点在于容量和性能的提升,包括目前正在进行中的支持各种资源的增量更新; -
Advanced UDPA management server 负责完成联邦,包括和其他环境的 Advanced UDPA management server 做联邦,以及从本地的其他注册中心聚合数据;
-
Configuration Resources/配置资源:控制平面生成,由管理服务器分发到 DPLB。平常大家熟悉的,通过 xDS 协议传输的 Listener / Route / Cluster / Endpoint 等资源就属于这种类型; -
Client Resources/客户资源:DPLB 生成,准备交给控制平面使用。前面 UDPA 中定义的 OracLoadReport 就是典型例子,这是最近才有的新特性,由 DPLB 收集统计信息和状态,汇报给到控制平面,以便控制平面在决策时可以有多完善的参考信息;
-
名称/Name:对于给定类型是唯一的,而且资源名称是结构化的,其路径层次结构如下:/ ,例如 com.acme.foo/service-a 。注意 namespace 的引入,是后面的资源联邦和所有权委派的基础; -
类型/Type:资源类型由 Type URL 提供的字符串来表示; -
版本/Version:对于给定的命名资源,它可能在不同的时间点具有不同的版本。在资源定义中带上版本之后,检测资源是否有更新就非常方便了;
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;
}
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 是做通用定义,然后转换(Translate)为各种 DPLB 的原生配置格式。这意味着 UDPA-DM API 和实际的 DPLB 原生配置格式可能会有非常大的不同,甚至有可能是完全不一样的格式定义。这个关系有点类似 Istio API 和 xDS API 的关系,也类似于 SMI (微软推出的 Service Mesh Interface)和 xDS 的关系; -
右边的图是子集方案:按照第二段文字的描述,UDPA-DM 是做通用定义,但是不会做转换,其他 DPLB 会直接复用这些 UDPA-DM 的 API 定义,然后补充自身特有的 API 定义。这样 UDPA-DM 会以通用子集的形式出现,逐渐扩大范围,然后其他 API 会逐渐将自身的 API 中和 UDPA-DM 重叠的部分替换为 UDPA-DM API,只保留自身特有的扩展 API;
-
描述 L7 路由层,该层描述主要 L7 DPLB 之间的常见行为,包括 Envoy,HAproxy,Nginx,Google Cloud Platform URL mapping 和 Linkerd; -
为代理 /LB 的特有扩展提供灵活性,用于不适合通用抽象的行为。即逃生舱口(escape hatch)(备注:类似 SQL 方言); -
提供 L7 路由表的可伸缩性和有效的对数评估(logarithmic evaluation)。例如,Envoy v2 xDS 是严格线性评估的路由表,具有明显的扩展限制。对于可以支持 UDPA-TP 这个特性的 DPLB,应该可以按需获取路由表段; -
在 v2 Envoy xDS API 中支持线性匹配路由表的旧有用户; -
删除多 xDS 样式 API 的需求,例如 RDS,VHDS 和 SRDS; -
资源的可组合性;应该有可能支持 UDPA 联邦用例,带有诸如虚拟主机这种被独立管理的资源等;
-
服务/Service:描述后端服务的不透明字符串(或在 Envoy 的术语中,为集群/Cluster)。当前文档未提供有关服务表示的任何进一步详细说明,这留待以后的工作; -
路由表/Route table:一组匹配条件,用于 HTTP 请求和相关操作。操作可以包括重定向或转发到特定服务; -
L7 路由/L7 routing:根据路由表评估给定的 HTTP 请求;
-
线性(Linear):其中路由表类似于[([Match], Action)] 类型。在此模型中,路由表是匹配 criteria-action 条件的有序列表。每个匹配的 criteria 是匹配 criteria 的逻辑”与”,例如: -
If :authority == foo.com AND path == / AND x-foo == bar THEN route to X -
If :authority == bar.com AND x-baz == wh00t THEN route to Y -
分层(Hierarchical):其中路由表类似于树结构,每个节点具有(MatchCriteria, [(Value, Action)]) 类型。通过这种结构,任何给定的节点都会只评估单个匹配条件,例如:authority 的值。分层匹配能提供相对高效的实现。

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 对这种拓扑进行建模。
-
Issue 讨论 [WiP] L7 routing straw man; -
在 PR 中提交的 Routing API 定义文件 udpa/config/v1alpha/routing.proto:可以自行和 xDS v3 的 API 做一个比较;
总结
附言
参考资料
https://github.com/cncf/udpa :UDPA 在 github 的项目,API 定义来自这里
Universal Data Plane API Working Group (UDPA-WG): UDPA 设计文档,但是内容很少
Universal Data Plane API Working Group (UDPA-WG):CNCF 下的 UDPA 工作组,加入之后能看到一些资料
UDPA-TP strawman: UDPA-TP 的设计文档
UDPA-DM: L7 routing strawman: UDPA-DM 的设计文档
Stable Envoy API versioning :Envoy 官方文档,讲述 Envoy 的稳定API版本控制策略
CNCF 正在筹建通用数据平面 API 工作组,以制定数据平面的标准 API:我去年写的 UDPA 介绍文章
The Universal Dataplane API (UDPA): Envoy’s Next Generation APIs:Harvey Tuch 的演讲,帮助理解 xDS 和 UDPA 的关系
🎉奖励支持 SOFAStack 的你~
* 点下右下角“在看”
* 到公众号对话框发送“电脑包”,试试手气~
* 本期互动奖品“蚂蚁定制电脑内胆包”
本文分享自微信公众号 - 金融级分布式架构(Antfin_SOFA)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。