比较服务网格体系结构

如果你正在围绕微服务构建您的软件和团队,那么你应该正在寻找更快迭代和灵活扩展的方法。服务网格可以帮助你在保持(或增强)可见性和控制的同时实现这一点。在这篇博客中,我将讨论服务网格中的实际内容以及您在选择和部署服务网格时可能需要考虑的事项。

那么,什么是服务网格呢?它和你的堆栈中的内容有什么不同呢?服务网格是一个通信层,它在请求/响应之上,解锁了一些健康微服务所必需的模式。我最喜欢的几个:

  • 不假定可信任外围的零信任安全
  • 跟踪显示每个微服务如何以及为什么与另一个微服务通信
  • 错误注入和容错,让你可以通过实验验证应用程序的弹性
  • 高级路由,可以让你执行诸如A / B测试,快速版本控制和部署以及请求镜像等操作

为什么是新的术语?

看到这个列表,你可能会想:“我可以在没有服务网格的情况下完成所有这些内容”,而且你是对的。相同的逻辑适用于滑动窗口协议或请求框架。但是一旦有一个新兴的标准可以满足你的要求,那么依赖这个层而不是自己实现它会更有效。服务网格是微服务模式的新兴层。

服务网格还处于初级阶段,编码标准尚未出现,但是有足够的经验表明一些最佳实践开始变得清晰。当最前沿的领导者开发他们自己的方法时,交换意见和提炼最佳实践通常是有用的。我们已经看到Kubernetes成为运行生产Web应用程序容器的标准方法。我最喜欢的标准是紧急而非强制的:就通用的API,协议和概念达成一致,这绝对是一种很好的艺术。

想想计算机网络的历史。在尽力而为的分组交换网络的创新之后,我们发现我们中的许多人正在通过它们创建虚拟电路 —— 使用握手,重传输和网际互联将一堆数据包变成有序的字节流。为了实现互操作性和简单性,出现了一种“最佳实践”流式数据包:TCP(RFC675的引入很好地解释了它上面的层)。还有其他选择 - 我在空间网络中使用了Licklider传输协议,因为分布式拥塞控制既不必要也不高效。你的浏览器可能已经在使用QUIC(基于UDP互联网传输层协议)。然而,标准化TCP却让一代程序员摆脱了对滑动窗口、重试和拥塞崩溃实现的操作(除了那些实现它的包头)。

接下来,我们发现了很多在TCP之上运行的请求/响应协议。其中许多最终迁移到HTTP(或像HTTP / 2或gRPC这样的协议)。如果你可以将通信因素分解为“方法,元数据,主体”,那么你应该查看类似HTTP的协议来管理框架,将元数据从主体中分离出来并解决线头阻塞问题。这不仅局限于浏览器应用 —— 像Mongo这样的数据库也提供HTTP接口,因为无处不在的HTTP解锁了大量的工具和开发知识。

您可以将服务网格视为围绕微服务的下一层通信模式的词典,API和实现。

好的,那么这一层位于哪里呢?你有几个选择:

  • 在你的微服务应用程序导入和使用的中。
  • 在为特定节点/机器上的所有容器提供服务的节点代理程序或守护程序中。
  • 在与应用程序容器一起运行的Sidecar容器中。

库方法是最初的方法,它简单而直接。在这种情况下,每个微服务应用程序都包含实现服务网格功能的库代码。像HystrixRibbon这样的库就是这种方法的例子。

这对于那些运行团队只用一种语言编写的应用程序来说非常有效(因为很容易插入库)。库方法也不需要底层基础架构的太多合作 -——容器运行者(如Kubernetes)不需要知道你正在运行一个Hystrix增强型应用程序。

在多语言库中有一些工作(重复实现相同的概念),这里面临的挑战是一遍又一遍复制相同行为的复杂性和工作量。

我们看到在我们的用户库中对库模型的采用非常有限,因为我们的大多数用户正在运行使用多种不同语言(polyglot)编写的应用程序,并且还在运行至少几个不是他们编写的应用程序,因此注入库是不可行的。

这个模型在工作核算方面有一个优势:代表微服务执行工作的代码实际上正在该微服务中运行。该信任边界也很小,你只需要信任调用自己的进程库,而不必在网络之外的某个地方使用远程服务。该代码的特权仅与它代表其执行工作的微服务相同。这项工作也是在微服务环境中执行的,所以很容易公平地分配CPU时间或内存等资源 —— 操作系统可能会为你这样做。

节点代理

