在我的控制面中如何同时支持多个 xDS API 的主版本?

如果可能的话,为了简单起见,强烈建议控制面在给定的时间点只支持单个主版本。这种情况适用于让控制面仅需支持 Envoy 的一个窗口期,而这窗口期一般小于一年。关于滚动更新期间临时支持多个版本的方案在 这里 <control_plane_version_support> 有所描述。

对于需要支持更广泛版本的控制面来说,可以采用如下几种方式:

  1. 独立的 vN/v(N+1) 配置生成流水线。这很容易理解但却涉及到大量的代码重复且在工程方面成本高昂。如果使用的 API 接口比较少,这种情况下效果会不错。

  2. 让控制面规范地使用 vN,然后机械地即将 vN 消息转换为与其同等的 v(N+1)。这对使用任何新 v(N+1) 特性的情况来讲是不被允许的。避免使用任何已经弃用的 vN 字段是非常有必要的。如果暂时忽略这些警告的话,一个简单的转换就是将 vN proto 消息进行序列化,然后反序列化成 v(N+1) proto 消息(这需要保证二进制的兼容性)。当在 DiscoveryResponse 中使用 google.protobuf.Any 资源时,一种优化方案就是简单的重新类型 URL。

  3. 当使用仅支持 vN 的 Envoy 时,让控制面规范地使用 v(N+1) 然后机械地将其转换为与其同等的 vN。当为配置流水线提供输入时(例如,如果请求了一个新的正则表达式类型,但在 vN 版本的 Envoy 中默默地忽略了 RouteMatch ,这就会有问题),从操作员的角度来讲,如果忽略那些仅存在于 v(N+1) 中字段的安全性时,这种方法是行之有效的。和上述第二种情况类似,通过序列化和反序列化,v(N+1) 消息或许被转换为与 vN 等同的消息。如果目标是支持范围最广的 vN 客户端,有必须使用手写代码来将那些同时存在于 vN/v(N+1) 中的字段转换为 vN 中弃用的同等部分,因为版本较早的 vN Envoy 客户端中并没有 vN 和 v(N+1) 所共有的一些较新字段。