20

生产环境里的Istio和Kubernetes(二)- Tracing

 5 years ago
source link: http://dockone.io/article/8701?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

在上一篇 博文 里,我们介绍了Service Mesh(服务网格)Istio的组成部分,并回答了Istio新手经常会问的问题。本文会研究如何整理这些在网络上收集到的tracing信息。

在听到Service Mesh这个新概念的时候,开发人员和系统管理员首先考虑的事情是tracing。我们会为每个微服务添加特定的代理服务器来处理所有TCP流量。你可能会自然地认为很容易收集所有网络事件的信息。但不幸的是,实际需要考虑很多细节。让我们一起研究一下。

一大误解是可以轻松得到网络流量上的网络交互数据

实际上,相对容易的仅仅是得到由箭头连接的系统节点图,以及服务间的数据速率(实际上,仅仅是单位时间内的比特数)。但是,绝大多数情况下,服务通过应用层协议来通信,比如HTTP,gRPC,Redis等。当然,我们想看到这些协议的tracing信息,想看到应用级别请求的速率,而不是单纯的数据速率。另外,我们想知道协议的请求延时。最终,则想看到从用户输入触发的请求到收到回复这之间的全路径。不过这可不是一件容易的事情。

首先,从Istio的架构角度看怎么发送tracing信息。上文提到,Istio有一个特定的组件收集Telemetry,称为Mixer。但是,在当前的1.1.*的版本里,代理服务器,也就是envoy代理,直接发送tracing span。envoy代理支持使用zipkin协议发送tracing span。其他协议则要求单独的插件。Istio自带预编译并且预先配置好的envoy代理,仅支持zipkin协议。比如,如果用户想使用Jaeger协议并通过UDP发送tracing span,那么他需要构建自定义的istio-proxy镜像。Istio-proxy的确支持自定义插件,但是,还仅仅有alpha版本。因此,如果想避免多个自定义的设置,那么接受并存储tracing span的方案里并没有太多的选择。可以使用最受欢迎的协议,Zipkin或者Jaeger,但是如果使用后者,所有东西都需要使用zipkin兼容的协议(性能会差一些)来上传。zipkin协议通过HTTP协议将所有tracing信息发送给收集器,消耗更大。

如上文所说,我们需要跟踪应用层协议。这意味着每个服务旁的代理服务器必须理解当时发生的网络事件。Istio默认所有端口使用plain TCP,这意味着不会发送trace。要发送trace,首先需要在main mesh config里启用相关的配置,然后依据服务内协议的实现来命名所有Kubernetes服务实体的所有端口。比如:

apiVersion: v1

kind: Service

metadata:

name: nginx

spec:

ports:

- port: 80

targetPort: 80

name: http

selector:

app: nginx

还可以使用组合名称,比如http-magic(Istio能够识别http并且将端口识别为http端口)。

为了避免修补多个配置来定义协议,有如下workaround:在Pilot组件 执行协议决策逻辑 的时候修改它的配置。然后,当然需要切回标准逻辑并且切换所有端口的命名惯例。

为了理解协议是否定义正确,可以从envoy代理进入任意sidecar容器,从location/config_dump发送请求给envoy接口的admin端口。在最终的配置里,检查相应服务的operation字段。在Istio里,它就相当于请求目的地的标识。在istio里自定义这个参数(之后可以在tracing系统里看到),启动sidecar容器的时候设置serviceCluster标记。比如,它可以从Kubernetes API得到的变量里计算出来:

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

这里 很好地解释了envoy的trace是如何工作的。

在envoy代理的启动标记里必须指定发送tracing span的端口,比如: —-zipkinAddress tracing-collector.tracing:9411

另一个误解是用户可以轻松获取系统内请求的所有trace

不幸的是事实并非如此。实现的复杂度取决于服务是如何交互的。为什么是这样呢?

问题在于要让Istio代理理解服务的入站和出站请求的匹配关系,仅仅截获所有流量是不够的。你需要某种匹配标识符。HTTP envoy代理使用特别的header,这样envoy能够准确理解服务的哪个请求生成对其他服务的特定请求。这些header包括:

  • x-request-id
  • x-b3-spanid
  • x-b3-parentspanid
  • x-b3-sampled
  • x-b3-flags
  • x-ot-span-context

如果你只有一个单点,比如,一个基础的客户端,这里可以加入逻辑,然后需要做的就是等待library在所有客户端里更新完毕。但是如果你面对的是一个复杂的异构系统,没有统一的服务-服务的网络流量,那么很可能就会有问题。不加这样的逻辑,所有的tracing信息都是单层级的。你可以得到所有服务-服务的交互,但是却无法形成网络流量链。

结论

Istio提供了方便的工具收集网络上的所有tracing信息,但是它的实现要求系统的变更,要考虑到Istio的实现的独特性。这是要解决的两大问题:定义应用层的协议(envoy代理必须支持)以及设置转发信息,匹配入站和出站请求(如果是HTTP协议的话,使用header)。如果这两大问题都解决了,那么你就有了强大的工具,可以从网络上透明地收集信息,即使这是个高度异构的系统,可能由多种语言使用多种架构组成。

下一篇博文里,我们会讨论Istio最大的挑战之一——每个sidecar代理容器所带来的高RAM使用率的问题——并且讨论如何解决这个问题。

原文链接:[Istio and Kubernetes in production. Part 2. Tracing]( https://medium.com/avitotech/i ... f82e9 )(翻译:崔婧雯 校对:)

===========================

译者介绍

崔婧雯,现就职于IBM,高级软件工程师,负责IBM WebSphere业务流程管理软件的系统测试工作。曾就职于VMware从事桌面虚拟化产品的质量保证工作。对虚拟化,中间件技术,业务流程管理有浓厚的兴趣。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK