WePay为什么选择Linkerd作为服务网格代理?


【编者的话】本文是WePay工程团队服务网格系列文章的第一篇,在这篇文章里,作者对比了服务网格代理可能的选型方案,并最终选择了Linkerd。

在接下来的几个月里,我们将会编写一系列的文章,记录WePay工程团队从传统的负载均衡迁移到Google Kubernetes Engine(GKE)上的服务网络的历程。

在本系列的第一部分里,我们不妨一起来看看之前使用过的一些路由和负载均衡方案,把它们和我们看过的可能作为服务网格代理的服务做个对比,以及它们是如何改变我们基础设施的操作模式。
image_0.png

图1:使用sidecar代理模式的数据面板

图1展示了一个数据面板的简化版,这是服务网格里的术语,其中服务X通过它的sidecar代理向服务Y发送请求。由于服务X是通过它的代理发送请求,因此请求将首先传递给服务X的代理(PX),然后再到达本次请求的目的地,服务Y之前会先发送给服务Y的代理(PY)。在大多数情况下,PX会通过一个服务发现的服务找到PY,例如Namerd

我们关于gRPC的演讲会介绍到使用这种模式来代理负载均衡。

在这篇文章中,为了简单起见,我们将会把重点放在数据面板上,再者,为了进一步简化,我们将只讨论使用sidecar模式的代理。

旁注:本文中提到的所有技术都是一些非常复杂的软件,它们是由一些天才工程师编写然后开源,供其他存在类似场景的公司使用。下面的对比完全是基于WePay的用例场景,针对这些用例,哪种技术最适用,但是这并不代表不能使用其他技术。

搭建舞台

在WePay,我们目前在GKE中运行许多微服务(Sx)。 其中一些微服务与同一数据中心的其他微服务进行通信,如下图所示:
image_1.png

图2:使用GKE和NGINX的简单负载均衡

在图2所示的模型中,服务Y向服务X发送了一个请求,Kubernetes的负载均衡对象通过将请求转发给X1的NGINX sidecar的方式为服务X提供负载均衡。当NGINX收到请求时,它会终止SSL并将数据包转发给X1。

在过去一年左右的时间里,随着在基础设施运行的微服务数量的不断增长,事实证明,下面这些问题对我们来说非常重要,而且在某些方面,也是促使我们转向服务网格的动机:
  • 更加智能,更高性能和并发的负载均衡
  • 平台和协议无关的路由,要求支持HTTP和HTTP/2(重点关注gRPC)
  • 面向应用程序独立的路由和跟踪指标
  • 传输安全性


我们开始意识到,我们想要的是一个服务网格式的基础架构,随即我们便开始调研各种不同的代理,用来构建我们的数据面板。从列表中可以看到,EnvoyLinkerd看起来最接近我们的需求,同时也提供了一套成熟的功能集。

旁注:在我们调研时,NGINX还没有支持服务网格,但是为了支持服务网格式的基础设施,NGINX如今已经增加了对Istio的支持。为了能够进行对比,这里我们把Envoy和NGINX算作同一类产品。

更出色的负载均衡

EnvoyLinkerd均有提供一些更复杂的负载均衡算法,但是Linkerd更注重于性能调优,而且得益于Finagle的平台,这使得它成为负载均衡方案里的一个有力竞争。
image_2.png

图3:sidecar代理模式处理负载均衡

图3展示了服务网格代理如何通过服务发现获取的可用目标列表来处理负载均衡。

除了基本的负载均衡功能外,通过支持Kubernetes DaemonSets的部署模式,Linkerd还允许将负载均衡推向更靠近每个Kubernetes节点的边缘。从资源分配的角度来看,这也显著降低了在较大集群中运行代理的成本。
image_3.png

图4:DaemonSet代理模式

