深度剖析!istio共享代理新模式ambient mesh-凯发k8国际娱乐官网入口

云容器大未来 发表于 2022/09/23 10:24:43 2022/09/23
【摘要】 今年9月份,istio社区宣布ambient mesh开源,由此引发国内外众多开发者的热烈讨论。实际上,通过与istio toc成员linsun(https://github.com/linsun)的交流,我们得知早在2021年,solo.io已经开始共享代理的研究和设计,同样也是在2021年google内部也在探索共享代理模式。

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

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

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


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


开始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/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弹性伸缩策略,不再与应用耦合,提供更加灵活的扩展性并可以在一定程度上提升资源的使用率。

我们知道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_internalcluster选择的是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_inboundcluster处理


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

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


扫描二维码 | 加入云原生技术交流群

【凯发k8国际娱乐官网入口的版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。