Service Mesh

目录

微服务架构流量治理的难点

微服务一方面是把原来在静态编译时产生的能力与能力之间的关联关系,通过架构拆分推演到动态的运行时。因此在运行时,服务与服务之间是需要进行通讯、协同,才能完成某一项具体的业务功能。

当大家进行通讯、协同时,就一定要对其通讯过程进行管理,或者说要进行流量管理。例如,我们要知道怎样从一个微服务找到另一个微服务,以及怎样能保证一个微服务找到最佳的微服务实例跟它进行通讯,这是一个比较复杂的过程,其中包括 RPC 能力、服务注册发现能力、动态配置管理能力以及服务降级能力等等。

为了减轻业务开发者的负担,不用重复的在每一个微服务中写一遍微服务的流量管理的通用能力,因此大家开发了很多分布式的微服务治理框架,比如:

  • Java 的 Spring Cloud
  • Golang 的 Go Mirco
  • 阿里巴巴的 HSF

在这里插入图片描述

因此,从抽象层面可以看到一个服务包含了两个层面:

  1. 一个层面是本身的业务逻辑,也就是由微服务业务开发人员去编写的,功能实现与业务实现相关的代码。

在这里插入图片描述

  1. 另一个层面是为了实现微服务与微服务之间通讯、流量、服务治理的代码,我们会将其抽象成一个框架,如下图中标出的 Spring Cloud。这样的抽象带来了一个问题,就是所有的通用能力都依赖于这个具体的框架。

在这里插入图片描述

假设在公司之中,除了 Spring Cloud 之外,我们去引入另外一些服务框架,如阿里巴巴 HSF 如果希望和 Spring Cloud 框架上面编写的微服务进行通讯的话应该如何去操作?这就要求 HSF 与 Spring Cloud 之间互联互通以及协议之间的互相理解。但其实这些框架之间往往并不具备这个能力。

更大的一个问题可能在于,云原生时代我们允许这些微服务的研发能用不同开发语言及模型来进行编程。因此,框架之间的系统并不是不是一对二的关系,也不是仅仅是 Spring Cloud 与 HSF 的关系,可能是 Java 体系与 JavaScript、Python、Go 体系这些微服务框架都需要打通的问题,它变成了一个 N to M 的 Problem,来解决多语言、复杂环境中微服务的治理与管理问题。

这时,当我们有了容器、容器平台、POD 这些抽象,能够提供一个平台,而不是必须要完全依赖于业务中的代码或框架时,有没有更好的办法来解决刚才提到的问题?

现在有一个比较流行的概念叫 Service Mesh(服务网格)。它的本质就是为了更好地解决流量治理在多语言、多环境场景下的问题,它的主要思想如下:

  • 第一就是希望把流量管理的这些框架能力从耦合在业务的二进制中抽象、剥离出来,形成一个流量管理的单独进程,并以 Sidecar 的模式部署在 Pod 中。通过操作系统级别的透明流量劫持工作,把所有的微服务之间的流量劫持到 Sidecar 中,然后通过 Sidecar 与 Sidecar 之间通讯进行流量的转发与管理。这样问题就简单多了,我们只需要让流量管理的 Sidecar 之间互相通讯、能够进行互联互通。目前比较知名、流行的开源流量劫持和管理 Sidecar 实现叫做 Envoy。

  • 当然,单单有了这层流量劫持与管理还是不够的,还需要管控平面的支持。比如原来微服务体系做的服务注册、服务发现以及流量观测还是需要的,这些策略和规则需要下发给流量管理的 Sidecar 代理。因此,我们还需要构建一个管控平面来管理在 Pod 中部署的流量管理的数据平面的单点,让它们形成一个网状,形成一个集群。所以我们需要有一些管控平面的能力,在开源中比较流行的一个管控平面实现叫 Istio。主要实现了三个能力:流量的配置、流量的安全、流量的观测。

在这里插入图片描述

我们认为在云原生这个逐渐平台化的时代,大部分新的应用及场景都会尝试选用基于 Service Mesh 的技术进行微服务的流量治理。

Service Mesh

SOA 采用中心化的服务总线架构,解耦了业务逻辑和服务治理逻辑。而微服务架构则回归了去中心化的点对点调用方式,在提升敏捷性和可伸缩性的同时,也牺牲了业务逻辑和服务治理逻辑解耦所带来的灵活性。

