首页 / 平台管理 / 网络管理 / 负载均衡器 / 配置 OpenTelemetry (OTel)

配置 OpenTelemetry (OTel)

OpenTelemetry(OTel)是一个开源项目,旨在为分布式系统(如微服务架构)提供一个厂商中立的标准,用于收集、处理和导出遥测数据,它支持开发人员更轻松地分析软件的性能和行为,从而更容易地诊断和排除应用问题。

名词解释

名词 解释
Trace 提交到 OTel Server 的数据,是一系列相关的事件或操作的集合,用于跟踪请求在分布式系统中的流动,每个 Trace 由多个 Span 组成。
Span Trace 中的一个独立的操作或事件,包含开始时间、持续时间和其他相关信息。
OTel Server OTel 服务器,能够接收和存储 Trace 数据的服务器,例如 Jaeger、Prometheus 等。
Jaeger 一个开源的分布式追踪系统,用于监控和故障排除微服务架构,支持与 OpenTelemetry 集成。
Attributes 附加在 Trace 或 Span 上的键值对,用于提供更多上下文信息。包括资源属性(Resource Attributes)和 Span 属性(Span Attributes),具体请参考 Attributes
Sampler 决定是否采集和上报 Trace 的策略组件。可以配置不同的采样策略,例如全量采样、比例采样等。
ALB(Another Load Balancer) 是一种把网络请求分散到一个集群中的可用节点上的软件或硬件设备,平台中使用的负载均衡器(ALB)为七层软件负载均衡器,可以配置 OTel 以监控流量。ALB 支持提交 Trace 到指定 Collector 上,支持不同的采样策略,支持在 Ingress 级别单独配置是否提交 Trace。
FT(Frontend) ALB 的端口配置,指定端口级别的配置。
Rule 端口(FT)上的路由规则,用来匹配具体的路由。
HotROD(Rides on Demand) 是 Jaeger 提供的一个示例应用程序,用于演示分布式追踪的使用,具体说明请参考 Hot R.O.D. - Rides on Demand
hotrod-with-proxy 通过环境变量指定 HotROD 内部各微服务地址,具体请参考 hotrod-with-proxy

前提条件

操作步骤

更新 ALB 配置

  1. 在集群 Master 节点上,使用 CLI 工具执行下述命令编辑 ALB 配置。

    kubectl edit alb2 -n cpaas-system <otel-alb> # 需使用 ALB 名称替换 <otel-alb> 部分
  2. spec.config 字段下添加下述字段。

    otel:
      enable: true
      exporter:
        collector:
          address: "<jaeger-server>" # 需使用 OTel 数据上报的服务器地址替换 <jaeger-server> 部分
          request_timeout: 1000

    配置完成示例:

    spec:
      address: 192.168.1.1
      config:
        otel:
         enable: true
         exporter:
           collector:
             address: "http://jaeger.default.svc.cluster.local:4318"
             request_timeout: 1000
        antiAffinityKey: system
        defaultSSLCert: cpaas-system/cpaas-system
        defaultSSLStrategy: Both
        gateway:
        ...
    type: nginx
  3. 执行下述命令保存更新。更新完成后,ALB 将默认开启 OpenTelemetry,并将所有请求的 Trace 信息上报至 Jaeger Server。

    :wq

相关操作

在 Ingress 中配置 OTel

在应用中使用 OTel

下述配置展示了完整的 OTel 配置结构,可以用于定义如何在应用中启用和使用 OTel 功能。

可以在集群 Master 节点上,使用 CLI 工具执行下述命令获取 OTel 的完整配置结构。

kubectl get crd alaudaloadbalancer2.crd.alauda.io -o json|jq ".spec.versions[2].schema.openAPIV3Schema.properties.spec.properties.config.properties.otel"

回显结果:

{
    "otel": {
        "enable": true
    }
    "exporter": {
        "collector": {
            "address": ""
          },
    },
    "flags": { 
        "hide_upstream_attrs": false
        "notrust_incoming_span": false
        "report_http_request_header": false
        "report_http_response_header": false
    },
    "sampler": {
        "name": "", 
        "options": {
            "fraction": ""
            "parent_name": ""
          },
      },
 }

参数说明:

参数 说明
otel.enable 是否启用 OTel 功能。
exporter.collector.address OTel 数据上报的服务器地址,支持 http/https 协议,支持域名。
flags.hide_upstream_attrs 是否上报关于 upstream(上游) 的规则的信息。
flag.notrust_incoming_span 是否信任和使用传入请求中的 OTel 的 Trace 信息(例如 trace ID)。
flags.report_http_request_header 是否上报请求 Header。
flags.report_http_response_header 是否上报响应 Header。
sampler.name 采样策略名,具体请参考 采样策略
sampler.options.fraction 采样率。
sampler.options.parent_name parent_base 采样策略的 parent 策略。

继承

默认情况下,若 ALB 配置了某些 OTel 参数,而 FT 未配置,则 FT 会使用 ALB 的参数作为自己的配置项,即 FT 继承了 ALB 的配置,而 Rule 可以继承 ALB 和 FT 的配置。

操作步骤

通过配置 ALB、FT、Rule 的 YAML 文件中 spec.config.otel 字段,可以增加 OTel 的相关配置。

相关说明

采样策略

