Istio跟踪和监视:微服务和不确定性原则

海森堡不确定性原理指出,不可能同时测量物体的位置及其速度。 如果物体移动,则它没有位置。 如果位置在,那意味着他没有速度。



至于在Red Hat OpenShift平台(运行Kubernetes)上的微服务,由于使用了相应的开源软件,它们可以同时报告其性能和运行状况。 当然,这并不能反驳旧的海森堡,但是可以消除使用云应用程序时的不确定性。 Istio使组织此类应用程序的跟踪(跟踪)和监视变得容易,以使所有内容都受到控制。

定义术语


通过跟踪,我们指的是记录系统活动。 这听起来很笼统,但实际上,这里的主要规则之一是将跟踪数据转储到适当的存储中,而不必担心对其进行格式化。 搜索和分析数据的所有工作都委托给他们的消费者。 Istio使用Jaeger跟踪系统,该系统实现了OpenTracing数据模型。

通过痕迹 (例如,在弹道检查中, 痕迹 (Traces)和`` 痕迹'' (traces)一词在这里是指``痕迹''的意思),我们指的是完全描述请求或工作单元通过的数据,正如他们所说的``从和到''。 例如,从用户按下网页上的按钮到返回数据的那一刻之间发生的一切,包括其中涉及的所有微服务。 我们可以说一个跟踪完全描述(或模拟)了请求的来回传递。 在Jaeger界面中,沿时间轴将磁道分解为分量,例如如何将链分解为单独的链接。 轨道不是链接而是由所谓的跨度组成。

跨度是从工作单元开始到完成的间隔。 继续类推,我们可以说每个跨度是链中的单独链接。 一个跨度可能有一个或多个子跨度,也可能没有。 结果,顶级范围(根范围)的总持续时间与其所属的跟踪相同。

实际上, 监视是通过眼睛,UI或自动化对系统进行的观察。 监视基于跟踪数据。 在Istio中,监视是使用Prometheus工具实现的,并具有相应的UI。 Prometheus支持使用警报和警报管理器警报进行自动监视。

留下刻痕


为了进行跟踪,应用程序必须创建一个范围集合。 然后必须将它们导出到Jaeger,以便他依次创建轨迹的可视表示。 其中,这些跨度标记了操作的名称以及操作开始和结束的时间戳。 通过将Jaeger特定的HTTP请求标头从传入请求转发到传出请求来发送跨度。 根据所使用的编程语言,这可能需要对应用程序源代码进行一些修改。 以下是一个Java代码示例(使用Spring Boot框架时),该示例在Spring配置类中向您的请求添加了B3(Zipkin样式)标头:


使用以下标头设置:


如果使用Java,则可以保持代码不变,只需在Maven POM文件中添加几行并设置环境变量即可。 这是您需要添加到POM.XML文件中以实现Jaeger Tracer Resolver的行:


并在Dockerfile中设置相应的环境变量:


就是这样,现在已经全部设置好了,我们的微服务将开始生成跟踪数据。

我们一般来说


Istio包括一个基于Grafana的简单控制面板。 在Red Hat OpenShift PaaS平台上配置并运行所有内容后(在我们的示例中,在minishift上部署了Red Hat OpenShift和Kubernetes),将使用以下命令启动此面板:

open "$(minishift openshift service grafana -u)/d/1/istio-dashboard?refresh=5⩝Id=1" 

Grafana面板可让您快速评估系统。 下图显示了该面板的一部分:


在这里,您可以看到微服务客户调用了微服务首选项v1,又调用了微服务建议v1和v2。 Grafana面板上有一个“仪表板行”块,用于高级度量,例如请求总数(全局请求量),成功请求百分比(成功率),4xx错误。 此外,还有一个“服务器网格”视图,其中包含每个服务的图形,以及一个“服务行”块,用于查看每个服务的每个容器的详细信息。

现在更深入


正如他们所说,使用正确配置的跟踪,可以立即使用Istio进行系统性能分析。 在Jaeger UI中,您可以查看轨迹并查看轨迹的深度和深浅,以及可视化地定位性能瓶颈。 在minishift平台上使用Red Hat OpenShift时,请使用以下命令启动Jaeger UI:

 minishift openshift service jaeger-query --in-browser 


