使用Service Mesh整合您的微服务架构

2018/07/19 19:42
阅读数 3.2K

在微服务架构的世界中,它正在达到这样的程度,即管理系统的复杂性对于利用它带来的好处变得至关重要。

目前,如何实现这些微服务不再是一个问题,因为有很多可用的框架(Spring Boot,Vert.XNodeJs ......)。

也不是,如果我们从考虑如何进行部署,这是一样的工具覆盖的点看泊坞窗KubernetesOpenShift ...现在面临的挑战是在这些微服务本身之间的通信。

 

最初,微服务之间的通信是逐点进行的,每个微服务都提供了“额外的智能” 。这控制了通信的许多重要方面,例如路由,容错,延迟,服务发现,分布式可追溯性,安全性等......,将通信信道留作仅仅是“管道”,通过它旅行的消息。

目前,一些业务流程平台(例如Openshift)已经提供了其中一些方面(例如服务的发现),但它们尚未完全覆盖。然而,当微服务的体积增加及其复杂性时,这种方法是不充分的,甚至变得不太可行。
 

作为所有这些的一个例子,我们有一个微服务开发人员的情况,在执行它时必须考虑到:

  • 服务功能的业务逻辑的实现(计算,服务的组成等)。
  • 网络功能的实现,处理与其他服务的通信机制(应用弹性和稳定性模式,发现服务等)。

考虑到这一点,如果我们考虑用于实施微服务的努力量,我们可以看到,很大一部分时间专门用于构建旨在实现微服务之间通信的这些网络功能。

但是,如果在我们的架构中使用多种技术(和/或多种编程语言)共存的微服务,这也会更加突出,为此,必须在更大或更小的程度上为每种技术做出同样的努力。 / o语言...... 同样,我们还需要对我们的微服务所发生的一切进行更详尽的控制:监控,指标,请求的分布式可追溯性,安全性......这会增加整个系统的复杂性。
 

现在,由于服务之间的大多数通信要求在所有微服务实现中都非常通用,我们可以考虑将所有这些任务下载到不同的层,这样我们就可以保持服务代码的独立性。这是出现“服务网格”(或服务网格)的概念。它带来了一系列特性,这些特性在微服务的实用实现中是必需的,它们直接在基础架构上而不是在代码上解决这种类型的架构模式。
 

换句话说,Service Mesh最终不是向微服务生态系统引入新功能,而是重新定位现有功能

但是......什么是服务网?

一般而言,服务网格可以被视为专用软件基础设施,以处理微服务之间的通信服务网格的主要职责是以可靠,安全和及时的方式将服务A的请求传递给服务B. 从功能的角度来看,这有点类似于ESB的功能,其中异构系统互连用于消息通信。这里的区别在于没有集中式组件,而是分布式组件网络。作为解释,可以在服务网格的功能之间建立类比



和TCP / IP网络堆栈的。在后者中,字节(网络数据包)通过底层物理层从一台计算机传送到另一台计算机,包括路由器,交换机和电缆,能够吸收故障并确保正确传送消息。虽然TCP / IP和服务网格之间存在相似之处,但后者在真实的生产环境中需要更多的功能。以下是良好的服务网格实现所需的功能列表:

 

  • 确保服务之间通信可用性的基本功能:断路模式,重试和超时,错误管理,负载平衡和故障转移......
  • 服务发现:通过专用服务注册表发现服务端点。
  • 路由功能:将请求路由到不同版本的服务......
  • 可观察性:分布式指标,监控,日志记录和可追溯性。
  • 安全性:传输级安全性(TLS)和密钥管理。
  • 认证/授权
  • 部署:对容器的本机支持(Docker,Kubernetes)。
  • 服务间通信协议:HTTP / 1.1,HTTP / 2,gRPC ......

为什么有必要?

当我们有一个分布式应用程序(或者公共或私人),基于由微服务,容器和编排层上(例如OpenShift或Kubernetes)架构* ; 并有数百那些谁站起来,消除基于缩放特定需求的微服务和情况下,遵循的路径由通过业务拓扑一个应用程序可以是极其复杂的。

 这将是最常见的情况,但有可能是其他部署拓扑,不是基于容器和/或编排的层(例如,不同的主机上运行,用HA的更传统的结构不同的服务),其中它也可以使用服务网格解决方案。

复杂性和重要性的组合激发了需要为服务之间的通信采用专用层,从应用程序代码,并能捕捉到基础环境的高度动态性分离,提供的工具转向监控,管理和控制这些沟通。

它是由什么组成的?

在为了进行所有你应该提供的功能服务网格,它是基于实现一些设计模式和分布式已经知道,但而不是将应用它们的代码(如的确是常见的),则执行关于基础设施本身。