参数 说明
always on 始终上报所有追踪数据。
always off 永不上报追踪数据。
traceid-ratio 根据 traceid 决定是否上报。traceparent 的格式为 xx-traceid-xx-flag,其中 traceid 的前 16 个字符表示一个 32 位的十六进制整数。如果该整数小于 fraction 乘以 4294967295(即 (2^32-1)),则进行上报。
parent-base 根据请求的 traceparent 中的 flag 部分决定是否上报。当 flag 为 01 时上报,例如:curl -v "http://$ALB_IP/" -H 'traceparent: 00-xx-xx-01';当 flag 为 02 时不上报,例如:curl -v "http://$ALB_IP/" -H 'traceparent: 00-xx-xx-02'

Attributes

配置示例

在下面的 YAML 配置中,部署了一个 ALB,并使用 Jaeger 作为 OTel 服务器,Hotrod-proxy 作为演示后端。通过配置 Ingress 规则,当客户端请求 ALB 时,流量会被转发到 HotROD。同时,HotROD 内部的微服务之间的通信也通过 ALB 进行转发。

  1. 将下述 YAML 保存至名称为 all.yaml 的文件中。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hotrod
    spec:
      replicas: 1
      selector:
        matchLabels:
          service.cpaas.io/name: hotrod
          service_name: hotrod
      template:
        metadata:
          labels:
            service.cpaas.io/name: hotrod
            service_name: hotrod
        spec:
          containers:
            - name: hotrod
              env:
                - name: PROXY_PORT
                  value: "80"
                - name: PROXY_ADDR
                  value: "otel-alb.default.svc.cluster.local:"
                - name: OTEL_EXPORTER_OTLP_ENDPOINT
                  value: "http://jaeger.default.svc.cluster.local:4318"
              image: theseedoaa/hotrod-with-proxy:latest
              imagePullPolicy: IfNotPresent
              command: ["/bin/hotrod","all","-v"]
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: hotrod-frontend
    spec:
      ingressClassName: otel-alb
      rules:
      - http:
          paths:
          - backend:
              service:
                name: hotrod
                port:
                  number: 8080
            path: /dispatch
            pathType: ImplementationSpecific
          - backend:
              service:
                name: hotrod
                port:
                  number: 8080
            path: /frontend
            pathType: ImplementationSpecific
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: hotrod-customer
    spec:
      ingressClassName: otel-alb
      rules:
      - http:
          paths:
          - backend:
              service:
                name: hotrod
                port:
                  number: 8081
            path: /customer
            pathType: ImplementationSpecific
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: hotrod-route
    spec:
      ingressClassName: otel-alb
      rules:
      - http:
          paths:
          - backend:
              service:
                name: hotrod
                port:
                  number: 8083
            path: /route
            pathType: ImplementationSpecific
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: hotrod
    spec:
      internalTrafficPolicy: Cluster
      ipFamilies:
        - IPv4
      ipFamilyPolicy: SingleStack
      ports:
        - name: frontend
          port: 8080
          protocol: TCP
          targetPort: 8080
        - name: customer
          port: 8081
          protocol: TCP
          targetPort: 8081
        - name: router
          port: 8083
          protocol: TCP
          targetPort: 8083
      selector:
        service_name: hotrod
      sessionAffinity: None
      type: ClusterIP
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: jaeger
    spec:
      replicas: 1
      selector:
        matchLabels:
          service.cpaas.io/name: jaeger
          service_name: jaeger
      template:
        metadata:
          labels:
            service.cpaas.io/name: jaeger
            service_name: jaeger
        spec:
          containers:
            - name: jaeger
              env:
               - name: LOG_LEVEL
                 value: debug
              image: jaegertracing/all-in-one:1.58.1
              imagePullPolicy: IfNotPresent
          hostNetwork: true
          tolerations:
            - operator: Exists
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: jaeger
    spec:
      internalTrafficPolicy: Cluster
      ipFamilies:
        - IPv4
      ipFamilyPolicy: SingleStack
      ports:
        - name: http
          port: 4318
          protocol: TCP
          targetPort: 4318
      selector:
        service_name: jaeger
      sessionAffinity: None
      type: ClusterIP
    ---
    apiVersion: crd.alauda.io/v2
    kind: ALB2
    metadata:
      name: otel-alb
    spec:
      config:
        loadbalancerName: otel-alb
        otel:
          enable: true
          exporter:
            collector:
              address: "http://jaeger.default.svc.cluster.local:4318"
              request_timeout: 1000
        projects:
        - ALL_ALL
        replicas: 1
        resources:
          alb:
            limits:
              cpu: 200m
              memory: 2Gi
            requests:
              cpu: 50m
              memory: 128Mi
          limits:
            cpu: "1"
            memory: 1Gi
          requests:
            cpu: 50m
            memory: 128Mi
      type: nginx
  2. 在 CLI 工具中执行下述命令部署 Jaeger、ALB、HotROD 以及测试需要的所有 CR。

    kubectl apply ./all.yaml
  3. 执行下述命令获取 Jaeger 的访问地址。

    export JAEGER_IP=$(kubectl get po -A -o wide |grep jaeger | awk '{print $7}');echo "http://$JAEGER_IP:16686"
  4. 执行下述命令获取 otel-alb 的访问地址。

    export ALB_IP=$(kubectl get po -A -o wide|grep otel-alb | awk '{print $7}');echo $ALB_IP
  5. 执行下述命令通过 ALB 向 HotROD 发送请求。其中,ALB 会将 Trace 上报到 Jaeger 中。

    curl -v "http://<$ALB_IP>:80/dispatch?customer=567&nonse=" # 使用上述步骤中获取的 otel-alb 访问地址替换命令中的 <$ALB_IP> 部分
  6. 打开 步骤 3 中获取的 Jaeger 的访问地址查看结果。