关于此屏幕上的轨迹可以说些什么:

  • 它分为7个跨度。
  • 总执行时间为6.99毫秒。
  • 微服务推荐(这是链中的最后一条)花费0.69毫秒。

这种类型的图表使您可以快速找出由于单个服务不良而导致整个系统性能下降的情况。

现在,让任务复杂化并启动两个推荐微服务实例:v2和oc scale --replicas = 2 Deployment / Recommendation-v2命令。 在此之后,我们将提供以下吊舱:


如果现在切换回Jaeger并为推荐服务部署跨度,我们将看到路由到哪些pod请求。 因此,我们可以轻松地将制动器定位​​在特定的吊舱水平。 您应该查看node_id字段:


一切进展顺利


现在,我们转到Prometheus界面,非常期望地看到,推荐服务的第二个版本与第一个版本之间的请求严格按工作窗格的数量以2:1的比例划分。 此外,该图在向上和向下扩展Pod时会动态变化,这对于Canary Deployment尤其有用(我们将在下一次更详细地研究此部署方案)。


这仅仅是开始


实际上,正如他们所说,今天,我们只触及了有关Jaeger,Grafana和Prometheus的有用信息的仓库。 总的来说,这是我们的目标-指导您正确的方向,开拓Istio的前景。

请记住,所有这些已经内置在Istio中。 当使用某些编程语言(例如Java)和框架(例如Spring Boot)时,所有这些都可以实现,而无需完全触摸应用程序代码本身。 是的,如果您使用其他语言(主要是Nodejs或C#),则必须对代码进行一些修改。 但是,由于可追溯性(读取,“跟踪”)是创建可靠的云系统的先决条件之一,无论如何,无论是否具有Istio,您都必须编辑代码。 那么,为什么不花更多的精力来赚钱呢?

至少要始终以100%的确定性回答问题“在哪里?”和“有多快?”。

Istio的混沌工程:它的构思


打破事物的能力有助于确保它们不会破裂


软件测试不仅是一件复杂的事情,而且是一件重要的事情。 同时,进行正确性测试(例如,一个函数是否返回正确的结果)是一回事,而在不可靠的网络中进行测试则是完全不同的任务(通常认为网络始终可以正常工作而没有故障,这是对分布式的八种误解中的第一种)计算)。 解决此问题的困难之一是如何通过执行所谓的故障注入来模拟系统中的故障或有意引入故障。 这可以通过修改应用程序本身的源代码来完成。 但是,您将不会测试原始代码,而是测试专门模拟故障的版本。 结果,您冒着进入故障注入的致命境地并与heisenbags碰撞的风险-当您尝试检测故障时,故障会消失。

现在,我们将展示Istio如何帮助他们一二面对这些困难。

一切正常时的外观


考虑以下情形:我们从Istio教程中获得了两个用于推荐微服务的Pod。 一个吊舱标记为v1,另一个吊舱标记为v2。 如您所见,尽管一切正常,但:


(顺便说一句,右边的数字只是每个吊舱的呼叫计数器)

但是我们不需要这个吗? 好吧,让我们尝试在不触及源代码的情况下破坏所有内容。

我们安排微服务的工作中断


以下是Istio路由规则的yaml文件,该文件在一半情况下将失败(服务器错误503):


请注意,我们明确规定在一半情况下应返回错误503。

这是激活此规则以模拟失败后在循环中启动的curl命令的屏幕截图。 如您所见,一半的请求都返回错误503,并且无论哪个pod(v1或v2)都转到:


要恢复正常操作,只需删除此规则就足够了,在我们的示例中,是istioctl delete route推荐-503 -n教程命令。 此处的教程是运行我们的Istio教程的Red Hat OpenShift项目的名称。

人为延迟


人为错误503有助于测试系统的容错能力,但是预测和处理延迟的能力应该会给您留下深刻的印象。 现实生活中的延误比失败更多。 运行缓慢的微服务是整个系统遭受的毒药。 借助Istio,您可以测试与延迟处理相关的代码,而无需进行任何更改。 首先,我们将展示在人为引入的网络延迟情况下如何执行此操作。

