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

参考