1

深度剖析Istio共享代理新模式Ambient Mesh - 华为云开发者联盟

 1 year ago
source link: https://www.cnblogs.com/huaweiyun/p/16725206.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

摘要:今年9月份,Istio社区宣布Ambient Mesh开源,由此引发国内外众多开发者的热烈讨论。

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

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

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

1.Ambient Mesh 是什么

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

2.Ambient Mesh架构分析

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

v2-fe64a813b169eb5eaae966a4b4d1a287_720w.jpg

图1 Istio架构

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

v2-81489610e49ccc31bd46867a5ba14263_720w.jpg

图2 Ambient mesh分a层

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

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

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

v2-332ceed836571f695a1a5126a695061f_720w.jpg

图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七层治理的架构:

v2-35bac2a3aa7989c670c5b55ed3a9a05c_720w.jpg

图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/v1alpha2
kind: Gateway
metadata:
  name: productpage
  annotations:
    istio.io/service-account: bookinfo-productpage
spec:
 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应用分别运行在两个不同的节点。

v2-f02dab7e96441eec36cf606533fbbc65_720w.jpg

图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模式的监听器完全不同,它包含所有本节点上的服务到整个网格其他服务的过滤器链。
v2-eb009eb293992723b2f717f3387a00a3_720w.jpg
v2-201da25f7febf2deabff4a56fb00e8bd_720w.jpg

图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"过滤器处理,

v2-e7c0396ce8848905507b65314150ab1b_720w.jpg

图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" 的监听器处理。

v2-d84cad65344e7af9e78acae70e0cb866_720w.jpg

图8 outbound_internal内部Cluster配置

v2-3e0d43b4899f6436440b25a1eb684c28_720w.jpg

图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 组件之间安全通信的承载协议。

v2-251d902c9290fb0ffa764139362d1da4_720w.jpg

图10 outbound_tunnel监听器配置

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

v2-67fa11dd48106c85df5c84ddc3414dac_720w.jpg

图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处理。

v2-0109bf6851cf018f34ecc91f5f029fea_720w.jpg

图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容器。

v2-5546c956fa5fe51916a8f8f41a2f6910_720w.jpg

图13 virtual_inbound cluster配置

3.3 Ambient Mesh四层流量治理小结

v2-282bb578adf1106068ad4c9490c59ef5_720w.jpg

图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的第二选择。

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK