01 服务网格数据面的演进
以 Istio 为代表的 Mesh 技术已经存在四五年的时间了,阿里云也是第一批支持 Mesh 云服务的厂商。在 Mesh 技术中,通过把服务治理的能力进行 化,实现与应用程序本身的解耦。这些若干个 代理就形成了一个网状的数据平面,通过该数据平面可以处理和观察所有应用服务间的流量。负责数据平面如何执行的管理组件称为控制平面。
可以看到,控制平面是服务网格的大脑,它为网格使用人员提供公开 API,以便更容易地操纵网络行为。总之,通过 Mesh 技术,Dev/Ops/SRE 将以统一的、声明的方式解决应用服务管理问题。
服务网格作为一种应用感知的云原生基础设施,提供了云原生应用感知的网络管理能力。
网络是 的核心部分,涉及了 Pod 间通信、Pod 和服务间通信以及服务与外部系统间的通信等。 集群中使用 CNI 插件来管理其容器网络功能,使用 Kube-proxy 维护节点上的网络规则,譬如使发往 的流量(通过 和端口)负载均衡到正确的后端 Pod。
容器网络成为用户使用 IaaS 网络的新界面,以阿里云 ACK 网络为例,基于阿里云 VPC 网络直通弹性网卡,具备高性能特征;同时无缝地跟阿里云 IAAS 网络对接;
然而,kube-proxy 设置是全局的,无法针对每个服务进行细粒度控制;而且 kube-proxy 只是专在网络数据包级别上运行。它无法满足现代应用程序的需求,如应用层流量管理、跟踪、身份验证等。
我们来看服务网格 代理模式下的云原生应用网络是如何解决这些问题的。服务网格通过 代理将流量控制从 的服务层中解耦,将代理注入到每个 Pod;并通过控制平面操纵管理这些分布式代理,从而可以更加精细地控制这些服务之间的流量。
那么在 代理下的网络数据包的传输是怎样的过程?
当前 Istio 实现中涉及了 TCP/IP 堆栈的开销,它使用了 Linux 内核的 通过配置 来拦截流量,并根据配置的规则对进出 代理的流量进行路由。客户端 pod 到服务器端 pod 之间的典型路径(即使在同一主机内)至少要遍历 TCP/IP 堆栈 3 次(出站、客户端 Proxy 到服务器端 Proxy、入站)。
为了解决这个网络数据路径问题,业界通过引入 eBPF 绕过 Linux 内核中的 TCP/IP 网络堆栈来实现网络加速,这不但降低了延迟,同时也提升了吞吐量。当然,eBPF 并不会替换 Envoy 的七层代理能力,在七层流量管理的场景下,仍然是 4 层 eBPF + 7 层 Envoy 代理的融合模式。只有针对 4 层流量网络的情况下,跳过代理 pod 直接进入网络接口。
前面讲述的是传统的 代理模式,除此之外,业界开始在探索一种新型的数据平面模式。它的设计理念是:将数据平面分层,4 层用于基础处理,特点是低资源、高效率;7 层用于高级流量处理,特点是功能丰富,当然需要更多的资源。这样的话,用户可以根据所需功能的范围,以渐进增量的方式采用服务网格技术。具体来说:
在 4 层处理中,主要包括:
在 7 层处理中,则主要包括:
那么数据面 L4 与 L7 代理的解耦模式下, Mesh 的网络拓扑将是什么形式?
一方面,将 L4 Proxy 能力下移到 CNI 组件中,L4 Proxy 组件以 的形式运行,分别运行在每个节点上。这意味着它是为一个节点上运行的所有 pod 提供服务的共享基础组件。
另一方面,L7 代理不再以 模式存在,而是解耦出来,我们称之为 Proxy, 它是为每一个 创建的 7 层代理 pod。
4 层和 7 层代理的配置仍然保持通过 Mesh 控制面组件来进行下发管理。
总之,通过这种解耦模式,实现了 Mesh 数据平面与应用程序之间的进一步解耦分离。
那么,在 Istio 的具体实现中,可以分为 3 个部分:
不影响应用程序是使 Mesh 比传统的 模式具备更少侵入性的原因之一。与采用 模式时必须将 代理注入到每个应用程序部署中相比, 模式下无需以任何方式重新部署或修改现有应用程序。通过不重新部署和直接修改应用程序,可以有效地降低落地风险并简化采用 Mesh 的落地曲线。
Mesh 的设计是非侵入式的,并且仅对存在特定标记的命名空间并使现有应用程序成为 Mesh 的一部分,可以逐步采用。一旦应用程序成为 Mesh 的一部分,它立即获得 mTLS 和 L4 可观察性功能。
02 网络 CNI 插件为节点进行网络命名空间配置
模式中 CNI 插件在两个位置进行网络命名空间的配置,其中一个就是在所处的节点上,另一个是在 pod 上。
具体如下:
CNI 插件在每个节点上初始化路由并设置 和 ipset。
注意:与 模式下不同,CNI 插件所做的配置不会直接影响任何工作负载 pod。更改仅在节点网络命名空间和 pod 的网络命名空间中进行,与流量重定向机制无关。
网格 CNI 插件为节点进行配置的内容可以分为 4 个部分:
1. 创建名为 -pods-ips 的 IP 集(ipset)
2. 由 Mesh CNI 网络插件创建网络接口( )
3. 设置网络接口的参数
4. 设置 、路由表和路由规则具体来说:
1. 创建名为 -pods-ips 的 IP 集(ipset)
节点上创建了一个名为 -pods-ips 的 IP 集,用于存储当前节点中启用 模式的 pod 的 IP 地址。每次添加一个 pod 时,CNI 插件将 pod 的 IP 地址添加到节点上的 -pods-ips IP 集(ipset)中。
随着 pod 的添加或删除(即它们的 IP 地址发生变化),CNI 插件会让节点上的 ipset 保持最新。
在节点上可以通过运行 ipset list 命令查看作为 ipset 中的 IP 地址:
通过 查看纳入到 模式中的本节点下的 Pod 列表,例如:
对比分析可以看到,在节点 172.17.0.3 上,纳入到 模式的 Pod 有 2 个,IP 地址分别为 172.17.0.48 和 172.17.0.66。这 2 个地址也被写入到 -pods-ips IP 集 (ipset) 中。
2. 由 Mesh CNI 网络插件创建网络接口( )
在每个节点上,设置了两个虚拟网络接口( ) – 和 。
由 Mesh CNI 网络插件创建:
执行前面三行的命令后,Linux 系统会将 IP 地址 192.168.126.1 和子网掩码 255.255.255.252 添加到 网络接口中,以便该网络接口可以用于与该 IP 地址所在的子网中的其他主机进行通信。然后将 网络接口启用,以便该网络接口可以用于网络通信和数据传输。网络接口启用后,它可以接收和发送数据包,与其他网络设备进行通信和交换数据。
同样的,后面三行命名执行后,Linux 系统会将 IP 地址 192.168.127.1 和子网掩码 255.255.255.252 添加到 网络接口中,以便该网络接口可以用于与该 IP 地址所在的子网中的其他主机进行通信。然后将 网络接口启用,以便该网络接口可以用于网络通信和数据传输。网络接口启用后,它可以接收和发送数据包,与其他网络设备进行通信和交换数据。
在 Linux 系统中,网络接口启用后通常会被标记为 “UP” 状态,可以通过 ip link show 命令查看网络接口的状态信息。例如, 在节点上运行命令 ip link show,显示网络接口的链路层信息,可以得到类似如下内容:
3. 设置网络接口的参数
4. 设置 、路由表和路由规则
节点上的另一个更改是 链,它将数据包从现有的表(NAT 和 )中的标准链(例如 , 等)重定向到自定义的 链。如下图所示:
具体来说,对应执行如下命名:
此外,通过执行如下命令,用于在 表和 nat 表中为自定义链 -、-、-INPUT、- 和 – 添加一些规则,具体含义如下:
以及用于在 表中的自定义链 – 中添加一些规则,具体含义如下:
任何标记为 0x100/0x100 的数据包(即来自 pod)根据对应的路由表中的规则进行路由。创建这些路由表所需要执行的命令如下:
具体描述如下:
配置 IP 路由规则
具体来说,对于标记为 0x200/0x200 的数据包,跳转到主路由表(编号为 32766)进行路由。
对于标记为 0x100/0x100 的数据包,在路由表 101 中查找路由信息进行路由。
对于标记为 0x040/0x040 的数据包,在路由表 102 中查找路由信息进行路由。
将路由表 100 作为本地主机的默认路由表。
出站标记以及数据包标记的说明如下:
网格内部 Pod 的流量请求所经过的数据包流向,大致如下:
03 网格 CNI 插件为 Pod 配置网络命名空间
网格 CNI 插件为 Pod 进行配置的内容可以分为 3 个部分:
1. 由 Mesh CNI 网络插件创建网络接口( )
2. 设置网络接口的参数
3. 为 pod 设置 、路由表和路由规则
具体来说:
1. 由 Mesh CNI 网络插件创建网络接口( )
在每个 Pod 上,设置了两个虚拟网络接口( )- 和 。由 Mesh CNI 网络插件在 pod 里创建:
在 Pod 里运行命令 ip link show,可以得到类似如下内容:
2. 设置网络接口的参数
类似地,网格 CNI 插件将为 pod 设置网络接口, 参数设置为 0,关闭反向路径过滤,绕过数据包源 IP 地址的校验;
3. 为 pod 设置 、路由表和路由规则
在 pod 上, 接口接收到的任何内容都会被转发到端口 15008(HBONE)和 15006(纯文本)。
同样, 接口接收到的数据包最终会到达端口 15001。
还捕获端口 15053 上的 DNS 请求,以提高网格的性能和可用性。请注意,仅当在 DNS 代理中指定的 RE 设置为 true 时,才会创建配置到 15053 的路由规则。
网格 CNI 插件为 Pod 里设置 Pod 也设置了路由规则,可以使用 ip rule list 命令查看路由规则:
对应的含义指,当数据包的标记值在 0x400~0xfff 范围内时,将会匹配这条规则,并将数据包发送到编号为 100 的路由表中进行操作,优先级为 20000。
当数据包的标记值恰好等于 0x4d3~0xfff 范围内时,将会匹配这条规则,并将数据包发送到编号为 100 的路由表中进行操作,优先级为 20003。
此外,网格 CNI 插件为 配置 ,定义如下:
可以看到, 规则使用 标记(0x400/0xfff)标记来自入站或出站隧道的数据包,并将其定向到相应的 入站和出站端口。为什么使用 方式呢? 是 Linux 内核的一个功能,允许在传输层透明地拦截和重定向网络流量,相比之下,使用 目标修改数据包以更改目标地址。使用 ,这样请求从pod通过隧道到 代理的所有跳跃中,流量的原始源 IP 和端口被保留,允许目标服务器看到原始客户端的 IP 地址和端口。
04 节点与 通过 隧道连接
( )是一种网络虚拟化封装(隧道)协议,它的设计的初衷是为了解决当前数据传输缺乏灵活性和安全性的问题。
相较于 VXLAN 封装,具有更加灵活、安全、扩展和运维的特点,适用于更加复杂和安全性要求高的虚拟化网络环境。
veth 设备与 机制之间存在关联。 是 Linux 内核中的一种通信机制,用于内核与用户空间之间的通信。通过 机制,用户空间可以向内核发送请求,获取网络设备、路由表、套接字等信息,实现网络配置和管理等功能。
在容器化技术中,veth 设备的创建和配置通常是通过 机制实现的。前面的介绍中提及可以使用以下类似命令创建一个名为 的 设备:
ip link add name type id 1000 “${}”
其中,type 表示创建一个 设备,id 1000 表示设备的虚拟网络标识符, IP 地址表示设备的远程目的地址。
CNI 插件在每个节点上初始化路由并设置 和 ipset 规则。在每个节点上,设置了两个虚拟接口 – 和 ,用于处理节点上的入站 () 和出站 () 流量。其中,虚拟接口 和 的 IP 地址分别为 192.168.126.1 和 192.168.127.1。
这两个接口使用 (通用网络虚拟化封装)隧道连接到在同一节点上运行的 pod 的接口 和 上。其中,虚拟接口 和 的 IP 地址分别为 192.168.126.2 和 192.168.127.2。
结合节点上的 规则和路由表,确保来自 pods 的流量被拦截,并根据方向(入站或出站)分别发送到 或 。发送到这些接口的数据包最终会到达在同一节点上运行的 pod 的 或 。
具体来说,使用 隧道连接到节点上的 接口 —> 端的 接口,如下所示:
使用 隧道连接到节点上的 接口 —> 端的 接口,如下所示:
05 L4 与 L7 的融合及端到端的流量路径
对于仅涉及到 4 层请求的业务场景来说,L4 请求处理下的端到端的流量路径如下所示:
1. 模式下的应用 Pod 会被 CNI 插件将其 IP 地址写入到 ipset 中,当发起请求时,流量数据包进入到该节点上对应的 veth 接口。
2. sleep app pod 的请求被节点上的规则和 配置捕获。
3. 因为该 pod 是环境网格的一部分,它的 IP 地址被添加到节点上的 IP 集合中,并且数据包被标记为 0x100。
4. 节点上的规则指定任何标记为 0x100 的数据包都要通过 istio 出口接口定向到目标 192.168.127.2。
5. 代理上的规则透明地代理来自 的数据包到 出站端口 15001。
6. 处理数据包并将其发送到目标服务()的 IP 地址。该地址在节点 B 上为 创建专用接口 veth,请求在该接口上被捕获。
7. 入站流量的规则确保数据包被路由到 接口。
8. 和 之间的隧道使数据包落在 pod 上。
9. 配置捕获来自 的数据包,并根据标记将它们定向到端口 15008。
10. pod 处理数据包并将其发送到目标 pod。而如果涉及到 7 层请求的业务场景来说,端到端的流量路径则增加了 Proxy 的部分,如下所示:
在 Proxy 中执行的流程如下:
1. 进入到 proxy 之后, 通过流量总入口监听 接收来自 HBONE 的流量,包括身份认证,HBONE 解包等。然后将流量转给 这个主监听器。
2. 主监听器里面有匹配逻辑,根据 ip + port 来匹配。匹配上之后,执行各种 L7 流量策略。然后转发给对应的 。 并没有把流量直接转发出去,而是转发给了。
3. 以 HBONE 的方式,向上游转发数据。
06 与 模式融合的服务网格
作为业内首个全托管 Istio 兼容的阿里云服务网格 ASM 产品,在不同维度提供了企业级产品功能:
1)在控制面维度,实现了全面托管机制,为用户降低运维复杂度;为数据面提供了统一标准化的接入方式;支持开箱即用的 插件市场,支持 / 及 AI / 生态等。
2)在数据面维度,支持形态与功能多样化,支持不同形态的计算基础设施,包括 K8s 集群、 ECI 节点、边缘集群、注册集群等;支持不同的数据面网络形态;支持异构服务统一治理、精细化的多协议流量控制与全链路灰度管理。
3)在性能维度,实现软硬一体的端到端网格优化,支持自适应配置推送优化,实现了 AVX 指令集提升 TLS 加解密、以及资源超卖模式下的支持等。更多内容可以参考:《企业级服务网格优化中心:优化 Mesh 以提高性能和高可用性》
近期阿里云服务网格 ASM 产品即将推出业界首个 与 模式融合的服务网格平台,欢迎试用与交流!
可以通过: 查看具体的内容介绍。
作者:王夕宁 阿里云服务网格负责人,以下内容基于 2023 全球软件工程创新技术峰会的演讲内容整编而成
点击立即免费试用云产品:
原文链接:
———END———
限 时 特 惠: 本站每日持续更新海量各大内部创业教程,永久会员只需109元,全站资源免费下载 点击查看详情
站 长 微 信: nanadh666