节点代理模型是下一个选择。在此体系结构中,每个节点上都有一个独立的代理(通常是用户空间进程),为不同的工作负载提供服务。为了进行比较,它与库模型相反:它不关心应用程序的语言,但它为许多不同的微服务租户提供服务。

Linkerd推荐的Kubernetes部署就像这样。F5的应用服务代理(ASP)和Kubernetes默认kube-proxy一样。

由于每个节点上都需要一个节点代理,因此此部署需要基础架构进行一些合作。如果没有一点协调,此模型就无法正常工作。通过类推,大多数应用程序不能只选择自己的TCP堆栈,猜测一个短暂的端口号,并直接发送或接收TCP数据包,它们将其委托给基础架构(操作系统)。

这种模式不是强调工作核算,而是强调工作资源共享。如果节点代理为我的微服务分配了一些内存来缓冲数据,那么它可能会在几秒钟内转向,并将该缓冲区用于服务的数据。这可能非常有效,但是存在滥用的途径。如果我的微服务要求所有缓冲区空间,那么节点代理需要确保它首先为缓冲区空间提供一个机会。你需要更多的代码来管理每个共享资源。

从共享中受益的另一个工作资源是配置信息。将配置的一个副本分发到每个节点比向每个节点上的每个pod分发一个配置副本要便宜。

集装箱化微服务所依赖的许多功能由节点代理或类似的拓扑提供。想想kubelet初始化你的pod,你最喜欢的CNI守护进程,比如flanneld,或者扩展你的大脑,甚至操作系统内核本身也遵循这个节点代理模型。

Sidecar

Sidecar是这个领域的新人。这是Istio与Envoy一起使用的模型。导管也使用边车方法。在Sidecar部署中,为每个应用程序容器部署一个相邻的容器。对于服务网格,边车处理应用程序容器内外的所有网络通信。

这种方法介于库方法和节点代理方法之间,这是我迄今为止讨论的许多折衷方案的一种。例如,你可以部署边车服务网格,而无需在每个节点上运行新的代理程序(这样你不需要在整个基础架构范围内合作来部署该共享代理程序),但是你将运行同一辆边车的多个副本。另一个解决方案是:我可以为一组微服务安装一个服务网格,你可以安装另一个服务网格,并且(有一些特定于实现的注意事项)我们不必协调。这在服务网格初期非常强大,你和我可能会共享相同的Kubernetes集群,但有不同的目标,需要不同的特性集,对最前沿的和可靠的有不同的容忍度。

Sidecar有利于工作核算,特别是在某些安全相关方面。下面是一个例子:假设我使用服务网格来提供零信任风格的安全性。我希望服务网格以加密方式验证连接的两端(客户端和服务器)。我们首先考虑使用节点代理:当我的pod想要成为另一个服务器pod的客户端时,节点代理将代表我的pod进行身份验证。节点代理也在服务其他pod,所以它必须小心,另一个pod不能欺骗它代表我的pod进行身份验证。如果我们考虑sidecar,我的pod的sidecar不会服务于其它的pod。我们可以遵循最小特权的原则,并且为它提供的身份验证密钥,内存和网络功能方面的最小特权提供最低限度的支持。所以,从侧面来看,sidecar与它所附带的应用程序具有相同的特权。另一方面,sidecar需要介于应用程序和外部之间。这会产生一些安全性问题:你希望sidecar尽可能少的特权,但是你需要给它足够的权限来控制应用程序的流量。例如,在Istio中,负责设置Sidecar的init容器当前具有NET_ADMIN权限(以设置必要的iptables规则)。该初始化使用了良好的安全实践——它执行所需的最小数量,然后退出,但是NET_ADMIN中的所有内容都表示攻击面。(好消息——聪明的人正在努力进一步加强这一点)。

一旦Sidecar连接到应用程序,从安全角度来看,它是非常接近的。不像进程中的函数调用(如库)那么接近,但通常比调用多租户节点代理更接近。当在Kubernetes中使用Istio时,您的应用程序容器通过与pod共享的网络名称空间内的回环接口与sidecar进行对话——因此其他pod和节点代理通常无法看到这种通信。

大多数Kubernetes集群每个节点有多个pod(因此每个节点有多个sidecar)。如果每辆边车需要知道“整个配置”(无论对于您的环境而言意味着什么),那么您将需要更多带宽来分发该配置(以及更多内存来存储它的副本)。因此,限制每个sidecar的配置范围是非常有用的——但同样有一个相反的紧张关系:某些东西(在Istio的例子中的Pilot)必须花费更多的精力计算减少每个sidecar的配置。

