Service Mesh 是一种用于管理微服务架构中网络通信的解决方案,通过在每个服务实例中添加代理,实现流量控制、服务发现、负载均衡等功能。虽然 Service Mesh 能够提供很多优秀的功能,但也存在一些性能问题,譬如
在实际使用中,需要根据具体情况进行选择和优化,以达到更好的性能和用户体验。而作为业内首个全托管 Istio 兼容的服务网格产品 ASM,一开始从架构上就保持了与社区、业界趋势的一致性,控制平面的组件托管在阿里云侧,与数据面侧的用户集群独立。阿里云服务网格 ASM 产品也是首批通过可信云服务网格性能测评,先进级认证、排名第一、全项满分。
阿里云服务网格 ASM 产品是基于社区开源的 Istio 定制实现的,在托管的控制面侧提供了用于支撑精细化的流量管理和安全管理的组件能力。通过托管模式,解耦了 Istio 组件与所管理的 K8s 集群的生命周期管理,使得架构更加灵活,提升了系统的可伸缩性。
下图是阿里云服务网格 ASM 产品的技术架构。
托管式服务网格 ASM 在成为多种类型计算服务统一管理的基础设施中,提供了统一的流量管理能力、统一的服务安全能力、统一的服务可观测性能力、以及基于 WebAssembly 实现统一的代理可扩展能力,以此构筑企业级能力。
可以通过:https://www.aliyun.com/product/servicemesh 查看具体的内容介绍。
以下将讲述 ASM 产品从多维度、不同层面的性能优化手段来构建网格优化中心, 提升产品的性能指标与高可用性:
在 Istio 中,可以通过以下几种方式收敛服务发现的范围,从而提高控制平面推送网格配置的效率。通过收敛服务发现范围,可以达到如下目标,包括有效降低控制面组件 CPU 资源消耗与内存资源消耗、以及有效降低控制面组件与网格代理之间的通信时的带宽资源消耗。
通过 Discovery Selector 可以定义一组过滤规则,用于筛选出需要同步到控制平面的服务发现信息:
此外,通过 ExportTo 与 Workload Selector 来收敛规则配置的范围,其中:
阿里云服务网格 ASM 产品提供了对应的功能,具体来说,可以通过选中或取消选中命名空间来定义服务发现的范围,如下图所示:
此外,也可以支持通过编辑标签选择器的方式选择对应的命名空间下的服务,如果数据面 Kubernetes 集群的命名空间与任一标签选择器匹配,该命名空间下的服务将被包括在自动发现范围之内。同时,数据面 Kubernetes 集群的命名空间必须与每个标签选择器中定义的所有规则相符,才能被该选择器选中。
如下图所示:
更多细节,可以参考:https://help.aliyun.com/document_detail/363023.html
这个优化手段是基于 xDS 及 Sidecar 对象实现的,首先介绍下对应的背景信息。
xDS 协议是 “X Discovery Service” 的简写,是 Service Mesh 控制面和数据面 Sidecar Proxy 之间的通信协议,x 表示包含多种协议的集合,比如:LDS 表示监听器的发现,CDS 表示服务和版本的信息,EDS 表示服务和版本有哪些实例,以及每个服务实例的特征信息,RDS 表示路由的发现。
xDS 协议是网格代理获取配置信息的传输协议,也是 Istio 与网格代理连接的桥梁。可以简单的把 xDS 理解为:网格内的服务发现数据和治理规则的集合。xDS 数据量的大小和网格规模是正相关的。
默认情况下,下发 xDS 使用的是全量下发策略,也就是网格里的所有网格代理内存都会有整个网格内所有的服务发现数据。
在大多数情况下,在大规模集群中的一个简单的工作负载可能只与少数其他工作负载进行通信。将它的配置更改为仅包含一组必要的服务会对网格代理的内存占用产生很大影响。Sidecar 资源对象可以帮助定义这种配置约束关系。
基于访问日志分析自动推荐生成 Sidecar 资源对象的工作实现原理:
它适合的场景是已经存在了这些服务调用的日志数据,并且现有业务服务的调用依赖关系变化不大,通过该方式可以一次性地实现优化。以 bookinfo 示例来说,通过几次请求之后,每个网格代理都会产生对应的访问日志。以 productpage 服务为例,生成的推荐的 Sidecar 资源对象内容如下:
当然,使用该功能需要一定的前提条件:
需要依赖于用户开通日志服务来采集这些访问日志内容,并要求产生的日志需要覆盖全部业务调用,才能得到全部的依赖关系。一旦某业务路径没有调用产生日志,那么很有可能丢失对应的服务依赖关系,从而导致生成的 Sidecar 资源对象定义内容不准确,进而可能导致之后的该业务路径访问调用不通。
阿里云服务网格 ASM 产品提供了对应的功能,提供了使用基于访问日志分析自动推荐的 Sidecar 资源对象来提升 xDS 推送的效率,如下图所示。
具体可以参考:https://help.aliyun.com/document_detail/386398.html
为了缓解上述方案中的局限性,我们提供了另外一种优化手段,即按需推送 xDS 配置的能力,自适应应用服务的变更。
自适应配置推送优化根据网格内服务的访问日志分析服务之间的依赖关系,并自动为服务生成 Sidecar 资源对象以优化针对该服务工作负载的配置推送。功能开启后,集群中会部署名为 istio-axds-egressgateway 的出口网关,服务之间调用的所有 HTTP 流量初始都将指向该出口网关,并通过网关记录的访问日志自动分析服务之间的依赖关系。
具体来说,通过如下架构图可以看到:
要为集群内的服务启用自适应配置推送优化能力,可以按照命名空间范围进行开启。开启后,命名空间内的服务都将自动地进行基于 Sidecar 资源对象的配置推送优化。
此外,也可以在 Kubernetes 服务的 annotations 中增加 http://asm.alibabacloud.com/asm-adaptive-xds: true 注解以单独为该服务打开优化选项。
在使用 ASM 产品的某客户场景中,通过该方式优化之后,网格代理中的配置减少了 90%,所消耗的内存消耗从 400M 减少到 50M。
阿里云服务网格 ASM 产品提供了对应的功能,提供了自适应配置推送优化提升 xDS 推送的效率以及减少网格代理的不必要配置。
具体可以参考:https://help.aliyun.com/document_detail/479108.html
数据面的形态是多样的,运行的 ECS 规格型号、OS 的版本等都不尽相同,通过探测节点的特征,我们可以更好地理解节点所具备的支撑能力,譬如可以根据 Kernel 版本判断是否可以支持 eBPF 的相关功能,根据是否支持 AVX 扩展指令集决定开启 TLS 加解密处理能力, 或者判断是否提供了 Device Plugin 等。
也就是说,通过检测 Kubernetes 集群中每个节点上可用的硬件功能特征, 包括 CPUID 特征、指令集扩展等;然后根据探测到的特征,自适应动态配置相应的特性, 自适应启用或禁用对应特性,整个过程对用户无感知。
这样一来,可以充分利用用户使用的节点环境,动态启用这些特性,从而提升相应的能力。在阿里云服务网格 ASM 产品中,已经上线的功能包括了根据是否支持 AVX 指令集动态启用 Multi-Buffer 特性,提升 TLS 加解密性能。
具体可以参考与 Intel 合作的技术白皮书:https://developer.aliyun.com/ebook/7817
具体来说:
1) 在服务网格控制面,通过扩展 MeshConfig 或者 CRD 方式,为用户提供统一的声明式配置定义。
2) 控制面的配置通过 xDS 协议下发到数据面 Envoy 代理。这一部分也是在 ASM 产品中做的一些扩展能力。
3) 工作负载 Pod 的调度优先与自适应动态配置。通过对节点的特征标识,ASM 优先将启动 Multi-Buffer 功能的 Pod 调度到对应的节点上,从而使得相关的功能能够被启用。除了调度之外,ASM 产品支持自适应动态配置能力,也就是说即使没有对应的节点可调度,这些 Pod 在其他节点上部署时, 能够自适应去禁用这些功能。
在 Kubernetes 系统中,Kubelet 通过参考 Pod 的 QoS 等级来管理单机容器的资源质量,例如 OOM(Out of Memory)优先级控制等。Pod 的 QoS 级别分为 Guaranteed、Burstable 和 BestEffort。QoS 级别取决于 Pod 配置的 Request 和 Limit(CPU、内存)。
ack-koordinator 提供动态资源超卖功能,通过对节点负载数据的实时收集,可以充分挖掘集群中已分配但未使用的资源量,以实现对集群资源的动态超卖。
注意的是,一般不强制资源限制和所需资源配置为相同值。建议您参照工作负载类型,对资源限制和所需资源进行配置。
阿里云服务网格 ASM 产品提供了对应的功能,您可以设置注入的 Istio 代理以及 isito-init 初始化容器的 ACK 动态超卖资源。
更多信息,请参见配置 Sidecar 代理:https://help.aliyun.com/document_detail/613582.html
eBPF 是一项获得广泛关注和普及的技术,尤其是在流量、性能方面提供许多潜在的优化功能,例如在服务网格领域用 eBPF 替换 iptables 以在网格内进行流量重定向的功能。
Merbridge 是专注于使用 eBPF 加速服务网格的 CNCF 开源项目。Merbridge 在服务网格中使用 eBPF 技术代替 iptables,实现流量拦截。
借助 eBPF 和 msg_redirect 技术,Merbridge 可以提高 Sidecar 和应用之间的传输速度,降低延迟,如下图所示。
eBPF 提供重写 tcp_sendmsg 函数的能力,让 eBPF Program 接管 tcp_sendmsg。
同时,eBPF 提供了 bpf_msg_redirect_hash 相关的 helper 函数,可以在被接管的 tcp_sendmsg 内将主机上的两个 socket 传输路径进行短接,绕过内核态协议栈,从而加速进程间的访问。
Helper 函数依赖一个内核级别的 map 保存连接信息,需要确保每个连接在 map 中的 key 互不冲突。
Ambient 模式下,加入/移除网格将更加灵活,CNI 模式将不再适用(CNI 只会在 Pod 创建的时候生效,Ambient 模式允许通过修改 annotation 的方式将 Pod 纳入网格)。
Container 出口流量拦截的地址将不再是 127.0.0.1:15001,而需要转发到当前节点 ztunnel 实例。
由于 Pod 中不存在 Sidecar,之前通过判断是否监听 15001 端口等方案来确定是否需要拦截的方案将不再生效。
如何解决 Ambient 模式下这些问题呢?
通过 eBPF 观察进程创建事件,在用户态关联 cgroup id 和 Pod IP。同时,将 Pod 信息等进行储存。
在 eBPF 程序中,通过当前进程的 cgroup id 查找当前进程的 Pod IP。(一个容器中的进程应该具有相同的 cgroup id,且不会变更)
如果是 Ambient 模式的 Pod 发出的流量,将流量转发到 ztunnel。
阿里云服务网格 ASM 产品也在专注于一些基于 eBPF 以及阿里云容器服务 ACK 网络插件的性能改进,同时也正在与 Merbridge 团队更多地合作。
尽管我们已经实现了上述几种维度下的性能优化手段,然而众所周知性能是一个需要持续关注的话题,我们会进一步探索和研究,找到更加有效的解决方案,以提高 Service Mesh 的性能和稳定性。
作者:王夕宁 本文根据王夕宁在 2023 年 6 月份在北京举行的 CNCF Kubernetes Community Day(KCD)会议上的演讲主题整理而成
点击立即免费试用云产品 开启云上实践之旅!
原文链接
本文为阿里云原创内容,未经允许不得转载。