写点什么

深度剖析 Istio 共享代理新模式 Ambient Mesh

  • 2022 年 9 月 24 日
    中国香港
  • 本文字数:5056 字

    阅读完需:约 17 分钟

本文分享自华为云社区《深度剖析!Istio共享代理新模式Ambient Mesh》,作者:华为云云原生团队。


作者:华为云云原生团队 | GitHub ID:@hzxuzhonghu @zirain


今年 9 月份,Istio 社区宣布 Ambient Mesh 开源,由此引发国内外众多开发者的热烈讨论。实际上,通过与 Istio TOC 成员 linsun(https://github.com/linsun)的交流,我们得知早在 2021 年,Solo.io 已经开始共享代理的研究和设计,同样也是在 2021 年 Google 内部也在探索共享代理模式。因此,两家公司一拍即合,今年 4~5 月份开始以协作开发的方式,加速共享代理模式的发展。


目前 Ambient Mesh 已经发布预览版本,感兴趣的读者可以按需体验。由于篇幅限制,本文主要针对 Ambient Mesh 架构及四层流量治理的流程进行深度剖析,关于七层流量治理的详解,请关注后续文章。

1. Ambient Mesh 是什么


简单来讲,Ambient Mesh 是 Istio 服务网格的一种共享代理的新模式。它是由 Google 和 Solo.io 联合开发的一种新的数据面模式,旨在简化操作、提升应用兼容性并降低基础设施成本。Ambient 模式可在放弃引入 Sidecar 的情况下,保持 Istio 的零信任安全、流量管理和遥测等核心功能。

2. Ambient Mesh 架构分析


开始 Ambient 的架构之前,我们先简单回顾一下 Istio 的架构。其主要由两部分组成,分别是控制面和数据面。控制面 Istiod 进行基本的配置生成和推送,管理着所有的数据面;数据面引入 Sidecar 代理,接管应用的入口和出口流量。


图 1 Istio 架构


相比 Sidecar,Ambient Mesh 提供一种侵入性更低,升级管理更简单的选择。Ambient 将 Istio 的功能分成两个不同的层次,安全覆盖层(四层治理)和 七层 处理层(七层治理):


图 2 Ambient mesh 分 a 层


• 安全覆盖层:处理 TCP 路由、监控指标、访问日志,mTLS 隧道,简单的授权

• 七层处理层:除安全覆盖层的功能外,提供 HTTP 协议的路由、监控、访问日志、调用链、负载均衡、熔断、限流、重试等流量管理功能以及丰富的七层授权策略


Ambient Mesh 下的负载可与 Sidecar 模式下的负载无缝互通,允许用户根据自己的需要来混合搭配使用两种模式。


• 四层治理架构


在 Sidecar 模式下,Istio 通过 InitContainer 或 Istio-CNI 实现流量拦截。Ambient Mesh 下 Istio-CNI 是必选组件,下图展示了基本的 Ambient Mesh 四层治理架构:


图 3 Ambient mesh 四层治理架构


Istio-CNI 中,新增 Ambient 的处理模块 ,该模块会监听 Namespace 以及 Pod 的变化,为所在节点的应用设置路由和 iptables 规则:


• 路由:设置路由表,将本节点应用发出的流量路由到 ztunnel,以及将本节点接收的流量路由到 ztunnel。

• iptables:在 ztunnel 容器中设置 iptables 规则,将流量透明拦截至 ztunnel 对应的端口上。


ztunnel 是 Ambient 新引入的组件,以 Daemonset 的方式部署在每个节点上。ztunnel 为网格中的应用通信提供 mTLS、遥测、身份验证和 L4 授权功能,不执行任何七层协议相关的处理。只有当 ztunnel 运行在工作负载相同的节点上时,控制面才会将工作负载证书颁发给该 ztunnel。因此 当 ztunnel 被攻击时,只有运行在该节点上的负载的证书可能被盗用,安全风险相对可控,这和其他实现良好的节点共享基础设施类似。


• 七层流量治理架构


目前 Ambient Mesh 需要通过定义一个 Gateway API 资源显式对某个服务启用七层处理。下图展示了 Ambient 七层治理的架构:


图 4 Ambient mesh 七层治理架构


与 Ambient 四层治理相比,七层治理架构中新增了 waypoint 组件。Pilot 中新增了 waypoint 的处理模块 , 它监听 ServiceAccount、Deployment、Gateway API 对象的变化,然后调协相关的 waypoint 对象:


• ServiceAccount 发生变化时,Pilot 会尝试更新当前命名空间下所有的 waypoint

• Deployment 发生变化时,通过其 OwnerReference 关联的 Gateway 对象,触发 waypoint 的维护

• Gateway 发生变化时,更新关联的 waypoint 代理


当前 Ambient 创建 waypoint 代理需要依赖类似下面的 Gateway API 资源:


apiVersion: gateway.networking.k8s.io/v1alpha2kind: Gatewaymetadata:  name: productpage  annotations:    istio.io/service-account: bookinfo-productpagespec:  gatewayClassName: istio-mesh
复制代码


gatewayClassName 值必须设置为 istio-mesh,否则可能会被忽略。每个 ServiceAccount 都有自己专用的 waypoint 代理,这点与 Sidecar 模型非常相似。建议每个服务使用自己单独的身份,避免带来额外的安全风险。


Pilot 会将 七层七层 流量规则通过 xDS 更新至 waypoint 代理,实现 七层 相关流量治理能力。waypoint 代理不一定保证与其所服务的工作负载位于同一节点,这似乎会带来一定的性能问题。但是对于 Istio 来说,延迟更多来自于复杂的 七层 处理,预计最终 Ambient 模式的七层治理延迟与 Sidecar 模式接近。waypoint 代理通过单独 Deployment 部署,因此可为其单独配置所需要的 CPU、内存,设置相关 的 HPA 弹性伸缩策略,不再与应用耦合,提供更加灵活的扩展性并可以在一定程度上提升资源的使用率。

3. Ambient Mesh 四层流量治理


我们知道 ztunnel 只能进行四层的流量治理,四层负载均衡以及 TLS 流量加密、基本的认证和鉴权等,而不能进行更高级的七层路由和认证鉴权。这里我们通过 sleep 应用访问 bookinfo 的例子,深入理解 Ambient Mesh 的四层流量是如何路由的。本例子的实际环境背景如下,sleep 和 productpage 应用分别运行在两个不同的节点。


图 5 Ambient mesh 四层流量代理流程


• 在 sleep 容器内访问 productpage 服务,首先请求被拦截到同节点的 ztunnel 中,ztunnel 做基本的四层负载均衡和 TLS 加解密,最后选择一个目标实例(productpage 容器的 IP)将本次请求转发出去。

• 本次请求进入 productpage 容器所在的节点,首先被拦截到 ztunnel, ztunnel 负责 TLS 流量的解密,然后执行用户指定的鉴权策略,最后将请求发往 productpage 容器。


以上就是 Ambient mesh 流量转发的一个基本流程,下面我们结合具体的 xDS 配置深入理解完整的通信流程。

3.1 sleep 发送侧流量处理


(1) sleep 访问 productpage 的流量被同节点的 tunnel 以 TPROXY(透明代理)方式拦截转发到 ztunnel(监听 127.0.0.1:15001),使用 TPROXY 的好处是保留原始的目的地址,ztunnel 做转发时必须依赖原始目的地址。


-A PREROUTING -i pistioout -p tcp -j TPROXY --on-port 15001 --on-ip 127.0.0.1 --tproxy-mark 0x400/0xfff
复制代码


(2) ztunnel 通过"ztunnel_outbound"监听器,监听在 15001 端口。ztunnel_outbound 监听器与 Istio Sidecar 模式的监听器完全不同,它包含所有本节点上的服务到整个网格其他服务的过滤器链。



图 6 ztunnel_outbound 监听器


可以看到所有的过滤器链都没有设置匹配条件(默认全部匹配),那么这时 ztunnel 怎么根据流量特征选择目标过滤器链的呢?原来在监听器根上还有一种设置过滤器匹配条件的方式,通过下面匹配到源地址为 10.244.1.4,目的地址为 10.96.179.71,目的端口为 9080 的流量,交由"spiffe://cluster.local/ns/default/sa/sleep_to_http_productpage.default.svc.cluster.local_outbound_internal"过滤器处理,


图 7 ztunnel_outbound 过滤器链匹配


(3)"spiffe://cluster.local/ns/default/sa/sleep_to_http_productpage.default.svc.cluster.local_outbound_internal"过滤器关联到同名的 Cluster。该 Cluster 一共包含两个 Endpoint 实例,根据负载均衡算法选择某一个 Endpoint,并且最重要的是将 metadata(tunnel 的 destination 和 address)传递给名为"outbound_tunnel_lis_spiffe://cluster.local/ns/default/sa/bookinfo-productpage" 的监听器处理。


图 8 outbound_internal 内部 Cluster 配置

图 9 outbound_internal 内部 Cluster Endpoint


(4) “outbound_tunnel_lis_spiffe://cluster.local/ns/default/sa/sleep”监听器通过“set_dst_address”过滤器根据上一步的选择的 Endpoint 的 metadata 设置数据的目的地址。假如前面 outbound_internal Cluster 选择的是 10.244.2.8:9080 这个 Endpoint,那么这里的 tunnel 监听器将把 10.244.2.8:15008 设置为目的地址。另外该监听器,只有一个 TcpProxy,关联到名为“outbound_tunnel_clus_spiffe://cluster.local/ns/default/sa/ sleep”的 Cluster,那么流量自然交由该 Cluster 处理。TCP 过滤器上还设置了 HTTP Connect 隧道(承载发送到 10.244.2.8:9080 的流量),供后面 productpage 所在节点的 ztunnel 使用。HTTP 隧道是 Ambient Mesh 组件之间安全通信的承载协议。


图 10 outbound_tunnel 监听器配置


outbound_tunnel Cluster 的类型为“ORIGINAL_DST”,并且配置有 UpstreamTlsContext, 因此它负责流量 TLS 加密,然后直接发送到目的地址,即 10.244.2.8:15008。


图 11 outbound_tunnel cluster 配置

3.2 productpage 接收侧流量处理


(1) sleep 访问 productpage 的流量(目的地址是“10.244.2.8:15008”)到达 productpage 所在的节点,以 TPROXY(透明代理)方式被拦截到 ztunnel(监听 127.0.0.1:15008),使用 TPROXY 的好处是保留原始的目的地址,ztunnel 做转发时必须依赖原始目的地址。


10.244.2.8 via 192.168.126.2 dev istioin table 100 src 10.244.2.1
-A PREROUTING -i pistioin -p tcp -m tcp --dport 15008 -j TPROXY --on-port 15008 --on-ip 127.0.0.1 --tproxy-mark 0x400/0xfff
复制代码


(2) ztunnel 上面“ztunnel_inbound”监听器监听在 15008 端口,因此流量首先经过 ztunnel_inbound 监听器的处理。ztunnel_inbound 监听器上面设置了 TLS,根据其配置与下游进行 TLS 握手,从而所有的 ztunnel 之间基于双向 TLS 加密通信。另外,从下面配置中可以看到,CONNECT 升级已经设置,那么 Envoy 就会代理 HTTP 的 Connect 请求。除此之外,RouteMatch 中设置了 connectMatcher,意味着将 HTTP Connect 请求交由“virtual_inbound”Cluster 处理。


图 12 ztunnel_inbound 监听器配置


(3) virtual_inbound Cluster 类型为 ORIGINAL_DST,并且设置使用 x-envoy-original-dst-host HTTP Header 重写原始目的地址,而此 Header 恰恰由发送侧的“outbound_tunnel_lis_spiffe://cluster.local/ns/default/sa/sleep”监听器设置,值为 10.244.2.8:9080。因此本次请求通过 virtual_inbound 最终成功发送给 productpage 容器。


图 13 virtual_inbound cluster 配置

3.3 Ambient Mesh 四层流量治理小结


图 14 完整的服务访问四层代理


sleep 访问 productpage 的实例中,虽然我们使用的是 HTTP 协议,但是从 Ambient 所有的组件视角来看,其代理的为 TCP 流量。前面我们深入分析了 ztunnel 中每一个监听器、每一个 Cluster 的工作原理,看起来可能会很复杂。故在此通过图 14 进行一个概要的总结,我们发现在通信的过程中,实际参加工作的模块并不多:


1. 发送侧的路由、iptables:将流量拦截到 ztunnel 的 15001 端口

2. 发送侧 ztunnel:两个监听器和对应的两个 cluster

3. 接收侧的路由、iptables:将流量拦截到 ztunnel 的 15008 端口

4. 接收 ztunnel:virtual_inbound 监听器及关联的 cluster

4. 未来展望


Sidecar 是 Istio 的特色,利用 Sidecar,对应用进行非常小的修改就可以享受服务网格带来的好处,减少运维负担;但是 Sidecar 模式也有一些限制:


1. 侵入性:Sidecar 容器是以 Admission Webhook 的方式来注入,与应用容器属于同一个 Pod,因此 Sidecar 的升级,必须伴随着业务容器的重建。对应用负载来可能是破坏性的(例如:长连接场景下滚动升级可能造成浪涌)。


2. 资源利用率低:Sidecar 与应用一一对应,且必须预留足够的 CPU 和内存,可能导致整个集群资源利用率偏低;弹性扩缩容只能针对整个工作负载进行,无法单独对 Sidecar 进行。


3. 流量中断:流量的捕获和 HTTP 处理由 Sidecar 完成,成本高且可能破坏一些不兼容 HTTP 的实现。

当前 Ambient Mesh 已经较好地解决了 Sidecar 模式下应用和 Sidecar 的部署依赖问题,不再需要注入 Sidecar;服务网格的能力是通过 ztunnel 和 waypoint proxy 提供的,应用和网格组件的部署和升级不再相互依赖。


另外,Ambient 共享模式可以大大减少网格组件本身的资源开销,这一点对资源敏感的用户来说是一个巨大的福音。


Ambient 仍然处于预览状态,许多特性仍然在开发中,在官方文档 中已经列出不少限制,此外,社区用户在使用过程中也有新的发现:


• 不支持 IPV6

• 与 Calico CNI 不兼容,因为 Ambient 创建的 iptables 与 Calico 冲突。


同时,目前基于 envoy 的 ztunnel 在 xDS 效率、多租户、遥测方面可能存在性能问题,未来可能会基于 rust 重写一个更加轻量、高性能的 ztunnel。


长期来看,Sidecar 模式依然会是 Istio 的主流模式。Ambient 共享模式为 Istio 社区或者服务网格业界带来了足够的刺激,相信基于社区所有开发者的共同努力,Ambient 共享模式将会成为 Istio 的第二选择。


点击关注,第一时间了解华为云新鲜技术~

发布于: 刚刚阅读数: 4
用户头像

提供全面深入的云计算技术干货 2020.07.14 加入

华为云开发者社区,提供全面深入的云计算前景分析、丰富的技术干货、程序样例,分享华为云前沿资讯动态,方便开发者快速成长与发展,欢迎提问、互动,多方位了解云计算! 传送门:https://bbs.huaweicloud.com/

评论

发布
暂无评论
深度剖析Istio共享代理新模式Ambient Mesh_云计算_华为云开发者联盟_InfoQ写作社区