在图4中,DaemonSet方案展示了在每个Kubernetes集群节点上托管一个代理的模式。当服务Y向服务Z发送请求时,请求被转递给发送者的节点代理,这里会用到服务发现,它将请求转发到接收者的节点代理,并最终将包发送到服务Z。这种模式将代理的生命周期与在同一集群中运行的微服务分离,维护和配置这些代理变得更加轻松。

新的协议,不变的基础设施

回到2017年,在我们考虑改进gRPC服务之间的通信时,Linkerd支持了开箱即用的HTTP/2和gRPC,迁移到使用Linkerd的服务网格变得更加轻松。

此外,要求任何微服务能够同时使用HTTP和HTTP/2(gRPC)两种协议,并且需要在我们的基础架构中同时支持多种协议,这就意味着多协议的支持已经成为我们的基础设施选择代理的硬性规定……
image_4.png

图5:同样的设定下代理接收和转发gRPC和HTTP请求

上图展示了某些请求使用HTTP而其他请求使用HTTP/2的情况。当我们计划从HTTP迁移到HTTP/2(gRPC)时,能够在相同的基础设施配置中使用多种协议被证明是一个关键特性。在迁移期间,我们有一些服务通过HTTP相互通信,而其他服务通过HTTP/2通信。图5描绘了随着时间演变的基础设施。在后续的文章中,我们将深入探讨我们的微服务是如何在我们的基础架构中发送和接收不同类型的负载,例如:REST,Protobufs等。

今天,大多数服务网格代理,包括Envoy,都已经支持处理最新的协议,比如HTTP,HTTP/2和其他协议等。

我可以看到指标

在我们的基础设施中,我们使用Prometheus来监控Kubernetes,微服务及其他内部服务。Envoy需要一个额外的步骤来对接Prometheus,但是使用Linkerd的话,它提供了一个开箱即用的Prometheus监测插件,对我们来说更加轻松,我们可以直接用上这些监控图表,无需配置额外的服务将服务网格代理整合到我们的可视化看板:
image_5.png

image_6.png

图6:在集群和应用层面视图下的代理指标

图6中的示例看板在一处地方展示了全局的,每个微服务以及每个代理的流量,以便在DaemonSet代理模式下能够更好地了解基础设施的运行情况。

使用Linkerd的另一个方便之处在于代理自带了开箱即用的指标范围。此外,Linkerd还支持编写自定义的插件来简化控制的复杂度,举个例子,使用这些自定义指标的重试机制。因此,任何特定的指标,告警和监控都可以进行改造,以满足基础设施运转服务网格的需求。

做好准备,安全就是这样

现如今大多数代理均支持各种代理之间的加密和授权方法,当我们使用的是Linkerd的sidecar模式时,我们甚至可以更进一步。使用sidecar模式的话,我们能够在Linkerd中执行以服务为单位的授权,这使得我们无论何时何地均能让基础设施的安全性得到最大化的保障。

在一个sidecar代理模式的环境设定中有一个不同之处,那便是SSL握手也是每个服务一份TLS证书。
image_7.png

图7:以服务为单位的用于SSL握手的TLS证书

图7展示了一个服务Z的Linkerd代理在向服务X发送请求时使用服务X的证书,当请求服务Y时则用的是服务Y的证书。这使得我们能够相对独立的维护,更新和修改每个服务的SSL证书,也提升了微服务的安全性。

某些场景下这个功能可能很有用,但是对于其他一些场景可能又有点过,所以能够从中挑选出一个这一点挺不错的。

小结

基于基础设施的需求和改进,针对我们的技术栈,我们选择了Linkerd。

使用Linkerd的话,我们可以赢得我们需要的可靠性,为我们的微服务所使用的基础设施引入新的协议,更好地了解服务流量的情况,而且可以在适当的时候做安全方面的调整。

在本系列的后续文章里,我们将讨论服务网格架构的各个部分,以及它们是如何推广到WePay的架构。

原文链接:Using Linkerd as a Service Mesh Proxy at WePay(译者:吴佳兴)

0 个评论

要回复文章请先登录注册