Istio服务网格高级流量镜像,7种模式解决流量镜像难题

Posted ServiceMesh中文网

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Istio服务网格高级流量镜像,7种模式解决流量镜像难题相关的知识,希望对你有一定的参考价值。


翻译:吕德路 (https://github.com/lvdelu)

原文:Advanced Traffic-shadowing Patterns for Microservices With Istio Service Mesh



导言:


微服务可以加快系统开发速度和降低时间成本(注1)。然而,不能天真地认为只进行快速开发和变更就足够了(注2)。


如何在微服务中降低开发和变更的风险,Istio Service Mesh 提供了一种有助于降低将变更带入生产风险的方法,即将生产流量镜像到测试群集或软件的新版本中,并在我们引导实时流量之前针对问题进行测试


这使我们能够将实际的用例和模糊的使用情况发送到我们的代码中,而我们在非生产模拟中的测试可能不会被捕获到。


在我以前的文章中,我写了关于 Istio Service Mesh 有一个非常棒的功能对流量进行镜像(注3)。对于 Istio 和 Service Mesh,我确实有很多话要说(注4),所以请随时关注@christianposta(注5)参与并保持查看最新的文章。


今天的主要课程是:




流量镜像的难题


当我们将生产流量镜像到测试集群、或生产中的灰度集群时,我们将会面临一些挑战。


首先,


如何在不影响生产服务关键路径的情况下获得生产集群的流量?

是否需要过滤掉这些请求中的个人信息?

如何让测试集群不干扰实时协作者服务?

如果服务对数据进行了更改,如何隔离这些更改而不影响生产服务?


这些都是真正的挑战,或许会被用作不尝试流量镜像的理由。但恕我直言,镜像代表了安全发布中更重要、更强大的技术之一,所以让我们看看有哪些模式来解决这些问题。如下所示:


  • 在不影响生产关键路径的前提下将生产流量镜像到测试集群

  • 将流量定义为流量镜像

  • 镜像之后的实时服务流量与测试群集流量对比

  • 为某些测试配置文件提供协作服务

  • 合成事务

  • 虚拟化测试集群的数据库

  • 实现测试集群的数据库


让我们继续深入研究。




在不影响生产关键路径的前提下将生产流量镜像到测试集群


这可以说是最重要的部分。如果,在不影响生产流量的情况下,不能可靠地将流量镜像到测试群集,那么就应该停止。 不能为我们的“奇思妙想”牺牲生产的可靠性和可用性。 


通常我们会使用代理来镜像此流量。 Envoy Proxy(注6)是一个可用于此操作的代理。 Istio 是一种服务网格,它使用 Envoy 作为启用此功能的默认代理。有关更多信息,请参阅 Istio 镜像任务。


 所以基本上,服务网格(Istio)已经位于我们生产流量的关键路径,以实现弹性,安全性,策略规划,路由控制等之间,并且还可以将流量镜像到我们的测试集群。 


事实上,这就是我在上一篇博客中深入探讨的内容(注7)。 重要的是来自生产中的流量通过带外数据被异步镜像。 任何响应都会被忽略。



对于熟悉所谓“企业集成模式”的读者(谢谢 Gregor Hohpe!),你会注意到这种“镜像”的东西实际上是一种 flavor 或 EIP(注8)。





将流量定义为流量镜像


另一个重要的考虑是识别我们已经镜像的流量。 我们需要能够辨别出用于测试目的的实时生产流量。 使用 Istio / Envoy 时,被镜像的的流量会自动用额外的上下文进行标记。


例如,当 Istio 镜像流量时,它会追加(注9)-shdow 到主机或者权限头中。 对于某些实现来说,目前这是一个问题,因-shadow将被添加到主机的末尾,所以 foobar:8080 的 Host 头将以这样的头部结尾:foobar:8080-shadow,这在技术上并非有效 HTTP 1.X。


在 Envoy 中使用此修复程序后(注10),-shadow 后缀将被添加到主机名,以便 foobar:8080 变成 foobar-shadow:8080。

Istio服务网格高级流量镜像,7种模式解决流量镜像难题





镜像之后的实时服务流量与测试群集流量对比


一旦依赖流量镜像就可以做一些有趣的事情,也许我们希望通过进入测试集群的流量和我们从生产实时看到的期望行为进行对比。


例如,我们可能希望将预期的请求结果或API合同中任何偏离的请求结果与向前和向后兼容性进行比较。我们可以插入一个负责这种类型的流量协调的代理,以及一个可以进行有趣比较的代理。Twitter Diffy(注11)是这些代理中的一个,它已经在 Twitter 应用到了生产(注12),并且其它地方也将会这么做。它基本上需要镜像流量(感谢 Istio 和 Envoy,我们已经做到了这一点),并调用实时服务和新服务并比较结果。它能够检测结果中的 “noise” 并忽略它(时间戳,单调增加计数器等),通过首先调用两个实时服务实例来检测 “noise",然后忽略那些用于测试服务调用的部分。


Istio服务网格高级流量镜像,7种模式解决流量镜像难题


Diffy 还有一个非常棒的网页/仪表板,用于查看调用结果,它们的差异以及基于特定特征的过滤。 最后,Diffy 有一个很好的管理控制台,用于查看关于调用比较的指标和统计数据。


Istio服务网格高级流量镜像,7种模式解决流量镜像难题


我在这里有一个演示(注13),非常感谢 Prashant Khanduri,Puneet Khanduri 和 Alex Soto。 在我制作过程中,留意观看此演示视频。





为某些测试配置文件提供协作服务


当我们部署一个新版本的服务并将流量镜像到测试集群时,我们需要注意对其他环境的影响。我们的服务通常需要与其他服务协作(查询数据,更新数据等)。如果与其他服务的协作仅仅是读取或 GET 请求,并且这些协作者能够承担额外的负载,这可能不成问题。但是,如果我们的服务在我们的协作者中改变了数据,我们需要确保这些调用指向测试流量而不是真正的生产流量。你可以为你的部署创建不同的安装配置,从而注入这些配置。


例如,我们注入了 test.prod.com,而不是 live.prod.com 作为下游服务。如果在 Kubernetes上部署,则可以使用不同的 maps(注14)配置来控制此功能。


另一个有趣的方法是使用诸如 Hoverfly(注15)或 Microcks(注16)之类的东西部署虚拟化测试流量。使用这些服务虚拟化工具,你可以策划预期的请求/响应对,并将值发生变化的流量导向这些返回预期响应的代理。


Istio服务网格高级流量镜像,7种模式解决流量镜像难题





合成事务


在很多情况下,我们服务的新版本需要改变其本地数据存储中的数据。它可能会向协作者服务发出调用来改变数据,但也许我们不能(或不应该)使用先前的技术(服务虚拟化)来存储这些调用。


另一种方法是更明确地通过调用(比如在我们之前添加的镜像模式中我们添加了-shadow)来表明这些请求应该再一个“合成事务”结果中,即,这些不是真正的事务,并且再它们在请求结束时应该采取任何补偿来撤消他们。我们可以为我们的请求添加一个头文件,或者甚至可以使其成为请求主体的一部分,以表明某个事务是“合成的”。当我们这样做时,我们正在指示参与服务正常处理请求,包括所有数据操作,然后在提交之前回滚事务。请注意,这适用于事务性数据存储,但可能不适用于其他数据存储。在这些情况下,如果你已经有工作单元的概念,则可以将合成语义附加到该语义上。否则,最好不要试图通过合成事务来隔离和放弃更改。  


Istio服务网格高级流量镜像,7种模式解决流量镜像难题

这种方法对于执行全路径请求很有用,包括数据存储,获得更好的时序保真度和双测试方法可能捕捉不到的数据干扰/不匹配问题。


这种方法的一大缺点是它按惯例实施,难以执行。 它可能与你拥有和控制的服务一起工作,但可能无法扩展到许多参与协作的合作者。 你不愿意试图在所有服务中强制执行这个约定,并且有一个单独的服务不能正确地实现这个回滚功能,然后把所有的东西混淆起来。 在严格控制和协调部署中使用此模式。





虚拟化测试集群的数据库


在针对镜像流量进行测试时,我们已经开始涉及与处理数据相关的问题。通常,如果你的测试集群使用数据存储,并且测试服务以某种形式更新/插入/变更数据,则需要隔离这些更改。当用信头或嵌入式标志等信号发送时,我们只是简单地回滚任何更改,但这并不总是个办法。


在镜像流量时处理数据问题的另一种方法是为测试群集使用可替代的数据存储。你可以使用一个空的数据存储并使用测试数据填充它,并针对该数据运行镜像流量。但是,如果你使用的是像 Diffy(上面提到的)之类的东西,则可能会在响应比较中收到大量误报,因为测试群集中的数据正在使用测试数据,而实时服务正在使用生产数据。处理这个问题的一个好方法就是虚拟化数据层。我们让测试集群使用一个与生产数据存储相同数据的数据存储。


Istio服务网格高级流量镜像,7种模式解决流量镜像难题

当我们这样做时,我们可以获得生产数据的当前一致视图,也可以在不影响生产数据存储的情况下写入数据存储。 我们可以使用像 JBoss Teiid(注17)这样的工具轻松完成此操作。 Teiid 为所有类型的数据存储系统提供连接器,包括 RDBMS,No-SQL 系统,平面文件,hadoop,salesforce 等,并且可以为我们的测试集群虚拟化它们。 当你这样做时,任何时候变更的数据可以一次性写入数据库而服务无感知。 我有一系列博客讨论了这篇关于微服务迁移的博客文章(注18)。





实现测试集群的数据库


最后,另一种扩展先前数据虚拟化技术的方法是完全实现数据存储。这样,我们测试集群的数据存储基本上与生产集群的数据存储相同,并且通过流处理不断更新。工作方式是使用(CDC - 更改数据捕获)(注19)从生产数据库捕获更改,然后将这些更改发送到新数据库。一些数据存储允许将其作为内置的复制机制(想想 mysql 的从节点或者其他),但很多时候这些是只读的。你可以使用像Debezium(注20)这样的更改数据捕获工具来构建简单的 CDC 系统,以便你的测试数据存储具有完全复制的生产数据库副本并且不受约束的使用它。 


Debezium 为不同的数据存储提供连接器(注21),并从这些数据库中获取更改事件(即读取事务日志)并将这些更改传送到 Apache Kafka(注22)。从那里,你可以使用任何流处理工具将这些流实现到你的测试数据库中。 FWIW,上面提到的 Teiid(注23)很快就会有这个功能。


Istio服务网格高级流量镜像,7种模式解决流量镜像难题


此外,如果你已经拥有数据流管道,使用事件驱动架构或使用某种事件源数据机制,那么这个“实现”测试数据库将成为更好的选择。





总结


在实践中,将生产流量镜像到我们的测试群集(无论该群集是存在于生产环境还是非生产环境中)是降低新部署风险的非常有效的方法。 


多年来,推特和亚马逊这样的大型 webops 公司一直在这样做。 这种方法带来了一些挑战,但是上述模式中讨论的方法存在有效的解决方案。 


如果你认为我错过了某些东西,或者觉得有一个我没有涉及到的令人讨厌的问题,请与我联系,我会很乐意与你讨论并将其添加到此博客的更新中。 谢谢!



1、https://www.slideshare.net/ceposta/microservices-journey-summer-2017

2、 https://www.cnet.com/news/zuckerberg-move-fast-and-break-things-isnt-how-we-operate-anymore/

3、http://blog.christianposta.com/microservices/traffic-shadowing-with-istio-reduce-the-risk-of-code-release/

4、http://blog.christianposta.com/

5、https://twitter.com/christianposta

6、https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route.proto.html?highlight=shadow#route-routeaction-requestmirrorpolicy

7、http://blog.christianposta.com/microservices/traffic-shadowing-with-istio-reduce-the-risk-of-code-release/

8、http://www.enterpriseintegrationpatterns.com/patterns/messaging/WireTap.html

9、https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route.proto.html?highlight=shadow#route-routeaction-requestmirrorpolicy

10、https://github.com/envoyproxy/envoy/pull/2600

11、https://github.com/twitter/diffy

12、https://blog.twitter.com/engineering/en_us/a/2015/diffy-testing-services-without-writing-tests.html

13、https://github.com/christian-posta/istio_tutorial/blob/ceposta-diffy/diffy/readme.md

14、https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/

15、https://hoverfly.io/

16、 http://microcks.github.io/

17、http://teiid.jboss.org/

18、 http://blog.christianposta.com/microservices/low-risk-monolith-to-microservice-evolution-part-iii/

19、https://en.wikipedia.org/wiki/Change_data_capture

20、http://debezium.io/

21、http://debezium.io/docs/

22、http://kafka.apache.org/

23、http://teiid.jboss.org/ 





推荐阅读


为什么我们需要Istio?四大组件助力Istio突围!使用Istio简化微服务系列二:如何通过HTTPS与外部服务进行通信?



ServiceMesh中文社区:

ServiceMesh中文社区(servicemesh.cn)已上线,Istio、Conduit官方文档翻译版已在社区发布,欢迎大家登录浏览。社区翻译小组志愿者招募中,有兴趣的私信小数即可~


ServiceMesh微信交流群:


社区活动:

3月31日(周六),数人云联合ServiceComb社区,并由ServiceMesh社区支持,开启meetup系列活动 Building Microservice 第2期 北京站 :微服务,从架构到发布,已经开始报名啦,扫码报名!



以上是关于Istio服务网格高级流量镜像,7种模式解决流量镜像难题的主要内容,如果未能解决你的问题,请参考以下文章

在KubeSphere启动服务网格Istio并解决解决ContainerCreating问题

在KubeSphere启动服务网格Istio并解决解决ContainerCreating问题

Istio 网关之南北向流量管理(内含服务网格专家亲自解答)

Istio 网关之南北向流量管理(内含服务网格专家亲自解答)

在 Istio 中实现 Redis 集群的数据分片读写分离和流量镜像

在 Istio 中实现 Redis 集群的数据分片读写分离和流量镜像