但谈到每一个使组件前面了一个服务网,我们将介绍这些模式您使用的一个。我们正在谈论边车模式。在图案车斗,一个主处理(服务)的功能被扩展或通过与它们之间的小链路的“并行”处理改善。
 

该行为类似于代理,其为主进程提供其所需的所有基础“商品”服务(例如,服务发现,断路器等)。当使用Kubernetes作为容器编排平台时,此模式特别有用。在Kubernetes中使用“豆荚”,每个豆荚由一个或多个应用容器组成。因此,边车是吊舱中“实用”的容器,其目的是支撑主容器。重要的是要记住,边车本身是无用的,但必须与一个或多个主要容器结合使用。


 

通常,边车容器是可重复使用的,并且可以与多种类型的主容器组合。

数据平面(数据平面)

想象一组独立服务,其中每个服务都与同一个Kubernetes pod中的代理边车一起部署。

我们还要确保每个服务仅与其自己的代理边车通信,而不是直接相互通信,后者(边线车)最终负责通过其可靠的请求传递可以像我们一样复杂的拓扑或体系结构。

我们可以看到每个服务只与自己的代理边车通信。

让我们的想象更进一步,在心理上,从计划中消除商业服务本身,只需留下一套侧车和它们之间的相互通信方式。

现在我们可以更清楚地看到,结果图表如何表示底层的“连接网格” 

如果消除了业务服务,连接拓扑本身就会成为专利。

那么,这组服务和代理边车(简称为这个网格)被分配了数据平面“ 数据平面”的名称

在高层次上,“数据平面”的责任是确保请求以可靠,安全和及时的方式从微服务A传递到微服务B,负责提供以下功能:

  • 发现服务(服务发现)。
  • 可用性检查(健康检查)。无论是主动检查还是被动检查。
  • 路由和负载平衡:超时,重试,断路器,故障转移......
  • 保护和访问控制(身份验证/授权)。使用TLS,ACL保护通信通道......
  • 可观察性:度量,监控,日志记录和分布式可追溯性......

控制平面(控制平面)

在该另一方面,我们将有最后一块是解决方案,这就是所谓的部分 控制平面控制平面

该元素将负责管理和监督侧柜的所有实例,作为理想的实施调控政策,指标收集,监测点...

它是服务网格正常运行的必要部分。但是,这片没有到是呈现用户界面元素(图形,CLI ...),但可能连经理亲自负责作为控制平面和执行车斗和其他配置参数配置平台(虽然看起来很明显,但这是不可取的)。

我们可以看到数据平面和控制平面之间的连接。

另一个重点是服务网格可以在应用程序层级工作,而不仅仅是网络层

这意味着它可以获得有关请求的更详细信息,例如能够区分以错误500或404结束的请求(这在网络层级别是不可能的)。

通过这种方式,您可以将这些信息用于不同的区域(可追溯性,健康检查......)。

尽管上面提到的功能是通过代理边车在数据平面内提供的。这些功能的全局配置在控制平面内完成。控制平面使所有代理边车都没有状态,并将它们转换为分布式系统。

如果此时我们回到TCP / IP堆栈的类比,我们可以说控制平面类似于交换机和路由器的配置,以便TCP / IP在它们之上正常工作。

因此,在服务网格中,控制平面负责配置代理边车网络。控制平面的功能包括配置:

  • 路由。
  • 负载均衡
  • 断路器,重试策略,超时......
  • 部署。
  • 发现服务。

总结:

  • 数据平面:触摸每个包/系统请求。负责发现服务,健康检查,路由,负载平衡,安全性和可观察性。
  • 控制平面:为现有数据中的所有级别策略和配置服务网。请勿触摸系统中的任何包装/请求。控制平面将所有数据平面转换为分布式系统。

部署模式

我们可以为服务网格建立两种可能的部署模式

  • 基于每个主机的一个代理的部署模式。
  • 基于代理边车的仓库模式。

基于每个主机的一个代理的部署模式

在这种类型的部署中,一个代理被部署为每个主机,这是虚拟机或物理主机或工作节点Kubernetes。

在此类型中,多个应用程序服务实例在同一主机上运行,​​并且所有实例都通过同一代理实例路由流量。

对于Kubernetes,代理实例可以显示为守护进程。

在这种类型的部署中,服务A,B,C通过其相应的代理实例相互通信。在每个主机中,运行A,B,C的多个实例。

边车代理的部署模式

在此模式中,为每个服务的每个实例部署一个边车代理。此模型对于使用容器或Kubernetes的部署非常有用。

在后一种情况下,sidecar-proxy容器可以与应用程序服务容器一起部署,作为Kubernetes pod的一部分。

显然,这种类型的部署需要更多的边车实例,因此,侧车的较小资源配置通常是合适的。

