Сквозная наблюдаемость приложений ИИ в Kubernetes

Материал из Документация Ключ-АСТРОМ
Версия от 20:23, 29 января 2026; IKuznetsov (обсуждение | вклад) (Новая страница: «Современные приложения всё чаще разрабатываются на базе архитектуры микросервисов, кот...»)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)

Современные приложения всё чаще разрабатываются на базе архитектуры микросервисов, которые обычно развёртываются в среде Kubernetes. AI‑агенты и приложения, как правило, встраиваются в один или несколько таких микросервисов. Распределенные трассировки подобных систем создаёт сложности при мониторинге, диагностике неполадок и оптимизации производительности множества взаимосвязанных сервисов. Ключ-АСТРОМ упрощает решение этих задач, обеспечивая комплексную сквозную наблюдаемость приложений, работающих в Kubernetes.

Что вы узнаете

В этом руководстве мы:

  • Настроим рабочую среду;
  • Разберём, как платформа Ключ-АСТРОМ обеспечивает сквозную наблюдаемость AI‑приложений в Kubernetes.

В качестве основного механизма мы будем использовать OpenTelemetry/OpenLLMetry для передачи специфичных для GenAI телеметрических данных (трассировок и метрик — таких как модели, токены, задержки и затраты) в Ключ-АСТРОМ.

ЕдиныйАгент дополняет это, предоставляя полный контекст Kubernetes и приложений (состояние инфраструктуры, обнаружение рабочих нагрузок/процессов, логи, видимость на уровне кода, уязвимости), а также сопоставляя трассировки OTEL с сервисами, проблемами и аналитическими данными Ключ-АСТРОМ ИИ.

Конфигурация

1. Настройте свою среду

  • Убедитесь, что в вашей среде Kubernetes включена функция Full-Stack Observability.
  • Включить обнаружение сервисов v2 для Kubernetes.

2. Разверните коллектор Ключ-АСТРОМ.

Для производственных нагрузок рекомендуется также направлять трафик OpenLLMetry через коллектор OpenTelemetry. Коллектор предоставляет функции выборки, которые помогают контролировать стоимость данных OpenTelemetry.

  • Сохраните следующий YAML-файл конфигурации как values.yaml
mode: deployment

image:

  repository: ghcr.io/astromkey/astromkey-otel-collector/astromkey-otel-collector

  tag: 0.33.0

command:

  name: astromkey-otel-collector

extraEnvs:

- name: DT_API_TOKEN

  valueFrom:

    secretKeyRef:

      name: astromkey-otelcol-dt-api-credentials

      key: DT_API_TOKEN

- name: DT_ENDPOINT

  valueFrom:

    secretKeyRef:

      name: astromkey-otelcol-dt-api-credentials

      key: DT_ENDPOINT

resources:

  limits:

    memory: 512Mi

alternateConfig:

  extensions:

    health_check:

      endpoint: "${env:MY_POD_IP}:13133"

  processors:

    cumulativetodelta:

      max_staleness: 25h

    k8sattributes:

      extract:

        metadata:

          - k8s.pod.name

          - k8s.pod.uid

          - k8s.pod.ip

          - k8s.deployment.name

          - k8s.replicaset.name

          - k8s.statefulset.name

          - k8s.daemonset.name

          - k8s.job.name

          - k8s.cronjob.name

          - k8s.namespace.name

          - k8s.node.name

          - k8s.cluster.uid

          - k8s.container.name

        annotations:

          - from: pod

            key_regex: metadata.astromkey.com/(.*)

            tag_name: $$1

          - from: pod

            key: metadata.astromkey.com

            tag_name: metadata.astromkey.com

      pod_association:

        - sources:

          - from: resource_attribute

            name: k8s.pod.name

          - from: resource_attribute

            name: k8s.namespace.name

        - sources:

          - from: resource_attribute

            name: k8s.pod.ip

        - sources:

          - from: resource_attribute

            name: k8s.pod.uid

        - sources:

          - from: connection

    transform:

      error_mode: ignore

      trace_statements: &astromkey_transformations

        # Set attributes taken from k8s metadata.

        - context: resource

          statements:

            - set(attributes["k8s.workload.kind"], "job") where IsString(attributes["k8s.job.name"])

            - set(attributes["k8s.workload.name"], attributes["k8s.job.name"]) where IsString(attributes["k8s.job.name"])

            - set(attributes["k8s.workload.kind"], "cronjob") where IsString(attributes["k8s.cronjob.name"])

            - set(attributes["k8s.workload.name"], attributes["k8s.cronjob.name"]) where IsString(attributes["k8s.cronjob.name"])

            - set(attributes["k8s.workload.kind"], "daemonset") where IsString(attributes["k8s.daemonset.name"])

            - set(attributes["k8s.workload.name"], attributes["k8s.daemonset.name"]) where IsString(attributes["k8s.daemonset.name"])

            - set(attributes["k8s.workload.kind"], "statefulset") where IsString(attributes["k8s.statefulset.name"])

            - set(attributes["k8s.workload.name"], attributes["k8s.statefulset.name"]) where IsString(attributes["k8s.statefulset.name"])

            - set(attributes["k8s.workload.kind"], "replicaset") where IsString(attributes["k8s.replicaset.name"])

            - set(attributes["k8s.workload.name"], attributes["k8s.replicaset.name"]) where IsString(attributes["k8s.replicaset.name"])

            - set(attributes["k8s.workload.kind"], "deployment") where IsString(attributes["k8s.deployment.name"])

            - set(attributes["k8s.workload.name"], attributes["k8s.deployment.name"]) where IsString(attributes["k8s.deployment.name"])

            # remove the delete statements if you want to preserve these attributes

            - delete_key(attributes, "k8s.deployment.name")

            - delete_key(attributes, "k8s.replicaset.name")

            - delete_key(attributes, "k8s.statefulset.name")

            - delete_key(attributes, "k8s.daemonset.name")

            - delete_key(attributes, "k8s.cronjob.name")

            - delete_key(attributes, "k8s.job.name")

        # Set attributes from metadata specified in astromkey and set through the astromkey Operator.

        # For more info: https://docs.astromkey.com/docs/shortlink/k8s-metadata-telemetry-enrichment

        - context: resource

          statements:

            - merge_maps(attributes, ParseJSON(attributes["metadata.astromkey.com"]), "upsert") where IsMatch(attributes["metadata.astromkey.com"], "^\\{")

            - delete_key(attributes, "metadata.astromkey.com")

      metric_statements: *astromkey_transformations

      log_statements: *astromkey_transformations

  receivers:

    otlp:

      protocols:

        grpc:

          endpoint: ${env:MY_POD_IP}:4317

        http:

          endpoint: ${env:MY_POD_IP}:4318

    filelog: null

  exporters:

    otlphttp:

      endpoint: "${env:DT_ENDPOINT}"

      headers:

        Authorization: "Api-Token ${env:DT_API_TOKEN}"

  service:

    extensions: [health_check]

    pipelines:

      traces:

        receivers: [otlp]

        processors: [k8sattributes, transform]

        exporters: [otlphttp]

      metrics:

        receivers: [otlp]

        processors: [k8sattributes, transform, cumulativetodelta]

        exporters: [otlphttp]

      logs:

        receivers: [otlp]

        processors: [k8sattributes, transform]

        exporters: [otlphttp]

  • Выполните следующие команды для настройки и установки коллектора OpenTelemetry.
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts

