OTel

OpenTelemetry (OTel) — это проект с открытым исходным кодом, направленный на предоставление независимого от поставщика стандарта для сбора, обработки и экспорта телеметрических данных в распределённых системах, таких как архитектуры микросервисов. Он помогает разработчикам проще анализировать производительность и поведение программного обеспечения, что облегчает диагностику и устранение проблем в приложениях.

Содержание

Терминология

ТерминОбъяснение
TraceДанные, отправляемые на OTel Server, представляющие собой набор связанных событий или операций, используемых для отслеживания потока запросов в распределённых системах; каждый Trace состоит из нескольких Spans.
SpanНезависимая операция или событие внутри Trace, включающая время начала, длительность и другую релевантную информацию.
OTel ServerСервер OTel, способный принимать и хранить данные Trace, например Jaeger, Prometheus и др.
JaegerСистема распределённого трассирования с открытым исходным кодом, используемая для мониторинга и отладки архитектур микросервисов, поддерживающая интеграцию с OpenTelemetry.
AttributesПары ключ-значение, прикреплённые к Trace или Span для предоставления дополнительной контекстной информации. Включает Resource Attributes и Span Attributes; см. Attributes для подробностей.
SamplerКомпонент стратегии, определяющий, следует ли сэмплировать и отправлять Trace. Можно настроить различные стратегии сэмплирования, такие как полное сэмплирование, пропорциональное и др.
ALB (Another Load Balancer)Программное или аппаратное устройство, распределяющее сетевые запросы между доступными узлами в кластере; балансировщик нагрузки (ALB), используемый на платформе, является программным балансировщиком уровня 7, который можно настроить для мониторинга трафика с помощью OTel. ALB поддерживает отправку Trace на указанный Collector и позволяет использовать разные стратегии сэмплирования; также поддерживает настройку отправки Trace на уровне Ingress.
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: Создайте или используйте существующий ALB, имя которого в данном документе заменено на <otel-alb>. Инструкции по созданию ALB см. в Deploy ALB.

  • Убедитесь, что имеется адрес сервера отчёта данных OTel: Этот адрес далее будет называться <jaeger-server>.

Процедура

Обновление конфигурации ALB

  1. На Master-узле кластера используйте CLI для выполнения команды редактирования конфигурации ALB:

    kubectl edit alb2 -n cpaas-system <otel-alb> # Замените <otel-alb> на фактическое имя ALB
  2. Добавьте следующие поля в раздел spec.config:

    otel:
      enable: true
      exporter:
        collector:
          address: "<jaeger-server>" # Замените <jaeger-server> на фактический адрес сервера отчёта данных OTel
          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. Выполните команду для сохранения изменений:

    :wq

    После обновления ALB по умолчанию будет включён OpenTelemetry, и вся информация о Trace запросов будет отправляться на Jaeger Server.

Связанные операции

Настройка OTel в Ingress

  • Включение или отключение OTel на Ingress

    Настройка включения OTel на Ingress позволяет лучше мониторить и отлаживать поток запросов приложений, выявляя узкие места производительности или ошибки путём трассировки запросов при их прохождении между сервисами.

    Процедура

    Добавьте следующую аннотацию в поле metadata.annotations Ingress:

    nginx.ingress.kubernetes.io/enable-opentelemetry: "true"

    Объяснение параметра:

    • nginx.ingress.kubernetes.io/enable-opentelemetry: При значении true контроллер Ingress включает функциональность OpenTelemetry при обработке запросов через этот Ingress, что означает сбор и отправку информации о Trace запросов. При значении false или отсутствии этой аннотации сбор и отправка Trace не выполняются.
  • Включение или отключение доверия OTel на Ingress

    OTel Trust определяет, доверяет ли Ingress и использует ли информацию Trace (например, trace ID) из входящих запросов.

    Процедура

    Добавьте следующую аннотацию в поле metadata.annotations Ingress:

    nginx.ingress.kubernetes.io/opentelemetry-trust-incoming-span: "true"

    Объяснение параметра:

    • nginx.ingress.kubernetes.io/opentelemetry-trust-incoming-span: При значении true Ingress продолжает использовать уже существующую информацию Trace, что помогает поддерживать согласованность в межсервисном трассировании, позволяя полностью проследить и проанализировать всю цепочку запросов в системе распределённого трассирования. При значении false для запроса будет сгенерирована новая информация трассировки, что может привести к тому, что запрос будет рассматриваться как часть новой цепочки трассировки после входа в Ingress, прерывая непрерывность межсервисного трассирования.
  • Добавление различных конфигураций OTel на Ingress

    Эта настройка позволяет кастомизировать поведение OTel и методику экспорта данных для разных ресурсов Ingress, обеспечивая тонкий контроль над стратегией трассирования или целевым назначением для каждого сервиса.

    Процедура

    Добавьте следующую конфигурацию в поле metadata.annotations Ingress:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
        alb.ingress.cpaas.io/otel: >
          {
             "enable": true,
             "exporter": {
                 "collector": {
                     "address": "<jaeger-server>", # Замените <jaeger-server> на фактический адрес сервера отчёта данных OTel, например "address": "http://128.0.0.1:4318"
                     "request_timeout": 1000
                 }
             }
          }

    Объяснение параметров:

    • exporter: Определяет способ отправки собранных данных Trace на OTel Collector (сервер отчёта данных OTel).
    • address: Адрес OTel Collector.
    • request_timeout: Таймаут запроса.

