作者 | Raphael Do Vale
译者 | 王强
策划 | 冬梅
前言
在讨论服务网格这个话题之前,我们先来谈一谈它的起源。曾几何时,人们开始采用针对多个小型团队和云计算的分布式性质而设计的新生架构,它就是微服务架构。
微服务架构流行之前,软件系统往往设计成一个巨型的单体。但随着软件的持续发展,开发团队也在不断成长,所有开发人员都在使用同一个代码库,令代码的复杂性与日俱增,逐渐失控。进入云计算时代后人们对应用程序提出了新的要求,希望应用具备良好的可扩展能力:既能以很低的成本处理少量请求,也能在流量高峰期迅速扩张,应对大量请求的冲击。
微服务架构将单体分割成众多小型服务,每个服务由一个团队负责,并通过一种通信协议(通常为 REST API)与其他服务共享资源。
但微服务也极大增加了运维的复杂程度,所有平台日志都分布在多个服务中。每个服务在发送消息之前都需要找到自己依赖服务的位置,而且这种方式很容易受到恶意攻击。
接下来,Kubernetes 这样的容器编排器的理念出现了。它们可以管理所有平台服务、它们的版本、新的部署、网络连接以及扩展需求。但它们并不是设计用来解决服务间发现和通信问题的。
于是我们又等到了服务网格(service mesh),其提出了一种更廉价的方式来处理这种运维负担,同时又能继续保留微服务的种种优势。
服务网格之前的世界
微服务架构的问题都集中在它所产生的那些复杂性,因为每个服务都是一个独立的应用程序。它要求持续集成和持续部署配置、发现服务、安全层、网络层和监视层。
在容器化环境中,负责每一个服务的每个团队都可以选择自己独有的开发解决方案,使用自己习惯的编程语言和库。但 IT 部门需要指定一些实践,以尽量减轻这些服务的运维压力。
负载均衡和负载保护(断路器)
微服务,尤其是那些在容器编排平台(如 Kubernetes)上工作的微服务,可以增加或减少其实例数量,以在合理的时间内处理请求数量。因此,如果请求数量增加并且当前数量的实例不能在可预期的时间内响应这些请求,那么容器编排平台将创建新的服务实例。
传入的请求由负载均衡服务处理,其充当所有实例的前置服务,负责选择最合适的实例来满足给定请求。
远程服务的问题在于它们有时可能会失败。实际情况甚至可能变得更糟:例如,如果服务由于超时而失败,而超时又是因为另一个服务正在调用,则前者只能等下去,直到它声明错误为止。然后,由于大量请求被搁置,调用服务可能会耗尽关键资源,并在整个基础架构中造成级联故障。断路器这种模式很简单,一旦发现超时问题,它将向所有其他调用发送错误,以避免超时等待时间。
服务发现
在运行多种服务的情况下,它们的位置是很难被发现的。多个服务之间的依赖关系并没那么容易分得清,新服务可能会以对旧服务的新依赖关系进行部署。这些服务可以部署在基础架构中的任何位置,因此你需要的是服务发现服务。可选项有很多,例如 Netflix Eureka 或 HashiCorp Consul 等。
安全和访问权限
如果服务间的通信未加密,那么外部(有时是恶意的)工具就可以轻易读取各个服务之间传输的所有数据。一般来说,这些服务会运行在同一网络上,于是拦截它们之间的通信也会容易许多。另外,有些服务之间明明不应该通信,可是因为很少有限制服务间通信的措施,这一漏洞就可能被利用,使不该通信的服务被强制通信。
可观察性
一大堆微服务监视起来也要困难得多。由于每种软件都运行的是不同的代码库,因此你必须创建一些监视约定。而且由于微服务的分布式性质,请求跟踪更具挑战性。单个请求可以触发许多服务,因此如果不跟踪它所涉及的所有服务,人们可能就很难搞明白故障到底出在什么位置。——服务跟踪
👉服务网格如何解决这些问题
服务网格可以被看成是专注于过程通信的高吞吐量专用基础架构。服务网格可以管理服务之间的所有通信,轻松实现上述所有功能。
大多数服务网格使用边车模式(Sidecar)解决方案:每个服务旁边都插入一个辅助服务,该辅助服务在应用程序服务和其他服务之间添加一个通信层。这种方案不会依赖特定的库或集成式的平台等特殊技术。在 Kubernetes 环境中边车方案用起来很简单,并且通常不需要更改应用程序。
负载均衡、负载保护和服务发现
现在,每个服务通信操作都由辅助服务处理。在某些解决方案中,必须将应用程序配置为使用网络代理来处理所有程序包。
这些辅助服务可以与其他辅助服务通信,并在多个实例之间提供服务发现和负载均衡功能。除此之外,大多数服务网格解决方案都提供了开箱即用的断路器。
安全和访问权限
Istio 安全性概述
如上图所示,服务网格可以轻松保护通信过程,因为只有需要通信的服务之间才能被允许数据交换,而其他服务的通信请求则会被阻止和报告。专用 SSL 密钥还可以确保系统仅允许授权服务之间的通信。
通过授予访问权限,也可以允许与个体间的通信。
可观察性
现在我们用单个服务来管理所有通信过程,因此在服务之间创建指标和跟踪就容易多了。你无需添加特定于平台的库即可收集各种指标,例如延迟、流量、错误或饱和度等。此外,每个通信都可以具有分布式跟踪功能,因此你可以查看整个集群是如何管理单个请求的。
如今有许多服务网格产品可用。通常,它们可以与 Kubernetes 集成以提供更简洁和安全的微服务部署。Istio 可能是最著名的 Kubernetes 服务网格解决方案,此外还有 NGINX Service Mesh、Linkerd 和 HashiCorp Consul 等。
需要注意,尽管服务网格用起来有许多优点,但我们也要考虑一些问题。服务网格这项技术还是很新,要让所有通信都依赖它来处理是要小心谨慎的。
服务网格还增加了一些计算开销,这可能会增加大型集群的集群成本,此外,由于现在我们必须加密并保护每一个通信,因此它可能会稍微增加服务通信延迟。
下一步
服务网格提出了一种用于处理所有服务通信的标准化方法。服务网格还为你提供了透明的、具有高级安全性并遵循最佳实践的服务间通信途径。
尽管如此,这项技术才刚刚成熟而已。它实在太新了,版本更新可能会带来重大更改。开始使用它之前,请先在测试环境或备份计划中测试一段时间。当你觉得没问题了再考虑下一步,这样就比较稳妥了。
作者介绍:
Raphael Do Vale 在开发企业系统(包括编码、项目规划和规范)方面拥有十多年的经验。他的技术栈涉及 Java、Spring、Python、关系数据库、JavaScript 和 Devops 与 Kubernetes、Docker 和 Puppet。
原文链接:
https://iamondemand.com/blog/what-is-a-service-mesh-and-why-is-it-essential-for-your-kubernetes-deployments/