摘要:今年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 代理,接管应用的入口和出口流量。

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

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

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

深度剖析Istio共享代理新模式Ambient Mesh的更多相关文章

  1. 深度剖析JDK动态代理机制

    摘要 相比于静态代理,动态代理避免了开发人员编写各个繁锁的静态代理类,只需简单地指定一组接口及目标类对象就能动态的获得代理对象. 代理模式 使用代理模式必须要让代理类和目标类实现相同的接口,客户端通过 ...

  2. Istio Ambient Mesh七层服务治理图文详解

    摘要:本文主要集中剖析Ambient mesh七层服务治理相关内容. 本文分享自华为云社区<Istio Ambient Mesh七层服务治理图文详解>,作者:华为云云原生团队. 由于Amb ...

  3. ASP.NET MVC深入浅出系列(持续更新) ORM系列之Entity FrameWork详解(持续更新) 第十六节:语法总结(3)(C#6.0和C#7.0新语法) 第三节:深度剖析各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字 各种通讯连接方式 设计模式篇 第十二节: 总结Quartz.Net几种部署模式(IIS、Exe、服务部署【借

    ASP.NET MVC深入浅出系列(持续更新)   一. ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态模 ...

  4. 深度剖析java中JDK动态代理机制

    https://www.jb51.net/article/110342.htm 本篇文章主要介绍了深度剖析java中JDK动态代理机制 ,动态代理避免了开发人员编写各个繁锁的静态代理类,只需简单地指定 ...

  5. Java反射机制剖析(四)-深度剖析动态代理原理及总结

    动态代理类原理(示例代码参见java反射机制剖析(三)) a)  理解上面的动态代理示例流程 a)  理解上面的动态代理示例流程 b)  代理接口实现类源代码剖析 咱们一起来剖析一下代理实现类($Pr ...

  6. js对象详解(JavaScript对象深度剖析,深度理解js对象)

    js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了. JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕 ...

  7. 读书笔记之:C语言深度剖析

    读书笔记之:C语言深度剖析 <C 语言深度解剖>这本书是一本“解开程序员面试笔试的秘密”的好书.作者陈正冲老师提出“以含金量勇敢挑战国内外同类书籍”,确实,这本书中的知识点都是一些在面试中 ...

  8. .NET5.0 单文件发布打包操作深度剖析

    .NET5.0 单文件发布打包操作深度剖析 前言 随着 .NET5.0 Preview 8 的发布,许多新功能正在被社区成员一一探索:这其中就包含了"单文件发布"这个炫酷的功能,实 ...

  9. DDOS学习笔记(《破坏之王-DDOS攻击与防范深度剖析》)

           最近花了点时间把<破坏之王-DDOS攻击与防范深度剖析>看了一遍,坦白来说,这本书比较浅显,可以说是入门书,当然对于我这种对DDOS一知半解的人来说,也是一本不错的书,起码我 ...

随机推荐

  1. Pytorch从0开始实现YOLO V3指南 part2——搭建网络结构层

    本节翻译自:https://blog.paperspace.com/how-to-implement-a-yolo-v3-object-detector-from-scratch-in-pytorch ...

  2. java,捕获和抛出异常

    package Exrro; public class Test { //ctrl + alt + T快速生成异常捕捉 public static void main(String[] args) { ...

  3. idea 内置tomcat jersey 跨服务器 上传文件报400错误

    报错内容 com.sun.jersey.api.client.UniformInterfaceException: PUT http://.jpg returned a response status ...

  4. CSS(十四):盒子模型

    页面布局的本质 网页布局过程: 先准备好相关的网页元素,网页元素基本都是盒子. 利用CSS设置好盒子样式,然后放到相应的位置 往盒子里面装内容 网页布局的本质:就是利用CSS摆盒子 盒子模型 组成 所 ...

  5. 「一本通 1.4 例 2」[USACO3.2]魔板 Magic Squares

    [USACO3.2]魔板 Magic Squares 题目背景 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 题 ...

  6. 第四天python3 python解析式-生成器-迭代器

    标准库datetime datetime模块  对日期.时间.时间戳的处理 datetime类 类方法: today() 返回本地时区当前时间的datetime对象: now(tz=None) 返回当 ...

  7. SpringBoot使用CORS的addCorsMappings中会遇到的问题

    跨域需要后端需要设置响应的跨域头 如下 public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/ ...

  8. mysql 存储过程和触发器

    存储过程 -- 声明结束符 -- 创建存储过程 DELIMITER $ -- 声明存储过程的结束符 CREATE PROCEDURE pro_test() --存储过程名称(参数列表) BEGIN - ...

  9. php和js的不定参

    function my_func() { $args = func_get_args(); print_r($args); } my_func('php','java','node.js'); jav ...

  10. 关于javascript中this

    ------------恢复内容开始------------ 1 var number = 5; 2 var obj = { 3 number: 3, 4 fn1: (function () { 5 ...