前面我们使用Jaeger的all in one docker镜像和Jaeger的HotROD示例应用简单试用了一下, 并对Jaeger的基本概念和组成做了初步了解。接下来该为了在生产环境中部署Jaeger做下一步的试验了。 本篇我们将尝试再Kubernetes集群上部署Jaeger,并使用我们已经存在的Elasticsearch集群作为数据存储。

1.jaeger-kubernetes项目

jaegertracing/jaeger-kubernetes这个项目给出了在Kubernetes上部署Jaeger的模板。

jaeger-production-template.yml中定义了jaeger collector和jaeger query(包含UI)的Deployment和Service。 jaeger collector和jaeger query的Deployment使用了名称为jaeger-configuration的ConfigMap读取后端存储等相关配置。

production-elasticsearch/elasticsearch.yml中是jaeger官方给的使用Elasticsearch作为存储时jaeger-configuration的定义和一个简单的使用SatefulSet部署ES的例子。 production/cassandra.yml中是jaeger官方给的使用cassandra作为存储时jaeger-configuration的定义和一个简单的使用SatefulSet部署cassandra的例子。 需要注意官方给的存储和配置定义是不能用于生产环境的,例如官方模板的SatefulSet的volumes使用的是emptyDir。因此无论使用哪种后端存储,都要根据生产环境的实际情况修改官方的存储和配置定义。

2.在Kubernetes上部署Jaeger

我们的ES集群是独立在Kubernetes外部的,使用Kubernetes的Service和Endpoint将这个外部的ES集群作为k8s上的Service来使用。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
---
apiVersion: v1
kind: List
items:
- apiVersion: extensions/v1beta1
  kind: Deployment
  metadata:
    name: jaeger-collector
    namespace: kube-system
    labels:
      app: jaeger
      jaeger-infra: collector-deployment
  spec:
    replicas: 1
    strategy:
      type: Recreate
    template:
      metadata:
        labels:
          app: jaeger
          jaeger-infra: collector-pod
      spec:
        containers:
        - image: jaegertracing/jaeger-collector:0.9
          name: jaeger-collector
          command:
            - "/go/bin/collector-linux"
            - "--config-file=/conf/collector.yaml"
          ports:
          - containerPort: 14267
            protocol: TCP
          - containerPort: 14268
            protocol: TCP
          - containerPort: 9411
            protocol: TCP
          volumeMounts:
          - name: jaeger-configuration-volume
            mountPath: /conf
        volumes:
          - configMap:
              name: jaeger-configuration
              items:
                - key: collector
                  path: collector.yaml
            name: jaeger-configuration-volume
- apiVersion: v1
  kind: Service
  metadata:
    name: jaeger-collector
    namespace: kube-system
    labels:
      app: jaeger
      jaeger-infra: collector-service
  spec:
    ports:
    - name: jaeger-collector-tchannel
      port: 14267
      protocol: TCP
      targetPort: 14267
    - name: jaeger-collector-http
      port: 14268
      protocol: TCP
      targetPort: 14268
    - name: jaeger-collector-zipkin
      port: 9411
      protocol: TCP
      targetPort: 9411
    selector:
      jaeger-infra: collector-pod
    type: ClusterIP
- apiVersion: v1
  kind: Service
  metadata:
    name: zipkin
    namespace: kube-system
    labels:
      app: jaeger
      jaeger-infra: zipkin-service
  spec:
    ports:
    - name: jaeger-collector-zipkin
      port: 9411
      protocol: TCP
      targetPort: 9411
    selector:
      jaeger-infra: collector-pod
    type: ClusterIP
- apiVersion: extensions/v1beta1
  kind: Deployment
  metadata:
    name: jaeger-query
    namespace: kube-system
    labels:
      app: jaeger
      jaeger-infra: query-deployment
  spec:
    replicas: 1
    strategy:
      type: Recreate
    template:
      metadata:
        labels:
          app: jaeger
          jaeger-infra: query-pod
      spec:
        containers:
        - image: jaegertracing/jaeger-query:0.9
          name: jaeger-query
          command:
            - "/go/bin/query-linux"
            - "--config-file=/conf/query.yaml"
          ports:
          - containerPort: 16686
            protocol: TCP
          readinessProbe:
            httpGet:
              path: "/"
              port: 16686
          volumeMounts:
          - name: jaeger-configuration-volume
            mountPath: /conf
        volumes:
          - configMap:
              name: jaeger-configuration
              items:
                - key: query
                  path: query.yaml
            name: jaeger-configuration-volume
- apiVersion: v1
  kind: Service
  metadata:
    name: jaeger-query
    namespace: kube-system
    labels:
      app: jaeger
      jaeger-infra: query-service
  spec:
    ports:
    - name: jaeger-query
      port: 80
      protocol: TCP
      targetPort: 16686
      nodePort: 30002
    selector:
      jaeger-infra: query-pod
    type: NodePort

注意上面部署的jaeger-query这个Service已经包含的了jaeger WebUI,但此时打开jaeger WebUI查询Trace数据时会报错。 因为jaeger还没有收集到trace数据,不会再ES中创建索引。

3.在Kubernetes上部署HotROD示例应用

已经在k8s上部署了jaeger query和jaeger collector。 接下来在Kubernetes上部署HotROD示例应用进行以下简单的测试。

jaeger官方没有提供HotROD示例应用的docker镜像,搜索了一下第三方的,mikelorant/jaeger-hotrod这个镜像可以使用。 部署定义如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
---
kind: Service
apiVersion: v1
metadata:
  labels:
    app: hotrod
  name: hotrod
spec:
  type: NodePort
  ports:
  - port: 8080
    targetPort: 8080
    nodePort: 30000
  selector:
    app: hotrod

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: hotrod
spec:
  template:
    metadata:
      labels:
        app: hotrod
    spec:
      containers:
      - image: mikelorant/jaeger-hotrod
        name: hotrod
        ports:
        - containerPort: 8080
      - image: jaegertracing/jaeger-agent
        name: jaeger-agent
        ports:
        - containerPort: 5775
          protocol: UDP
        - containerPort: 5778
        - containerPort: 6831
          protocol: UDP
        - containerPort: 6832
          protocol: UDP
        command:
        - "/go/bin/agent-linux"
        - "--collector.host-port=jaeger-collector.kube-system:14267"

在部署模板的Pod中除了jaeger-hotrod这个示例应用外,还有jaeger-agent这个容器作为sidecar,监听本地的UDP端口。 jaeger-hotrod应用中jaeger-client-go将追踪Span报告给本地的UDP端口。

hotrod应用部署完成后,点击使用hostrod应用,在jaeger ui中就可以查询到trace数据了。

jager-ui-traces.jpg

在后端的ES存储中可以看到创建了索引jaeger-service-2017-12-06jaeger-span-2017-12-06,可以看出当使用ES作为后端存储时,是按天创建索引的。

点击jaeger ui的Dependencies页面提示No service dependencies found.,这是因为使用的不是基于内存的后端存储时还需要jaeger spark job从存储中收集span数据,分析服务间的连接和依赖。

参考