为了解决上述挑战,社区提出了 Service Mesh(服务网格)架构。它重新将服务治理能力下沉到基础设施,在服务的消费者和提供者两侧以独立进程的方式部署。这样既达到了去中心化的目的,保障了系统的可伸缩性,也实现了服务治理和业务逻辑的解耦。二者可以独立演进不相互干扰,提升了整体架构演进的灵活性。同时服务网格架构减少了对业务逻辑的侵入性,降低了多语言支持的复杂性。

Google、IBM、Lyft 主导发起的 Istio 项目就是服务网格架构的一个典型的实现,也成为了新的现象级 “网红” 项目。

Istio

在这里插入图片描述

上图是 Istio 的架构,逻辑上分为数据平面和控制平面:

  • 数据平面:由一组以 Sidecar(边车)方式部署的智能代理组成,负责截获应用网络流量,收集遥测数据并且执行服务治理策略。
  • 控制平面:Galley 负责配置管理,Pilot 负责下发配置,Mixer 负责策略检查和遥测数据聚合,Citadel 负责通信中安全证书管理。

Sidecar 是一个抽象了公共代码的反向代理组件,每个服务都额外部署这个代理组件,所有出站入站的流量都通过该组件进行处理和转发。Sidecar 不会产生额外网络成本,会和微服务节点部署在同一台主机上并且共用相同的虚拟网卡。所以 Sidecar 和微服务节点的通信实际上都只是通过内存拷贝实现的。

在这里插入图片描述

Sidecar 只负责网络通信,还需要有个组件来统一管理所有 Sidecar 的配置。在 Service Mesh 中,负责网络通信的部分叫数据平面(Data plane),负责配置管理的部分叫控制平面(Control plane)。数据平面和控制平面构成了 Service Mesh 的基本架构。

在这里插入图片描述

Sevice Mesh 相比于微服务框架的优点在于它不侵入代码,升级和维护更方便。它经常被诟病的则是性能问题。即使回环网络不会产生实际的网络请求,但仍然有内存拷贝的额外成本。另外有一些集中式的流量处理也会影响性能。

Service Mesh 的问题

Istio 提供了一系列高阶的服务治理能力,比如:服务发现和负载均衡,渐进式交付(灰度发布),混沌注入与分析,全链路追踪,零信任网络安全等,可以供上层业务系统将其编排到自己的 IT 架构和发布系统之中。

但是 Service Mesh 不是银弹,其架构选择是通过增加部署复杂性(Sidecar)和损失性能(增加两跳),来换取架构的灵活性和系统的可演化性。

为了解决部署复杂性的挑战,社区和云服务商都在共同进行努力:

  • 一方面简化 Service Mesh 自动化运维水平,比如:阿里云通过 Operator 大大简化了 Istio 的升级运维和跨 K8s 集群部署的复杂度。
  • 另一方面提供托管的 Service Mesh 服务,帮助用户关注在业务层面的服务治理而非基础架构实现。

关于性能问题:

  • 一方面 Service Mesh 需要降低自身控制平面和服务平面的性能开销,比如:尽可能 offload mixer 负载,将治理策略执行下沉到数据平面完成;
  • 另一方面还需要重新思考整个通信栈中应用与网络基础设施的边界。

为了实现容器应用之间的互联互通,Kubernetes 社区提出 CNI 网络模型,将容器网络连通性与底层网络实现的进行解耦,同时 K8s 提供了 Service、Ingress、Network policy 等原语来支持应用层的服务通信和访问控制。但是这些能力远不能满足应用对服务治理的需求。

Service Mesh 在 L4/L7 增加了流量管理、全链路可观测性、安全互联等新功能,这些是通过引入运行在用户空间的 Envoy 代理实现的,在提升灵活性的同时也不可避免地增加了性能开销。

为了系统化解决这个问题,社区在进行有趣的探索。比如:在 Cillium 容器网络中,可以利用 eBPF/XDP 等操作系统和底层网络能力,将应用层的服务控制能力,如:Kube-Proxy 提供的 Service、Network policy 下沉到操作系统内核和网络层解决,并优化了 Service Mesh 数据链路,减少上下文切换和数据拷贝,有效地减少了性能开销。

在这里插入图片描述

目前 Service Mesh 技术还处在技术成熟度曲线的初期,除了在 L4/L7 层提供灵活的服务通信功能,社区也在探索通过网络 Service Mesh 实现灵活的 L2/L3 组网能力。我们相信其会成为未来企业分布式应用通信基础设施。

在这个过程中会有一些新的理念和项目被持续创造出来,我们需要能够理性地分析其业务价值和技术局限性。我们要避免将 Service Mesh 作为万灵药,不要将应用集成、应用侧安全等业务逻辑下沉到服务网格中,避免我们重蹈复杂性覆辙。

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付 49.00元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值