Istio和Kubernetes投入生产。 第2部分。跟踪

在上一篇文章中,我们检查了Service Mesh Istio的基本组件,熟悉了该系统,并回答了在开始使用Istio时通常出现的基本问题。 在这一部分中,我们将研究如何组织网络上的跟踪信息的收集。



许多开发人员和系统管理员在听到Service Mesh正在跟踪时遇到的第一件事。 实际上,我们向所有TCP流量通过的每个网络节点添加了一个特殊的代理服务器。 看来现在您可以轻松地发送有关网络上所有网络交互的信息。 不幸的是,现实中必须考虑许多细微差别。 让我们看看它们。

误解一:我们可以免费获取网络旅行数据


实际上,相对而言,我们只能通过箭头和服务之间传递的数据速率来连接系统的节点(实际上,每单位时间只有字节数)。 但是,在大多数情况下,我们的服务使用某种应用程序级协议进行通信,例如HTTP,gRPC,Redis等。 而且,当然,我们希望根据这些协议准确地跟踪信息,我们希望查看请求的速率,而不是数据的速率。 我们想通过我们的协议了解请求的延迟。 最后,我们希望看到请求从进入系统到收到用户响应的完整路径。 这个问题不是那么容易解决。

首先,让我们从Istio的体系结构角度看一下发送跟踪范围。 我们在第一部分中还记得,Istio有一个用于收集遥测的独立组件,称为Mixer。 但是,在当前版本1.0中*发送是直接从代理服务器完成的,即使用envoy代理。 Envoy代理支持开箱即用zipkin协议发送跟踪范围。 可以连接其他协议,但只能通过插件连接。 使用Istio,我们立即获得组装和配置的特使代理,该代理仅支持zipkin协议。 例如,如果要使用Jaeger协议并通过UDP发送跟踪范围,则需要组装istio-proxy映像。 支持istio-proxy的自定义插件,但是仍为Alpha版本。 因此,如果我们要在没有大量自定义设置的情况下进行操作,则会减少用于存储和接收跟踪范围的技术范围。 实际上,在主要系统中,现在您可以使用Zipkin本身或Jaeger,但可以使用与zipkin兼容的协议(效率要低得多)将所有内容发送到那里。 zipkin协议本身涉及使用HTTP协议将所有跟踪信息发送到收集器,这非常昂贵。

正如我所说,我们想跟踪应用程序级协议。 这意味着每个服务旁边的代理服务器必须了解现在正在发生哪种交互。 默认情况下,Istio设置所有普通TCP端口的类型,这意味着将不发送任何跟踪。 为了发送跟踪,必须首先在主网格配置中启用此选项,并且非常重要的是,根据服务中使用的协议重命名kubernetes服务实体的所有端口。 也就是说,例如:

apiVersion: v1 kind: Service metadata: name: nginx spec: ports: - port: 80 targetPort: 80 name: http selector: app: nginx 

您也可以使用复合名称,例如http-magic(Istio看到http并将该端口识别为http端点)。 格式为:原型附加。

为了不对用于定义协议的大量配置进行修补,可以使用一种肮脏的解决方法:仅在执行协议定义逻辑时对Pilot组件进行修补。 当然,最后,您将需要将此逻辑更改为标准,并使用所有端口的命名约定。

为了了解协议是否确实正确定义,您需要使用envoy代理进入任何sidecar容器,并使用location / config_dump向envoy接口的admin端口发出请求。 在结果配置中,您需要查看所需的服务字段操作。 在Istio中,它用作请求要去向的标识符。 为了在Istio中自定义此参数的值(然后将在跟踪系统中看到它),有必要在启动sidecar容器的阶段指定serviceCluster标志。 例如,可以从向下的API kubernetes获得的变量中像这样计算:

--serviceCluster ${POD_NAMESPACE}.$(echo ${POD_NAME} | sed -e 's/-[a-z0-9]*-[a-z0-9]*$//g')

这里有一个很好的例子,可以理解跟踪在特使中的工作原理。

还必须在特使代理的开始标志中指定用于发送跟踪范围的端点本身,例如:-- --zipkinAddress tracing-collector.tracing:9411

误解二:开箱即用,我们可以廉价地获取有关系统请求通过的完整痕迹


不幸的是,事实并非如此。 实现的复杂性取决于您已经实现了服务交互的方式。 为什么这样

事实是,为了使istio-proxy能够理解到服务的传入请求与来自同一服务的请求之间的对应关系,仅拦截所有流量是不够的。 您需要具有某种链接标识符。 Envoy代理HTTP使用特殊的标头,通过这些标头,envoy可以了解哪个特定服务请求生成对其他服务的特定请求。 此类标题的列表:

  • x-request-id,
  • x-b3-血流素
  • x-b3-spanid,
  • x-b3-父母父母,
  • x-b3采样,
  • x-b3标志,
  • x-ot-span-context。

如果您只有一个点,例如可以在其中添加这种逻辑的基本客户端,那么一切都很好,您只需要等待所有客户端更新此库即可。 但是,如果您的系统非常异构,并且活动中的服务从网络到网络的服务都没有统一,那么这很可能是个大问题。 如果不添加此类逻辑,则所有跟踪信息将只是“同级”。 也就是说,我们获得了所有的服务间交互,但是它们不会被粘贴到通过网络的单个通道链中。

结论


Istio提供了一种方便的工具,可用于通过网络收集跟踪信息,但是,您必须了解,对于实现,您将需要调整系统并考虑Istio的实现功能。 因此,您需要解决两个主要问题:确定应用程序层协议(应该由envoy代理支持)以及设置有关来自服务请求的请求到服务的连接性信息的转发(在HTTP协议的情况下使用标头)。 解决这些问题后,我们将提供一个功能强大的工具,即使在以多种不同语言和框架编写的异构系统中,您也可以透明地从网络中收集信息。

在下一篇有关Service Mesh的文章中,我们将考虑Istio的最大问题之一-每个Sidecar代理容器占用大量内存,并讨论如何处理它。

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


All Articles