背景
- Kubernetes 实现自动化基础设施部署和资源管理,降低运维成本,增强业务弹性。
- Kubernetes 在应用部署和弹性方面有巨大优势,但对服务治理、网关、认证鉴权和可观测支持不足。
- 许多产品和传统中间件改革来弥补 Kubernetes 的不足,迁移到云原生和 Kubernetes。
- 服务网格是下一代微服务治理,下沉基础设施层进行通用治理,支持异构系统。
- 服务网格从理论到实践依赖 Kubernetes 容器编排,得到广泛关注和生产使用。
- Istio 是最流行的服务网格,提供标准的声明式 API,像 Kubernetes 抽象基础设施。
- Nacos 深度集成 Spring 生态和 Dubbo,现在集成 Istio,让用户各场景使用。
- Nacos 紧跟技术潮流,不错过 Kubernetes 和服务网格红利。
- Kubernetes 改变了资源管理和部署运维方式,Nacos 也在演进来适应新技术。
- Kubernetes 降低运维成本,提高业务弹性。服务网格和 Nacos 为用户提供更好的技术体验。
- 云原生技术 Kubernetes 和服务网格带来产业变革,Nacos 接入其生态为用户带来价值。
什么是服务网格
要深入理解服务网格的概念,明确服务网格要解决的问题,以及认识服务网格带来的业务价值,需要从应用架构的演进发展从头开始讲起。
单体架构向微服务体系架构的演进
近年来,随着业务体系不断发展和扩大,单体应用已经完成了向微服务架构的转变。应用按照功能维度、业务领域进行了服务拆分,各个不同的业务团队专注于自身负责的服务,每个微服务独立迭代且互相不影响。 这种拆分业务域的思想,不仅加快了业务发展速度,而且带来了更敏捷的开发体验。
凡事都有两面性, 微服务在提升业务应用的迭代速度和敏捷性的同时,也给服务治理带来了更多的挑战 。原先是单体应用,所有的服务都在⼀个进程中,服务之间的调用就是方法调用,整条请求的处理流程就在当前线程中,调试、排查问题非常方便。改造成微服务架构之后,原先单体中的服务变成⼀个个独立部署运行的服务,方法调用变成了远程调用。
服务发现
首先要解决的问题就是服务发现问题 ,Consumer 服务如何在运行时发现 Provider 服务,并且独立部署的服务节点的 ip 地址是不固定的,意味着需要⼀种动态发现的能力。注册中心的出现就是来解决微服务架构中服务发现问题,每个微服务在 部署发布 时会向 注册 中心登记自己的节点网络 ip,在 下线 时也会及时向注册中心进行 注销 操作。同时,每个微服务也会向注册中心 订阅 自己依赖的 其他微服务的节点信息 ,当订阅的微服务的节点信息发生变化时能够实时收到并更新本地连接池。
负载均衡
解决了服务之间如何发现的问题之后,Consumer 服务在处理请求时就可以从注册中心获取的节点信息列表中选择⼀个 ip 地址对 Provider 服务发起网络调用。为了 最大化资源利用率,最小化请求RT ,需要从节点池中 选择出⼀个最佳的节点,这就是负载均衡 。如果微服务的副本所占的硬件资源不同时,需要给予硬件资源充足的节点更多的流量。如果微服务的副本所处的地域不同时,需要优先访问与调用端所处地域相同的节点。如果业务有 Session 粘性的诉求,需要同⼀用户的请求始终访问同⼀个节点。如果微服务在启动之后需要预热,需要将流量逐步引流到该节点
熔断限流
单体应用中的 整个调用链 在当前进程中,面对 突发的流量洪峰 ,我们只需 对应用入口处进行熔断、限流 即可。而在微服务架构中,每个微服务独立部署,副本数量根据其功能的重要性会有所不同。在面对高并发的流量请求时,各个服务的熔断限流的阈值应该是不⼀样的。另外, 微服务架构增加了整个请求处理链的网络跳数 ,其中任意⼀个上游服务都可以 拖垮下游服务,甚至导致系统整体不可用 。
可观测 (监控告警)
在 可观测 方面,微服务架构中主要依靠三种手段:
- Tracing :分布式链路追踪,用于定位具体的故障发生节点。因为微服务的请求调用链路复杂,需要通过某种手段来获知整条请求的访问链路。
- Logging :日志记录,用于定位具体的故障原因。与Tracing配合使用,记录每个服务中的请求元数据信息,帮助排查故障。
- Metrics :设置各服务的连接数、请求数、成功率等指标的告警规则,以发现问题和提高系统稳定性。
认证鉴权
在微服务架构中,为了保护敏感服务的 安全 ,通常会利用认证鉴权机制来限制只有特定的客户端才能访问敏感服务。具体做法是:
- 引入一个中心化授权系统,由各个敏感服务来授权哪些客户端可以访问。
- 客户端在发起请求调用时,首先从授权系统获取凭证信息。
- 访问敏感服务时携带凭证信息。
- 敏感服务对收到的所有请求进行凭证信息和权限校验,只有校验通过才处理请求,否则拒绝。
这能避免在微服务架构下,任何能获取服务节点信息的客户端随意访问敏感服务的问题
其他…
服务发布、通信安全、动态路由…
小结
上面通过⼀些真实的业务场景来详细讨论了微服务架构带来的挑战以及应对方案,基本涵盖了服务治理几大领域, 服务发现、负载均衡、熔断限流、监控告警以及认证鉴权 。
我们可以用下图来囊括微服务架构所涉及的几大领域。
微服务体系架构的传统解决方案
总结来说,业务向微服务架构演进的主要动力有:
- 业务规模的增长带来的协作难度增加和发布频率需求,微服务架构下各服务独立开发和部署,降低了团队协作难度,满足频繁迭代的需求。
- 互联网业务快速演进,服务拆分迫在眉睫。各大公司通过服务拆分和微服务框架应对业务变化。
- 开源微服务框架(Spring Cloud、Dubbo、Gin等)实现了分布式系统通信和服务治理的各种功能(负载均衡、服务发现、熔断等),简化了微服务开发,让开发者专注业务。
- 新业务选择微服务架构,借助框架实现敏捷开发。
- 这些框架对业务开发者友好,屏蔽底层细节,使开发者专注业务,少量框架代码即可开发健壮分布式系统。
总之,业务发展和技术进步共同推动了微服务架构的普及。开源框架简化了微服务开发,使之更加实用,这也加速了这一进程。微服务架构有效地解决了大规模分布式开发带来的协作和交付挑战,更好满足快速演进的业务需求。
下图展示了微服务场景中服务之间的调用,业务开发者只需在服务 A 的业务代码中发起对服务 B 的调用,不必关心请求调用的底层是如何实现,比如如何发现服务 B 的地址,如何对服务 B 的负载均衡,如何进行流量控制,协议层的编解码以及底层网络的可靠通信。
这种微服务模式架构看似完美,但也存在⼀些本质问题:
- 框架本身的高学习成本 。开发者需要花更多精力去掌握和管理复杂的框架,解决框架问题也很困难。
- 业务与框架紧耦合 。框架以库的形式和服务联编,版本兼容和升级问题复杂,框架升级会影响服务稳定性。
- 限制业务技术栈 。框架通常只支持某些语言,导致业务只能选择与框架兼容的语言和中间件。没有框架支持的语言难以融入微服务架构。难以使用多语言实现微服务体系的不同模块。
所以,虽然微服务框架简化了开发,但也带来了上述问题。业务在选型和运用微服务框架时,需要权衡这些问题,做好管理和风险控制。
实际应用中,可以选择简单稳定的框架,或定制开发框架,或不使用任何框架,直接 face 分布式带来的各种问题。要根据业务实际情况选择最佳方案
下⼀代微服务架构——服务网格
为了解决传统微服务体系架构的上述三种局限性,以 Istio,NginxMesh 为代表的代理模式(边车模式)应运而生,这就是当前微服务架构领域比较火热的服务网格技术——Service Mesh,它将分布式服务的通信层抽象为单独的⼀层,在这⼀层中实现负载均衡、服务发现、认证授权、监控追踪、流量控制等分布式系统所需要的功能 。
从宏观上看,其实现方式为引入⼀个代理服务,以 Sidecar 的方式(边车模式)与每⼀个业务服务部署在⼀起,由代理服务接管服务的所有出入流量。控制面作为核心控制大脑,对所有业务的代理服务(Sidecar)进行统⼀的流量控制和管理 。
从微观上看,这个代理服务是通过代理业务服务之间的流量通信间接完成服务之间的通信请求,分布式系统中涉及到的所有服务治理都在代理服务中完成。通过这样⼀个与业务解耦的服务治理层可以轻松解决上边所说的三个问题。
服务治理层
服务网格明星产品 Istio
Istio为希腊文,意思是“启航”,和“kubernetes(舵手)”遥相呼应,是一个开源的微服务管理、保护、监控的基础设施。Istio发音“意丝帝欧” .
什么是 Istio
Istio 是⼀个由 Google,IBM 和 Lyft 团队合作开发的开源项目,它用来连接、保护、控制和观察集群中部署的服务。
目前比较火热的云原生技术 ServiceMesh ,其中⼀套比较流行的方案就是采用 Istio + Envoy 实现的。
Envoy 作为代理以 SideCar 形式和应用服务部署在⼀起,透明拦截应用服务所有的入口流量和出入流量,在转发流量之前执行⼀些额外的治理策略,这些操作都是对业务服务透明的,无感知的 。这样⼀来,如果我们把与业务应用耦合的服务治理相关 SDK 的功能下沉到SideCar,那么业务代码就会与服务治理代码解耦,并且可以并行迭代发展。
从这个角度看, ServiceMesh 提供了应用层面上网络通信的基础设施层,对其上的流量执行用户配置的治理策略。定义并下发这些治理策略的角色就是 Istio。
我们都知道 K8s 改变了传统的应用部署发布的方式,给容器化的应用服务提供了灵活方便的容器编排、容器调度和简单的服务发现机制,但缺少了更丰富和更细粒度的服务治理能力。 而 Istio 的出现正是为了弥补 K8s 在服务治理上的不足,它定义⼀套标准 API 来定义常见的治理策略。
K8s 与 Istio 呈互补关系,共同决定了业务应用的部署、发布以及运行时的行为。
网关处于集群的边缘,控制着集群的出入流量,可以看做是 Envoy 代理的独立部署,代理的是整个集群。
Envoy
Envoy 是一个开源的云原生边缘代理(edge proxy)和通信总线,由 Lyft 开发和维护。Envoy 的主要作用是作为微服务架构中的代理,提供以下功能:
- 服务发现:Envoy 集成了多种服务发现机制,可以动态发现后端服务器。
- 负载均衡:Envoy 支持多种负载均衡算法,可以根据服务发现的后端列表进行负载均衡。
- 熔断与故障注入:Envoy 支持熔断器模式,当后端服务故障时可以直接返回错误,避免故障蔓延。也支持故障注入,用于测试应用的容灾能力。
- 监控与遥测:Envoy 暴露 Prometheus 格式的指标,方便使用 Prometheus 等系统进行服务监控和遥测。
- 灰度发布:Envoy 支持基于 HTTP header、cookie 等的流量分离,可以实现微服务的灰度发布。
- 安全:Envoy 支持基于 SSL/TLS 的互相身份认证 mTLS,可以加密和认证微服务间的通信。
- 可观测性:Envoy 生成各种统计信息、日志与追踪,用于监控流量和调试应用。
所以,Envoy 的主要作用是作为微服务架构中的代理,提供丰富的服务治理与可观测性功能,帮助构建稳定可靠的微服务系统。它屏蔽了大量分布式系统通信中的复杂细节,使服务开发者可以专注于域业务。
Envoy 已被很多知名公司使用,如 Lyft,Airbnb,Pinterest,Expedia,Aral, etc。在国内也已有阿里、滴滴等公司使用 Envoy
Envoy 和 Istio
Envoy 和 Istio 都是用于微服务架构的开源项目,但侧重点有些不同:
Envoy:
- Envoy 是一个开源的边缘代理(edge proxy),主要实现服务发现、负载均衡、熔断、监控、灰度发布等功能。
- Envoy 通过部署多个代理实例,构建一个分布式代理层,实现上述功能。每个服务的客户端请求会首先经过 Envoy 边缘代理,再转发到后端服务。
- Envoy 只是一个代理,性质比较轻量,与具体的服务框架解耦。可以用于任何语言/框架开发的服务。
- Envoy 无法实现更高级的服务治理功能,如安全(服务间 mTLS)、流量管理等。
Istio:- Istio 是一个服务网格(service mesh)框架,除了代理功能外,还提供更丰富的服务治理功能,如安全、流量管理、可观察性等。
- Istio 基于 Envoy 代理,但在 Envoy 之上构建,提供服务发现、安全、流量管理等控制功能,以控制整个服务网格。
- Istio 需要和特定的服务框架(如Kubernetes)结合使用,与服务框架耦合度高。
- Istio 具有更高级的服务治理能力,但也更重量级,部署和维护难度大。
所以,Envoy 是一款轻量级的开源服务代理,主要提供基本的服务治理功能。而 Istio 则是一整套服务网格解决方案,基于 Envoy 但提供更丰富的功能,是更重量级的方案。
根据需求,可以选择使用 Envoy 或 Istio,或二者结合使用。 Envoy 也可以在 Istio 之外单独使用。
Istio 的基本架构
Istio 项目是基于 Kubernetes 运维平台构建的云原生新⼀代的服务治理框架
其架构图如下,摘自Istio 官网 (https://istio.io)
其中主要涉及到 数据面的代理服务 Proxy,集群入口网关 Ingress、集群出口网关 Egress 以及 核心控制面 Istiod 。
各个组件的功能如下:
- 代理服务 Proxy 采用的 Lyft 公司开源的高性能 C++ 网络代理 Envoy,拦截业务的所有出入流量。
- 入口网关 Ingress,作为集群的访问入口,控制着集群内部服务如何安全的暴露出去,并对所有入口流量进行统⼀控制和观测。
- 出口网关 Egress,作为集群的访问出口,控制着集群内部服务如何安全的访问外部服务。
- 核心控制面 Istio 负责对所有数据面的代理服务 (包括 Ingress、Egress 网关)下发服务发现信息,流量治理配置,以及用于服务之间进行双向认证的 TLS 证书。
可以看出 Istiod 是微服务领域的集大成者,覆盖了服务发现、服务治理、认证鉴权和可观测,以无侵入的方式为微服务体系架构的业务提出了云原生时代下新的解决方案。
Nacos 服务网格生态演进
Nacos 为了融入服务网格生态,完成了⼀次从微服务 1.0 架构到服务网格架构的演进架构。
传统微服务架构下的 Nacos
传统微服务架构下的 Nacos,其流量从 Tengine(Nginx) 进入,经过微服务网关,然后再进入微服务体系。
之所以分为两层网关,是因为
- 第⼀层 Tegine(Nginx) 是负责流量的接入,核心具备的能力是抗大流量、安全防护和支持 https 证书,追求的是通用性、稳定性和高性能。
- 第二层是微服务网关,这层网关侧重的是认证鉴权、服务治理、协议转换、动态路由等微服务相关的能力,比如开源的 spring cloudgateway,zuul 等都属于微服务网关。
流量进入微服务体系后,会通过微服务框架实现服务间的调用,比如 hsf/dubbo、spring cloud等等,那么 Nacos 在这里起到的核心作用是 服务发现能力 ,比如 cousumer 会先从 Nacos 获取provider 的服务列表地址,然后再发起调用,还有微服务网关也会通过 Nacos 获取上游的服务列表。这些能力主要通过 SDK 的方式提供,同时也会 在 SDK 上增加⼀些负载均衡、容灾保护的策略 。
传统微服务架构下的 Nacos 存在以下几个问题:
- Tengine 不支持动态配置,包括开源的 Nginx 原生也是不支持的,阿里内部是定期 reload 配置的方式实现配置变更,这导致配置不能及时变更,影响研发效率;
- Fat SDK 模式下,服务治理、服务发现等逻辑与 SDK 强耦合,如果需要变更逻辑,就得修改 SDK,推动业务方升级;
- 多语言下需要维护不同语言的 SDK,成本高,服务治理策略难以统⼀;
服务网格时代的 Nacos
随着云原生技术的发展和微服务 2.0 架构的提出,很多公司正在尝试通过服务网格技术去解决微服务 1.0 架构中的问题。在微服务架构 2.0 架构中,流量是通过 ingress 网关接入的,进入微服务体系,与 1.0 架构不同的是引入了 数据面 Envoy 和 控制面 Istio ,Envoy 以 Sidecar 模式与应用部署在同⼀个 Pod 中,会劫持应用的进出流量,然后可以通过控制面 Istio 下发的 XDS 配置实现流量控制、安全、可观测能力,这⼀架构的优势是将服务治理能力与业务逻辑解耦,把服务框架中SDK 大部分能力剥离出来,下沉到 Sidecar,也实现了不同语言的统⼀治理。
服务网格技术优势非常多,但是新架构的引入也会带来新的问题,尤其是对于技术包袱比较重的公司,将面临的问题,比如:sidecar 性能问题、私有协议支持问题、新旧架构体系如何平滑迁移等等。
主要关注新旧架构体系平滑迁移这个问题,平滑迁移必然会面对的两个关于服务发现的问题:
新旧架构体系如何互相发现 ,因为迁移过程必然存在两个体系共存的情况,应用需要互相调用;
注册中心如何支持微服务网格生态 ,因为 istio 目前默认支持的是 K8s 的 service 服务发现机制;
那么,在 Nacos 服务网格生态下是如何解决这些问题的呢?观察如下的架构图,其流量是从云原生网关(云原生网关,它具备的特点是与微服务架构保持兼容,既支持微服务网关,同时又能符合云原生架构,支持 K8s 标准的 Ingress 网关)进来,然后进入微服务体系,微服务体系中 1.0 应用(非 mesh 化应用)和已经 mesh 化的应用共存。
上图讲解了非 mesh 化应用是如何访问已经 mesh 化的应用的。 从这个架构图可以看到非 mesh化的应用还是通过 SDK 方式从 Nacos 进行服务注册或者服务订阅, 已经 mesh 化的 provider也会注册到 Nacos 上 ,这样非 mesh 化的应用也能获取到已经 mesh 化的应用服务信息,provider 注册服务⼀般是通过 sdk 方式,因为开源 envoy 不支持代理注册功能,当然阿里内部实现的时候,其实已经把服务注册的能力下沉到 sidecar。
另⼀个问题,mesh 化的应用的服务发现是怎么做的。我们可以看架构图的下面这部分,Nacos 已经支持了 MCP server 的能力, Istio 是通过 MCP 协议从 Nacos 获取全量的服务信息列表,然后再转化成 XDS 配置下发到 envoy ,这样即支持了 mesh 化应用内的服务发现,也能访问非 mesh化的服务,业务在 mesh 化过程中服务发现不需要做任何改造,就能无缝迁移。
MCP 协议
MCP 协议是 Istio 社区提出的组件之间配置同步协议,这个协议在1.8 之后就废弃了,替代方案是 MCP over XDS 协议,Nacos 两个协议都兼容。
除了 MCP 协议同步方案外,也有其它方案实现注册中心的服务数据同步到 ServiceMesh 体系,这些方案做了对比,如下图描述:
Nacos 服务网格生态在阿里大规模落地实践
这张图总体概括了阿里落地的两个场景。
场景⼀:
钉钉云上和集团互通的场景,本质其实就是混合云场景下的应用互通,我们是用了网关去打通这两个环境,钉钉 VPC(阿里云部署)这边用的是 MSE 云原生网关,集团用的是 Envoy 网关,他们之间使用 Dubbo3.0 的 Triple 协议实现网络通讯,网关的控制面都使用的是 Istio,Istio 会通过MCP 协议从 Nacos 同步服务列表数据。
使用这个架构解决了两个问题:
- 私有云和公有云网络通讯安全问题,因为网关之间使用 mtls 加密通讯;
- 平滑支持微服务架构,因为应用通过 Triple 协议调用网关,不需要业务做代码改动,服务发现则是通过 Nacos mcp 去同步数据;
这套架构同时也用于蚂蚁集团互通的场景,就是这张图的左边,蚂蚁的网关使用的是 Mosn onEnvoy 的架构
场景二:
集团的微服务 mesh 化场景,对应这张图的中下部分,内部落地与社区的差异点是,Envoy 直接对接了 Nacos 注册中心,使用这个方案主要还是考虑到性能问题,我们有些应用会有几万的实例 ip,如果通过 EDS 推送,因为数据量过大,会导致 Istio OOM 或者 Envoy 数据面 cpu 飙高等问题。