istio环境-jaeger生产环境搭建

3,172 阅读5分钟

最近在搭建 istio 环境,正好调研到服务治理的链路追踪这一层,istio 所支持的有 jaeger、zipkin 以及 lightstep,本篇探索一下生产环境下 jaeger 的部署。

Jaeger 简介

Jaeger 是Uber推出的一款开源分布式追踪系统,兼容OpenTracing API。分布式追踪系统用于记录请求范围内的信息,包括一次调用的服务链路以及每个服务的延时,能够帮助我们很好的分析微服务间链路调用的错误及瓶颈。

OpenTracing api 及其原理将在下一篇 blog 中介绍。由于 istio 默认支持 Jaeger,因此准备测试下 Jaeger与Istio的集成。

Jaeger 整体架构如下图,主要包括3个组件: agent,collector以及query(UI)

  • agent: 用于监听应用传来的链路信息,并传递给collector,
  • collector:收集链路信息,并持久化。 其支持的后端存储为 Cassandra、ElasticSearch。此外也支持对接 Kafka,以进行后续的流式处理(可连入 spark、flink 以进一步分析)
  • query:提供查询的 api 接口及 UI 界面

Jaeger vs Zipkin vs Skywalk

//TODO

Jaeger 部署

在 K8s 环境中,Jaeger 支持两种模式部署:

  1. all-in-one
  2. 生产模式

all-in-one

all-in-one 模式是 istio 默认支持的模式,只需要在使用 helm 部署 istio 时,修改 values.yml 中 tracing: enabled: true 即可。这样无需其他操作。

由于 all-in-one 模式是用于测试的demo,因此所有的链路信息默认存储在内存中,无法用于生产环境。

若单独在 K8s 平台中, Jaeger 官方推荐使用 Jaeger Operator 部署。Operator 部署相对来说比较简单,参考连接https://www.jaegertracing.io/docs/1.14/operator/,此处不再赘述。

Operator 是 K8s 平台提供的一种可自定义 Controller 的方式,此外仍需定义一系列的 CRD,自定义 Operator 通过监听 CRD 的状态更新,实现一系列的逻辑,比如创建 deployment 等。

生产环境部署

Jaeger 在生产环境,需要独立部署三个组件,这样可以提高软件的扩展性和稳定性。

在 K8s 平台部署,可以参考 jaeger-on-k8s。其中collector 以及 query 均以 deployment 的形式部署;agent 可以选择 daemonSet 或以 sidecar 注入的方式部署。若 agent 选择 daemonSet 的方式,意味着每个节点中的所有pod 都可以向 Jaeger 发送链路信息。但在特定场景中,我们并不想收集所有服务的链路信息,因此可以选用 sidecar 的形式。

sidecar 具体形式如下:

apiVersion: apps/v1
  kind: Deployment
  metadata:
    name: myapp
  spec:
    selector:
      matchLabels:
        app.kubernetes.io/name: myapp
    template:
      metadata:
        labels:
          app.kubernetes.io/name: myapp
      spec:
        containers:
        - image: mynamespace/hello-myimage
          name: myapp
          ports:
          - containerPort: 8080
        - image: jaegertracing/jaeger-agent
          name: jaeger-agent
          ports:
          - containerPort: 5775
            protocol: UDP
          - containerPort: 6831
            protocol: UDP
          - containerPort: 6832
            protocol: UDP
          - containerPort: 5778
            protocol: TCP
          args: ["--collector.host-port=jaeger-collector.jaeger-infra.svc:14267"]

若使用 Jaeger Operator 部署的Jaeger, 仅需要在 Deployment 中加入注解 sidecar.jaegertracing.io/inject: true,以sidecar 的形式注入,则需要给应用客户端配置 JAEGER_AGENT_HOST来告诉服务 agent 在哪。

Isito & Jaeger

在 istio 中,我们可以不部署 agent 组件。因为在 istio 中,若在 mixer 组件配置 zipkin-address-url 参数,则会默认为服务网格中的服务创建调用链路信息,并发送到配置的地址中。

这里的zipkin-address-url 并非真正部署的 zipkin, 而是这个地址可以兼容 zipkin 所使用的数据格式。

因此,我们利用上述方法部署 jaeger collecor 和 query ui。首先创建 config.yml 用于配置 Jaeger,

apiVersion: v1
kind: ConfigMap
metadata:
  name: jaeger-configuration
  labels:
    app: jaeger
    app.kubernetes.io/name: jaeger
data:
  span-storage-type: elasticsearch
  collector: |
    es:
      server-urls: http://elasticsearch-logging.kube-system:9200
    collector:
      zipkin:
        http-port: 9411
  query: |
    es:
      server-urls: http://elasticsearch-logging.kube-system:9200
  agent: |
    collector:
      host-port: "jaeger-collector:14267"

然后获取生产模式的 Jaeger 部署文件并进行部署。

$ wget https://raw.githubusercontent.com/jaegertracing/jaeger-kubernetes/master/jaeger-production-template.yml

部署好之后,环境如下所示。

# pod
NAME                               READY   STATUS    RESTARTS   AGE
jaeger-collector-b9bf6d75b-gvg7r   1/1     Running   0          25h
jaeger-query-5fd6c9dcff-wvm82      1/1     Running   0          25h

# service
NAME               TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S) 
jaeger-collector   ClusterIP      10.233.20.50   <none>        14267/TCP,14268/TCP,9411/TCP 
jaeger-query       LoadBalancer   10.233.4.232   10.7.13.201   80:40000/TCP             
zipkin             ClusterIP      10.233.4.179   <none>        9411/TCP                 

对于已经部署好的 istio,需要修改 istio-system namespace 下的 名为 istio 的 configmap,更替其中的 zipkin: address: xxx为 Jaeger collector的 9411端口的服务。并重启应用所在的pod,以使该配置生效。

可以检查 应用pod中的 envoy 配置是否已修改。在 istio-proxy container中的 /etc/istio/proxy/recvx.json中可以找到。

若还未部署istio,则只需在helm 安装时,增加 --set gloable.zipkin.address=xxxx 参数。

注意 这里有一个坑! istio 的 policy 组件默认设置的链路追踪采样率为 1%,因此在配置好 Jaeger 以后可能访问好几次服务都无法获取链路信息(这个地方困了我一天,一直以为是哪个地方配错了。。。哎),可以在部署 istio的时候,添加参数 --set pilot.traceSampling=10 修改为 10% 或其他数字。

总结

其实 Jaeger 官方特别推荐使用 Operator 来部署 Jaeger,毕竟 Operator 是未来 K8s 使用的主流趋势,并且确实方便快捷。此外还有一种流式模式,即部署 Jaeger 对接 Kafka 的方式本文中并未列出,详情可参考 Jaeger 官方文档。本文只简单记录下平台层面上 Jaeger 的部署,并未涉及业务逻辑和业务场景,毕竟大规模的业务场景下,也需要更复杂的配置,包括 jaeger 采样策略,对接ES 或 Kafka 进行流式处理及分析等。