请注意,在进行此类测试后,您可能需要(或想要)完善代码。 好消息是,在这种情况下,您将采取积极行动,而不是被动行动。 这就是应该建立的开发周期的方式:编码测试反馈反馈编码测试...

这是规则的样子……尽管您知道什么? Istio非常简单,并且这个yaml文件非常清晰,因此本示例中的所有内容都能说明一切,请看一下:


在一半的情况下,我们将有7秒钟的延迟。 这一点与我们在源代码中插入sleep命令完全不同,因为Istio确实将请求延迟了7秒。 由于Istio支持Jaeger跟踪,因此在Jaeger倾斜的UI中此延迟非常好,如下面的屏幕快照所示。 请注意该图右上角的长请求-其持续时间为7.02秒:


这种情况下,您可以在网络延迟条件下测试代码。 很明显,通过删除此规则,我们将删除人为延迟。 我们重复一遍,但是同样,我们在不触及源代码的情况下完成了所有这些操作。

不要退缩,不要放弃


Istio的另一个对混乱工程有用的功能是重复调用服务指定次数。 这里的目的不是要在第一个请求以错误503结束时停止尝试-然后,也许是第N次,我们很幸运。 也许由于某种原因,该服务只是短暂停留了一段时间。 是的,应该发掘并消除这个原因。 但这是稍后的时间,但是现在让我们尝试使系统继续运行。

因此,我们希望该服务不时给出503错误,然后Istio将尝试再次与他联系。 在这里,我们显然需要一种生成错误503的方法,而无需触及代码本身...

停止等待! 我们做到了。

该文件将使Recommendation-v2服务在一半情况下生成503错误:


显然,部分请求将失败:


现在,我们将使用Retry Istio函数:


此路由规则以两秒钟的间隔进行了三次重试,并应减少(最好是完全从雷达中清除)503错误:


总结一下:我们这样做是为了让Istio首先为一半的请求生成503错误。 其次,如果发生503错误,同一个Istio会尝试三次重新连接到服务,结果一切正常。 因此,使用重试功能,我们实现了不退缩,不放弃的承诺。

是的,我们再次执行此操作,完全没有触及代码。 我们需要的只是两个Istio路由规则:


如何不让用户失望或七不等待


现在,我们把情况彻底弄清楚,考虑不必撤退而只放弃一些固定时间的情况。 然后,您只需停止尝试处理该请求,以免迫使所有人等待任何一项制动服务。 换句话说,我们将不会保护失去的位置,而是会移至备用线,以免让站点用户失望,也不会迫使他无知而感到沮丧。

在Istio中,您可以设置请求超时。 如果服务超过此超时时间,则返回错误504(网关超时)-再次,所有这些操作都是通过Istio配置完成的。 但是我们必须将sleep命令添加到服务源代码中(然后,当然要执行重建和重新部署),以模拟服务的缓慢运行。 las,否则它将无法正常工作。

因此,我们在推荐v2服务代码中插入了三秒钟的休眠时间,重建了相应的映像,并重新设置了容器模式,现在,我们将使用以下Istio路由规则添加超时:


上面的屏幕截图显示,如果我们在一秒钟内(即在发生错误504之前)未收到响应,则尝试与推荐服务联系。在应用此路由规则之后(向推荐服务代码添加了三秒钟的睡眠) :v2),我们得到以下信息:


我们再次重复,但是可以设置超时而无需触碰源代码。 另外,这里的额外好处是现在您可以修改代码,使其对超时做出响应,并且可以使用Istio轻松测试这些改进。

现在在一起


使用Istio进行一些混乱是测试代码和整个系统的可靠性的好方法。 在创建容错云系统时,后备,隔板和断路器模式,人为故障和延迟的创建机制以及重复的呼叫和超时将非常有用。 这些工具与Kubernetes和Red Hat OpenShift结合使用,可以帮助您自信地面对未来。

Source: https://habr.com/ru/post/zh-CN485136/


All Articles