OpenShift 4 - 可观测性之用 OpenTelemetry+Tempo 实现 Distributed Tracing

《OpenShift / RHEL / DevSecOps 汇总目录》
说明:本文已经在支持 OpenShift 4.13 的环境中验证

文章目录

  • 技术架构
  • 部署 Distributed Tracing 运行环境
    • 安装 minio 环境
    • 安装 Grafana Tempo 环境
  • 部署测试应用并进行观测跟踪
    • 测试应用1
    • 测试应用2
  • 参考

技术架构

Tempo 是 Grafana 公司推出的可对云原生应用实现请求跟踪的开源产品。它和 Jaeger 的功能大体相当,首先可以接收从被跟踪目标通过 OpenTelemetry 或 ZIPKIN 发送的跟踪数据,然后集中保存跟踪数据,最后通过 Jaeger 或 Grafana 界面进行展现。
Tempo 和 Jaeger 相比较大的区别是 Jaeger 一般使用诸如 Elasticsearch 这样的数据库来保存其接收到的跟踪数据,而 Tempo 则直接使用对象存储保存其接收到的跟踪数据。
OpenShift 4 - 可观测性之用 OpenTelemetry+Tempo 实现 Distributed Tracing_第1张图片

部署 Distributed Tracing 运行环境

安装 minio 环境

  1. 创建一个项目
$ oc new-project tempo-demo
  1. 根据以下 YAML 部署 minio 资源。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  labels:
    app.kubernetes.io/name: minio
  name: minio
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: minio
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: minio
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app.kubernetes.io/name: minio
    spec:
      containers:
        - command:
            - /bin/sh
            - -c
            - |
              mkdir -p /storage/tempo && \
              minio server /storage
          env:
            - name: MINIO_ACCESS_KEY
              value: tempo
            - name: MINIO_SECRET_KEY
              value: supersecret
          image: minio/minio
          name: minio
          ports:
            - containerPort: 9000
          volumeMounts:
            - mountPath: /storage
              name: storage
      volumes:
        - name: storage
          persistentVolumeClaim:
            claimName: minio
---
apiVersion: v1
kind: Service
metadata:
  name: minio
spec:
  ports:
    - port: 9000
      protocol: TCP
      targetPort: 9000
  selector:
    app.kubernetes.io/name: minio
  type: ClusterIP

安装 Grafana Tempo 环境

  1. 使用缺省配置安装由 Red Hat 发布的 Tempo Operator。
  2. 根据以下 YAML 创建能访问 minio 服务的 Secret。
apiVersion: v1
kind: Secret
metadata:
  name: minio
stringData:
  endpoint: http://minio.tempo-demo.svc:9000
  bucket: tempo
  access_key_id: tempo
  access_key_secret: supersecret
type: Opaque
  1. 根据以下 YAML 创建一个 TempoStack 实例,其中用到上一步创建的 Secret。
apiVersion: tempo.grafana.com/v1alpha1
kind: TempoStack
metadata:
  name: my-tempo
spec:
  storage:
    secret:
      name: minio
      type: s3
  storageSize: 1Gi
  resources:
    total:
      limits:
        memory: 2Gi
        cpu: 2000m
  template:
    queryFrontend:
      jaegerQuery:
        enabled: true
  1. 查看 Tempo 相关部署。
$ oc get deploy -l app.kubernetes.io/name=tempo
NAME                            READY   UP-TO-DATE   AVAILABLE   AGE
tempo-my-tempo-compactor        1/1     1            1           14m
tempo-my-tempo-distributor      1/1     1            1           14m
tempo-my-tempo-querier          1/1     1            1           14m
tempo-my-tempo-query-frontend   1/1     1            1           14m
  1. 查看 Tempo 相关服务,其中 tempo-my-tempo-distributor 是应用端的 OTEL 将跟踪到的数据推送的目标服务。
