• Русский
  • 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 см. в разделе Creating Load Balancer.

    • Убедитесь, что имеется адрес сервера отчётов данных 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. Выполните команду для сохранения изменений. После обновления ALB по умолчанию будет включён OpenTelemetry, и вся информация о Trace запросов будет отправляться на Jaeger Server.

      :wq

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

    Настройка 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Отчёт заголовков HTTP-запроса.
    flags.report_http_response_headerОтчёт заголовков HTTP-ответа.
    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, чтобы просмотреть результаты.