Использование 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Доверие и использование информации Trace OTel (например, trace ID) из входящих запросов.
flags.report_http_request_headerОтчёт заголовков запросов.
flags.report_http_response_headerОтчёт заголовков ответов.
sampler.nameИмя стратегии сэмплирования; подробности см. в Sampling Strategies.
sampler.options.fractionДоля сэмплирования.
sampler.options.parent_nameРодительская стратегия для стратегий parent_base.

Наследование

По умолчанию, если в ALB настроены определённые параметры OTel, а в FT они не настроены, FT наследует параметры от ALB как свою конфигурацию; то есть FT наследует конфигурацию ALB, а Rule может наследовать конфигурации как от ALB, так и от FT.

  • ALB: Конфигурация на ALB обычно глобальная и по умолчанию. Здесь можно настроить глобальные параметры, например адреса Collector, которые будут унаследованы нижестоящими FT и Rule.

  • FT: FT может наследовать конфигурации от ALB, то есть параметры OTel, не настроенные в FT, будут использовать настройки ALB. При этом FT можно дополнительно уточнять; например, можно выборочно включать или отключать OTel на FT без влияния на другие FT или глобальные настройки ALB.

  • Rule: Rule может наследовать конфигурации как от ALB, так и от FT. При этом Rule также можно уточнять; например, конкретное правило может отказаться от доверия входящей информации Trace OTel или изменить стратегии сэмплирования.

Процедура

Настройте поле spec.config.otel в YAML-файлах ALB, FT и Rule для добавления конфигурации, связанной с OTel.

Дополнительные сведения

Стратегии сэмплирования

ПараметрОбъяснение
always onВсегда отправлять все данные трассировки.
always offНикогда не отправлять данные трассировки.
traceid-ratioРешение об отправке принимается на основе traceid. Формат traceparentxx-traceid-xx-flag, где первые 16 символов traceid представляют 32-битное шестнадцатеричное число. Если это число меньше fraction, умноженного на 4294967295 (то есть (2^32-1)), данные будут отправлены.
parent-baseРешение об отправке принимается на основе флага в traceparent запроса. При флаге 01 данные отправляются; например: curl -v "http://$ALB_IP/" -H 'traceparent: 00-xx-xx-01'. При флаге 02 данные не отправляются; например: curl -v "http://$ALB_IP/" -H 'traceparent: 00-xx-xx-02'.

Атрибуты

  • Resource Attributes

    Эти атрибуты отправляются по умолчанию.

    ПараметрОписание
    hostnameИмя хоста Pod ALB
    service.nameИмя ALB
    service.namespaceПространство имён, где расположен ALB
    service.typeПо умолчанию ALB
    service.instance.idИмя Pod ALB
  • Span Attributes

    • Атрибуты, отправляемые по умолчанию:

      ПараметрОписание
      http.status_codeКод состояния
      http.request.resend_countКоличество повторных попыток
      alb.rule.rule_nameИмя правила, с которым совпал данный запрос
      alb.rule.source_typeТип правила, с которым совпал запрос, в настоящее время только Ingress
      alb.rule.source_nameИмя Ingress
      alb.rule.source_nsПространство имён, где расположен Ingress
    • Атрибуты, отправляемые по умолчанию, но могут быть исключены изменением поля flag.hide_upstream_attrs:

      ПараметрОписание
      alb.upstream.svc_nameИмя Service (внутреннего маршрута), на который перенаправляется трафик
      alb.upstream.svc_nsПространство имён Service (внутреннего маршрута), на который перенаправляется трафик
      alb.upstream.peerIP-адрес и порт Pod, на который перенаправляется трафик
    • Атрибуты, не отправляемые по умолчанию, но могут быть отправлены изменением поля flag.report_http_request_header:

      ПараметрОписание
      **http.request.header.<header>**Заголовок запроса
    • Атрибуты, не отправляемые по умолчанию, но могут быть отправлены изменением поля flag.report_http_response_header:

      ПараметрОписание
      **http.response.header.<header>**Заголовок ответа

Пример конфигурации

Ниже приведена 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. Выполните команду для отправки запроса к HotROD через ALB. ALB при этом отправит Trace в Jaeger.

    curl -v "http://<$ALB_IP>:80/dispatch?customer=567&nonse=" # Замените <$ALB_IP> в команде на адрес доступа otel-alb, полученный на предыдущем шаге
  6. Откройте адрес доступа Jaeger, полученный в Шаге 3, чтобы просмотреть результаты.