$ oc get svc -l app.kubernetes.io/name=tempo
NAME                                      TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                                          AGE
tempo-my-tempo-compactor                  ClusterIP   10.217.4.119   <none>        7946/TCP,3200/TCP                                16m
tempo-my-tempo-distributor                ClusterIP   10.217.5.226   <none>        4317/TCP,3200/TCP                                16m
tempo-my-tempo-gossip-ring                ClusterIP   None           <none>        7946/TCP                                         16m
tempo-my-tempo-ingester                   ClusterIP   10.217.4.249   <none>        3200/TCP,9095/TCP                                16m
tempo-my-tempo-querier                    ClusterIP   10.217.4.88    <none>        7946/TCP,3200/TCP,9095/TCP                       16m
tempo-my-tempo-query-frontend             ClusterIP   10.217.4.144   <none>        3200/TCP,9095/TCP,16686/TCP,16687/TCP            16m
tempo-my-tempo-query-frontend-discovery   ClusterIP   None           <none>        3200/TCP,9095/TCP,9096/TCP,16686/TCP,16687/TCP   16m
  1. 而 tempo-my-tempo-query-frontend 则是 Jaeger 的控制台,可以根据将其服务生成 Route,然后用浏览器访问 Route 地址。
$ oc expose service tempo-my-tempo-query-frontend --port=16686
$ oc get route tempo-my-tempo-query-frontend -o jsonpath='{.spec.host}'
tempo-my-tempo-query-frontend-tempo-demo.apps.cluster-6htgt.6htgt.sandbox2251.opentlc.com

部署测试应用并进行观测跟踪

测试应用1

  1. 执行以下命令,运行一个测试应用。
    说明:测试应用使用了手动 Instrumentation 方式获取的跟踪数据,应用代码参见 https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/tracegen/v0.55.0/tracegen/main.go
    注意:跟踪数据推送到 Tempo 的 tempo-my-tempo-distributor:4317 接收服务。
$ oc apply -f - <apiVersion: batch/v1
kind: Job
metadata:
  name: tracegen
spec:
  template:
    spec:
      containers:
        - name: tracegen
          image: ghcr.io/open-telemetry/opentelemetry-collector-contrib/tracegen:latest
          command:
            - "./tracegen"
          args:
            - -otlp-endpoint=tempo-my-tempo-distributor:4317
            - -otlp-insecure
            - -duration=300s
            - -workers=1
      restartPolicy: Never
  backoffLimit: 4
EOF
  1. 刷新 Jaeger 控制台,选择 tracegen 服务后可以看到对该请求的跟踪情况。
    OpenShift 4 - 可观测性之用 OpenTelemetry+Tempo 实现 Distributed Tracing_第2张图片
    OpenShift 4 - 可观测性之用 OpenTelemetry+Tempo 实现 Distributed Tracing_第3张图片

测试应用2

  1. 基于以下 YAML 部署测试应用。
    说明:测试应用使用了手动 Instrumentation 方式获取的跟踪数据,应用代码参见 https://github.com/rbaumgar/otelcol-demo-app/blob/main/src/main/java/org/acme/opentelemetry/TracedResource.java
    注意:其中在 Deployment 中对 OTELCOL_SERVER 参数使用了以上 tempo-my-tempo-distributor 服务的地址。
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: otel-demo-app
  name: otel-demo-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: otel-demo-app
  template:
    metadata:
      labels:
        app: otel-demo-app
    spec:
      containers:
        - image: quay.io/rbaumgar/otelcol-demo-app-jvm
          imagePullPolicy: IfNotPresent
          name: otel-demo-app
          env:
            - name: OTELCOL_SERVER
              value: 'http://tempo-my-tempo-distributor:4317'  
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: otel-demo-app
  name: otel-demo-app
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
    name: web
  selector:
    app: otel-demo-app
  type: ClusterIP
---
apiVersion: route.openshift.io/v1
kind: Route
metadata:
  labels:
    app: otel-demo-app
  name: otel-demo-app
spec:
  path: /
  to:
    kind: Service
    name: otel-demo-app
  port:
    targetPort: web
  1. 执行以下命令访问测试应用。
$ export URL=$(oc get route otel-demo-app -o jsonpath='{.spec.host}')
$ curl $URL/hello
hello 
$ curl $URL/sayHello/demo1
hello: demo1
$ curl $URL/sayRemote/demo2
hello: demo2 from http://otel-demo-app-tempo-demo.apps-crc.testing/

OpenShift 4 - 可观测性之用 OpenTelemetry+Tempo 实现 Distributed Tracing_第4张图片

OpenShift 4 - 可观测性之用 OpenTelemetry+Tempo 实现 Distributed Tracing_第5张图片

参考

https://tempo-operator.netlify.app/docs/prologue/quickstart.md/

你可能感兴趣的:(openshift)