本文通过一个示例演示了如何在启用了Istio的应用中使用分布式追踪系统Jaeger。

背景信息

在由单体架构迁移至微服务时,传统的监视工具往往无法提供跨越不同服务的可见性。因此就有必要引入分布式跟踪的工具。

为了解决不同的分布式追踪系统 API 不兼容的问题,诞生了 OpenTracing 规范。OpenTracing 是一个轻量级的标准化层,它位于应用程序/类库和追踪或日志分析程序之间。OpenTracing 已进入 CNCF,正在为全球的分布式追踪,提供统一的概念和数据标准。它通过提供平台无关、厂商无关的 API,使得开发人员能够方便的添加(或更换)追踪系统的实现。

Jaeger 是CNCF下的一款开源分布式追踪系统,兼容 OpenTracing API。

前提条件

  • 您已成功部署一个Kubernetes集群,参见创建Kubernetes集群
  • 您需要拥有一个本地Linux环境,并已配置好Kubectl工具连接到集群,参见通过kubectl连接Kubernetes集群
  • 您已下载对应Istio版本的项目代码,并在Istio文件目录下执行相关命令。参见Istio

步骤1 一键部署 Jaeger 追踪系统

  1. 登录容器服务管理控制台
  2. 单击左侧导航栏的集群,选择所需集群,单击更多 > 部署Istio
    说明 本例中Isito的版本是1.1,更多关于部署Istio的信息,请参见部署Istio
    集群
  3. 在部署 Istio 页面中,选择启用分布式追踪 Jaeger。阿里云容器服务支持通过Web界面一键部署Jaeger追踪系统。
  4. 部署完成后,在左侧菜单栏中单击路由与负载均衡 > 服务,选择所需集群和命名空间,找到tracing服务。
  5. 如果tracing服务指定为LoadBalancer方式,单击tracing服务的外部地址,即可进入Jaeger UI页面。如果tracing服务指定为ClusterIP方式,可通过port-forward或路由方式访问。

    您可开始利用Jaeger观察服务间调用链,诊断性能问题、分析系统故障。

步骤2 部署分布式服务追踪示例Bookinfo

  1. 首先为default 命名空间打上标签 istio-injection=enabled
    说明 阿里云容器服务Kubernetes集群支持一键部署Istio,并支持自动Sidecar注入。更多信息,参见BookInfo指南
    $ kubectl label namespace default istio-injection=enabled
  2. 使用Kubectl命令部署Bookinfo示例应用。
    $ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml

    上面的命令会启动全部的四个服务,其中也包括了 reviews 服务的三个版本(v1、v2 以及 v3)。

  3. 确认所有的服务和 Pod 都已经正确的定义和启动。
    $ kubectl get svc,pods
  4. 您需要从外部访问应用程序,例如使用浏览器。您需要创建一个Istio Gateway 。为应用程序定义入口网关。
    $ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
    确认网关创建完成:
    $ kubectl get gateway
    NAME               AGE
    bookinfo-gateway   32s
  5. 然后确认istio-ingressgateway的访问地址。您可通过命令行快速查询。
    $ kubectl get svc istio-ingressgateway -n istio-system
    您也可通过容器服务管理控制台,在左侧导航栏单击应用 > 服务,选择集群和Istio-system命名空间,查看istio-ingressgateway服务的IP地址。
    服务列表
  6. 访问BookInfo首页,地址是http://{EXTERNAL-IP}/productpage
    error

    多次刷新浏览器,将在 productpage 中看到评论的不同的版本,它们会按照 round robin(红星、黑星、没有星星)的方式展现,因为目前为止还没有使用 Istio 来控制版本的路由。

步骤3 查看Jaeger追踪结果

Jaeger UI显示了分布式服务追踪信息的结果。

  1. 单击tracing-on-sls-query服务的外部地址,进入Jaeger UI 页面。
  2. 在左侧选择服务,然后选择各项配置,最后单击Find Traces,右上角显示的时刻和持续时间散点图用可视化方式呈现了结果,并提供了向下挖掘能力。
    说明 本例中以BookInfo示例应用为例,查看productpage服务的调用情况。
    Find Traces
  3. 用户可以选择用多种不同视图对追踪结果进行可视化,例如追踪时段内的直方图,或服务在追踪过程中的累积时间。
    追踪结果

Istio 分布式追踪实现原理

尽管Istio代理能够自动发送spans,但它们需要一些标识来将整个调用链关系联系起来。应用程序需要传入合适的HTTP header信息,便于代理发送span信息到Jaeger时,span可以准确地把每次调用关联起来。

为此,应用程序需要从传入的请求中收集如下的header信息并将其传入到每个传出请求:

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

示例服务中的productpage应用(Python应用)从HTTP请求中提取所需的header信息:

defgetForwardHeaders(request):
    headers = {}

    user_cookie = request.cookies.get("user")
    if user_cookie:
        headers['Cookie'] = 'user=' + user_cookie

    incoming_headers = [ 'x-request-id',
                         'x-b3-traceid',
                         'x-b3-spanid',
                         'x-b3-parentspanid',
                         'x-b3-sampled',
                         'x-b3-flags',
                         'x-ot-span-context'
    ]

    for ihdr in incoming_headers:
        val = request.headers.get(ihdr)
        if val isnotNone:
            headers[ihdr] = val
            #print "incoming: "+ihdr+":"+valreturn headers

在应用程序中调用其他服务时,这些header信息会被传播下去形成一个调用链。

具体代码请参见 Istio 文档Distributed-Tracing

总结

我们可以利用阿里云Kubernetes容器服务,快速搭建一套用于连接、管理以及安全化微服务的开放平台Istio,为应用引入和配置多个相关服务。本文通过一个示例演示了如何在启用了Istio的应用中使用分布式追踪系统Jaeger。 欢迎大家使用阿里云上的容器服务,快速搭建微服务的开放治理平台Istio,比较简单地集成到自己项目的微服务开发中。