Home / Platform management / Networking / Load balancers / Configure OpenTelemetry (OTel)

Configure OpenTelemetry (OTel)

OpenTelemetry (OTel) is an open-source project designed to provide a vendor-neutral standard for distributed systems (such as microservice architectures) to collect, process, and export telemetry data. It supports developers in analyzing software performance and behavior more easily, making it easier to diagnose and troubleshoot application issues.

Terminology

Term Explanation
Trace Data submitted to the OTel Server, a collection of related events or operations used to track the flow of requests in a distributed system. Each Trace consists of multiple Spans.
Span An independent operation or event within a Trace, containing start time, duration, and other relevant information.
OTel Server The OTel server capable of receiving and storing Trace data, such as Jaeger, Prometheus, etc.
Jaeger An open-source distributed tracing system used for monitoring and troubleshooting microservice architectures, supporting integration with OpenTelemetry.
Attributes Key-value pairs attached to Traces or Spans to provide more contextual information, including Resource Attributes and Span Attributes. See Attributes for more details.
Sampler A policy component that decides whether to collect and report Traces. Different sampling strategies can be configured, such as full sampling, proportional sampling, etc.
ALB (Another Load Balancer) A software or hardware device that distributes network requests to available nodes in a cluster. The load balancer (ALB) used in the platform is a Layer 7 software load balancer that can be configured with OTel to monitor traffic. ALB supports submitting Traces to a specified Collector, supports different sampling strategies, and can configure whether to submit Traces at the Ingress level.
FT (Frontend) ALB port configuration, specifying port-level configurations.
Rule Routing rules on the port (FT) used to match specific routes.
HotROD (Rides on Demand) A sample application provided by Jaeger to demonstrate the use of distributed tracing. For more details, see Hot R.O.D. - Rides on Demand .
hotrod-with-proxy Specifies the addresses of various microservices inside HotROD through environment variables. See hotrod-with-proxy for more details.

Prerequisites

Steps

Update ALB Configuration

  1. On the Master node of the cluster, use the CLI tool to execute the following command to edit the ALB configuration.

    kubectl edit alb2 -n cpaas-system <otel-alb> # Replace <otel-alb> with the ALB name
  2. Add the following fields under the spec.config field.

    otel:
      enable: true
      exporter:
        collector:
          address: "<jaeger-server>" # Replace <jaeger-server> with the server address for OTel data reporting
          request_timeout: 1000

    Sample configuration:

    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. Execute the following command to save the update. Once updated, the ALB will enable OpenTelemetry by default and report all request Trace information to the Jaeger Server.

    :wq

Configure OTel in Ingress

Use OTel in Applications

The following configuration shows the complete OTel configuration structure, which can be used to define how to enable and use OTel features in applications.

You can execute the following command on the cluster’s Master node using the CLI tool to obtain the complete configuration structure for OTel.

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

Output result:

{
    "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": ""
          },
      },
 }

Parameter Explanation:

Parameter Explanation
otel.enable Whether to enable OTel features.
exporter.collector.address The server address for OTel data reporting, supporting http/https protocols and domain names.
flags.hide_upstream_attrs Whether to report information about upstream rules.
flags.notrust_incoming_span Whether to trust and use the OTel Trace information (such as trace ID) in incoming requests.
flags.report_http_request_header Whether to report the request header.
flags.report_http_response_header Whether to report the response header.
sampler.name The name of the sampling strategy, please refer to Sampling Strategy for details.
sampler.options.fraction Sampling rate.
sampler.options.parent_name The parent strategy of the parent_base sampling strategy.

Inheritance

By default, if certain OTel parameters are configured on the ALB and not on the FT, the FT will use the ALB’s parameters as its own configuration, meaning the FT inherits the ALB’s configuration. Similarly, Rules can inherit configurations from both ALB and FT.

Operational Steps

You can add relevant OTel configurations by configuring the spec.config.otel field in the YAML files of ALB, FT, and Rule.

Sampling Strategy

Parameter Explanation
always on Always report all trace data.
always off Never report trace data.
traceid-ratio Decides whether to report based on traceid. The format of traceparent is xx-traceid-xx-flag, where the first 16 characters of traceid represent a 32-bit hexadecimal integer. If this integer is less than fraction multiplied by 4294967295 (i.e., (2^32-1)), then it will be reported.
parent-base Decides whether to report based on the flag part of the traceparent in the request. When the flag is 01, it reports, e.g., curl -v "http://$ALB_IP/" -H 'traceparent: 00-xx-xx-01'; when the flag is 02, it does not report, e.g., curl -v "http://$ALB_IP/" -H 'traceparent: 00-xx-xx-02'.

Attributes

Configuration Example

In the YAML configuration below, an ALB is deployed using Jaeger as the OTel server and Hotrod-proxy as the demo backend. By configuring Ingress rules, when a client requests the ALB, the traffic will be forwarded to HotROD. Meanwhile, communication between microservices within HotROD is also forwarded through the ALB.

  1. Save the following YAML to a file named 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. Execute the following command in the CLI tool to deploy Jaeger, ALB, HotROD, and all CRs needed for testing.

    kubectl apply -f ./all.yaml
  3. Execute the following command to get the access address for Jaeger.

    export JAEGER_IP=$(kubectl get po -A -o wide | grep jaeger | awk '{print $7}'); echo "http://$JAEGER_IP:16686"
  4. Execute the following command to get the access address for otel-alb.

    export ALB_IP=$(kubectl get po -A -o wide | grep otel-alb | awk '{print $7}'); echo $ALB_IP
  5. Execute the following command to send a request to HotROD through the ALB. The ALB will report the Trace to Jaeger.

    curl -v "http://<$ALB_IP>:80/dispatch?customer=567&nonse=" # Replace the <$ALB_IP> part in the command with the otel-alb access address obtained in the previous step
  6. Open the Jaeger access address obtained in Step 3 to view the results.