helm repo update

helm upgrade -i astromkey-collector open-telemetry/opentelemetry-collector -f values.yaml

3. Инструментируйте свой код

  • Создайте токен Ключ-АСТРОМ, чтобы OpenLLMetry мог передавать данные в ваш клиент Клюс-АСТРОМ.

Для создания токена Ключ-АСТРОМ

  1. В Ключ-АСТРОМ перейдите в раздел Токены доступа.
    Чтобы найти Токены доступа, нажмите Ctrl/Cmd+K для поиска и выберите Токены доступа.
  2. В разделе Токены доступа выберите Сгенерировать новый токен.
  3. Введите имя для вашего нового токена.
  4. Предоставьте своему новому токену следующие права доступа:
  5. Найдите и выберите все следующие области применения.
    • Метрики приема (metrics.ingest)
    • Логи загрузки (logs.ingest)
    • Приём трассировок OpenTelemetry (openTelemetryTrace.ingest)
  6. Выберите Сгенерировать токен.
  7. Скопируйте сгенерированный токен в буфер обмена. Сохраните токен в менеджере паролей для дальнейшего использования.
  • Инициализируйте OpenLLMetry токеном для сбора всех соответствующих KPI.

Способ инициализации фреймворка зависит от языка программирования.

Python Node.js
Backend‑компонент Ключ-АСТРОМ работает исключительно с дельта‑значениями и требует соответствующей временно́й агрегации. Убедитесь, что ваш экспортер метрик настроен соответствующим образом, либо установите переменную окружения OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE в значение DELTA.

Мы можем использовать OpenTelemetry для автоинструментации, которая собирает трейсы и метрики ваших AI‑нагрузок — в частности, OpenLLMetry, который можно установить с помощью следующей команды:

pip install traceloop-sdk

После этого добавьте следующий код в начало вашего основного файла.

from traceloop.sdk import Traceloop

headers = { "Authorization": "Api-Token <YOUR_DT_API_TOKEN>" }

Traceloop.init(

    app_name="<your-service>",

    api_endpoint="https://<YOUR_ENV>.live.astromkey.com/api/v2/otlp", # or OpenTelemetry Collector URL

    headers=headers

)

Мы можем использовать OpenTelemetry для автоматической инструментации, которая собирает трассировки и метрики ваших рабочих нагрузок ИИ, в частности OpenLLMetry, который можно установить с помощью следующей команды:
npm i @opentelemetry/exporter-trace-otlp-proto @traceloop/node-server-sdk

После этого добавьте следующий код в начало вашего основного файла.

import {OTLPTraceExporter} from "@opentelemetry/exporter-trace-otlp-proto";

import * as traceloop from "@traceloop/node-server-sdk";

const exporter = new OTLPTraceExporter({

    url: "https://<YOUR_ENV>.live.astromkey.com/api/v2/otlp", // or OpenTelemetry Collector URL

    headers: { Authorization: "Api-Token <YOUR_DT_API_TOKEN>" },

});

traceloop.initialize({

  appName: "<your-service>",

  exporter: exporter

});

В настоящее время OpenLLMetry для Node.js не поддерживает метрики.