分布式跟踪系统Jaeger(三):在Kubernetes上部署Jaeger

2017-12-06 阅读: jaeger OpenTracing Kubernetes

前面我们使用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来使用。

---
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这个镜像可以使用。 部署定义如下:

---
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数据,分析服务间的连接和依赖。

参考

标题:分布式跟踪系统Jaeger(三):在Kubernetes上部署Jaeger
本文链接:https://blog.frognew.com/2017/12/opentracing-jaeger-3.html
转载请注明出处。

目录