如果资源配置文件有问题,您可以将服务网格实例部署为daemoset,这会将服务网格容器的数量减少到每个主机一个,而不是每个pod一个。

在这种类型的部署中,服务A,B,C通过它们自己的边车代理实例相互通信。

动态路由请求

服务网格实现中,请求的动态路由允许将请求从路由规则路由到特定环境(dev,stag,prod)中的特定服务版本(v1,v2,v3)。

这种类型的动态路由规则的实际实现可能因不同的服务网格框架而异。

即便如此,基本机制仍然相同:源服务向目标服务发出请求; 目标服务的确切版本由服务网格根据建立的路由规则确定。

这种类型的动态路由还有助于在常见部署方案中进行流量切换,例如Blue-Green部署,Canary部署,A / B测试等。

在这种情况下,服务网格根据路由规则动态确定目标服务版本。接下来,它控制到两个不同版本的目标服务的路由请求的百分比,允许流量以递增方式移动和控制。

部署服务网格

目前有不同类型的服务网格解决方案,例如Nelson ,它使用Envoy作为其代理边车并使用Hashicorp 堆栈构建强大的控制平面(例如:NomadConsulVault ......)。

此外,Smartstack HAProxyNGINX以及其他元素(如NerveSynapseZookeeper)周围创建了一个控制平面,同时也证明了可以解耦控制平面和数据平面。另一方面,Linkerd Istio 是目前最流行的两种开放式网状开源实现。两者都遵循类似的架构,但不同的实现机制。
 

但是,我们不能忽视Conduit (仍然是实验性的),这是实施Linkerd的Kubernetes 的超轻服务网格

Istio vs Linkerd

由于Istio Linkerd 是两种最流行的实现服务网今天,让我们做一个小小的比较:

什么时候应该使用?

在微服务,容器和业务流程层汇聚的架构解决方案中(例如Kubernetes或Openshift),强烈建议包括服务网格提供的功能来管理微服务之间的通信。

使用的义务变得如果微服务更明显,因为发生在这样的体系结构是多种语言。也就是说,它们将用不同的框架和/或编程语言实现。

它也建议 ,以评估包括的可能性网格服务时,尽管有架构微服务,这是不是部署在一个平台上的业务流程(如Kubernetes),但在这种情况下,几个微服务进行分组,以在运行或多台机器(物理或虚拟),不以集中方式管理。

在这种情况下,您可以选择遵循每个主机一个代理模式的服务网格部署模型。但是,在微服务数量相对较少的解决方案中,如果所有这些服务都使用相同的框架(例如Spring Cloud)实现,那么它提供了面对已经提到的服务之间的通信需求的机制。 ,可能不会考虑使用服务网格层。
 

在这种情况下,我们必须意识到开发人员必须负责将这些功能手动或使用库和/或第三方组件包含在服务本身中。

举一个具体的例子,在使用Spring Cloud的微服务架构中,为了提供服务发现功能,没有必要在Eureka客户端中包含依赖项。

也不是拥有Eureka服务器本身,而这将与Spring Cloud提供的其他功能一起发生,例如Ribbon,Zuul ......

结论

一个服务网点解决了一些关于microservicio的结构实现的关键挑战。但与许多其他情况一样,使用新型解决方案会带来许多利弊,在处理它们时必须始终考虑到这些利弊:

优点

  • 基本网络功能在微服务代码之外实现,并且可以重复使用。发现服务,失败管理......
  • 它解决了微服务架构的大多数问题, 其中ad-hoc解决方案曾经是:可追溯性和分布式日志记录,安全性,访问控制等。
  • 在选择微服务实现语言时,它提供了更多的自由 。您不必担心特定语言是否具有或支持库来构建网络应用程序功能。
  • 它提供智能路由机制。当添加新服务部署策略(逐步引入的一个新版本,部署蓝/绿或淡黄色),和/或进行测试(如测试A / B),它们可以是非常有用的...

缺点

  • 复杂性增加。拥有服务网格会大大增加给定微服务实现中存在的运行实例的数量。
  • 潜在故障点的增加,源于需要执行其他组件。与现有的(微服务)一样,它们可能存在不可用的特定问题,但是由于这些故障可能影响整个网格或其部分功能的加重情况。因此,我们可以很好地选择服务网格的拓扑结构,并确保其弹性
  • 由于服务之间的额外中断(通过服务网格的代理边界制作的中断)的聚合而导致的延迟增加 
  • 不成熟。科技服务网是比较新的被宣布为一个完整的解决方案。

还应该明确的是,这种方法可以解决服务之间的常见通信问题。

但它并不解决其他问题的复杂请求路由,转换和映射类型,或者整合其他服务和系统,这需要由microservicio(例如业务逻辑来解决的机制使用集成框架,如Conductor,Apache Camel或Spring Integration)。

来源和参考资料

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部