碰巧在sidecar上复制的其他事情也会产生类似的账单。好消息是,当容器磁盘映像是相同的并且您正在使用正确的驱动程序时,容器运行时将重用这些映像,因此在许多情况下,磁盘开销不是特别重要,并且像代码页这样的内存也常常可以共享。但是每个sidecar的特定过程记忆对于sidecar来说都是独一无二的,所以保持这种控制是很重要的,并且避免在每个sidecar中做大量的复制工作,从而使你的sidecar成为“重量级”。

依赖于sidecar的服务网格提供了完整的特性集和轻量级内存占用之间的良好平衡

节点代理或Sidecar模型是否适用?

我想你可能会同时看到这两个。现在似乎是sidecar服务网格的最佳时机:新技术、快速迭代和逐步采用。随着服务网格的成熟和变化速度的降低,我们将看到节点代理模型的更多应用。

随着服务网格实现成熟和集群变大,节点代理模型的优势尤其重要:

  • 更少的开销(特别是内存),可以在节点之间共享。
  • 易于扩展配置信息的分布。
  • 构建良好的节点代理可以有效地将资源从服务一个应用程序转移到另一个应用程序。

Sidecar是向应用程序提供服务的新颖方式(如高级通信代理服务网格)。它特别适用于容器和Kubernetes。它的一些最大优点包括:

  • 无需中央协调即可逐步添加到现有群集。
  • 为应用程序执行的工作被计入该应用程序。
  • 应用程序到sidecar通信比应用程序到代理更容易保护。

下一步是什么?

正如Shawn在他的文章中谈到的那样,我们一直在思考几年来微服务如何改变网络基础设施的需求。对Istio的支持和理解的膨胀向我们证明,有一个社区已经准备好开发和合并策略规范,并提供了一个体系结构良好的方案。

Istio正在推进最先进的微服务通信,我们很高兴能帮助这项技术易于操作、可靠,并且非常适合你的团队在私有云、公共云或混合云中的工作流程。

本文的版权归 Aaroncang 所有,如需转载请联系作者。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java进阶架构师

「架构技术专题」超详细网站伸缩性架构的设计(7)

使用服务器集群,即将相同服务部署在多台服务器上构成一个集群整体对外提供服务。具体来说,集群伸缩性又分为应用服务器集群伸缩性和数据服务器集群伸缩性。这两种集群对于...

1032
来自专栏*坤的Blog

提高效率

842
来自专栏恰同学骚年

《大型网站技术架构》读书笔记之六:永无止境之网站的伸缩性架构

此篇已收录至《大型网站技术架构》读书笔记系列目录贴,点击访问该目录可获取更多内容。

622
来自专栏搜云库

分布式和集群区别?什么是云计算平台?分布式的应用场景?

分布式是指将一个业务拆分不同的子业务,分布在不同的机器上执行,集群是指多台服务器集中在一起,实现同一业务,可以视为一台计算机,一个云计算平台,就是通过一套软件系...

33210
来自专栏数据派THU

独家 | 教你用Scrapy建立你自己的数据集(附视频)

原文标题:Using Scrapy to Build your Own Dataset 作者:Michael Galarnyk 翻译:李清扬 全文校对:丁楠雅...

2018
来自专栏携程技术中心

[技术分享]携程App的网络性能优化实践

在4月23日~25日举行的QCon全球软件开发大会(北京站)上,携程技术中心无线开发总监陈浩然分享了《移动开发网络性能优化实践》,总结了携程在App网络性能优化...

23310
来自专栏SDNLAB

SDN世界里,网工需要哪些技能?

网络工程师需要学习新技能和使用自动化工具才能适应软件定义网络(SDN)的工作环境。 听起来似乎很难,但是网络工程师都很聪明。我们往往必须处理一些大型复杂网络,它...

3368
来自专栏社区的朋友们

漫谈分布式集群的负载均衡—口水篇

为了理解分布式集群这个概念,我们先说说这两个概念:“集群”和“分布式”。艺术来源于生活,计算机科学亦是如此。

8940
来自专栏顾宇的研习笔记

AWS 上的生产环境架构优化案例

在AWS 上的生产环境性能分析案例一文中,记录了我对客户应用生产环境的一次性能分析。接下来,我们要根据所发现的性能问题进行架构优化,以提升可用性和性能。同时,这...

781
来自专栏java思维导图

我的学习、归纳方法(以学习 Maven 为例)

本文 Markdown 源文件地址 转载请注明出处:https://github.com/judasn/hexo-blog/blob/master/2016/0...

2787

扫码关注云+社区