• Русский
  • Миграция с Alauda Build of OpenTelemetry на Alauda Build of OpenTelemetry v2

    В этом документе описано, как выполнить миграцию существующего развертывания Alauda Build of OpenTelemetry (построенного на upstream OpenTelemetry Operator/Collector 0.108.0) на Alauda Build of OpenTelemetry v2 (построенного на upstream 0.147.0).

    Оба дистрибутива поставляются через разные пакеты OLM — opentelemetry-operator и opentelemetry-operator2 — но владеют одними и теми же Custom Resource Definitions (OpenTelemetryCollector и Instrumentation). OLM не позволяет двум Operators одновременно владеть одними и теми же CRD, поэтому миграцию необходимо выполнять как uninstall v1 → install v2, а не как параллельное обновление.

    Обзор

    Что изменилось между v1 и v2

    Itemv1v2
    OpenTelemetry Operator/Collector version0.108.00.147.0
    OLM package / Subscription nameopentelemetry-operatoropentelemetry-operator2
    Recommended Operator namespaceopentelemetry-operatoropentelemetry-operator2
    Default subscription channelalphastable
    Java auto-instrumentation imageПредоставляется Alauda. Instrumentation.spec.java.image можно не указывать.Не предоставляется. Пользователь должен настроить Instrumentation.spec.java.image (образ из open source или собственный образ).
    Collector and Operator namespaceМогут использовать одно и то же namespace.Должны находиться в разных namespaces.
    Compatibility with Alauda Service MeshСовместимо с Alauda Service Mesh (v1).Не совместимо с Alauda Service Mesh (v1); совместимо только с Alauda Service Mesh v2.
    WARNING
    • Поскольку Operator v1 (opentelemetry-operator) и Operator v2 (opentelemetry-operator2) разделяют владение CRD, установить v2 нельзя, пока v1 полностью не удалён. Сами CRD сохраняются в ходе миграции; после установки v2 Operator подхватывает и обновляет их.

    Окно простоя при миграции

    Сбор телеметрии прерывается в промежутке между удалением v1 OpenTelemetryCollector и моментом, когда v2 OpenTelemetryCollector становится готовым. Pod’ы приложений продолжают работать нормально, но телеметрия, сгенерированная в этот промежуток, может временно буферизоваться и быть потеряна, если её не удастся вовремя экспортировать. Планируйте миграцию на окно с низкой нагрузкой и заранее уведомите потребителей телеметрии.

    Схема миграции

    [Step 1] Delete v1 Instrumentation resources
    
    [Step 2] Delete v1 OpenTelemetryCollector resources    ← telemetry collection paused
    
    [Step 3] Uninstall the v1 Operator (Subscription + CSV)
    
    [Step 4] Install the v2 Operator
    
    [Step 5] Recreate OpenTelemetryCollector resources
    
    [Step 6] Recreate Instrumentation resources (set spec.java.image)
    
    [Step 7] Roll out application pods to apply the new Java agent
        ↓                                                  ← telemetry collection resumed
    [Step 8] Verify the migration

    Предварительные требования

    • Активная сессия ACP CLI (kubectl) у администратора кластера с ролью cluster-admin.
    • Установлен командный JSON-процессор jq.
    • Alauda Build of OpenTelemetry (v1) в настоящее время установлен в кластере.
    • Если какой-либо сервис использует OTel Java auto-instrumentation, в реестре, доступном из кластера, доступен образ Java auto-instrumentation. См. Подготовка образа Java agent. Сервисам, которые не используют OTel Java auto-injection, этот образ не нужен.
    • Потребители телеметрии (например, Jaeger, Prometheus, консоль Tracing платформы) и владельцы приложений уведомлены о планируемом окне простоя.

    Предварительные задачи перед миграцией

    Инвентаризация существующего развертывания

    Перед внесением изменений зафиксируйте текущее состояние, чтобы понимать объём миграции и подготовить резервные копии для rollback.

    1. Выведите список ресурсов v1 Operator:

      kubectl get subscription -A | grep opentelemetry
      kubectl get csv -A | grep -i opentelemetry
    2. Выведите список существующих custom resources OpenTelemetry:

      kubectl get opentelemetrycollector -A
      kubectl get instrumentation -A
    3. Выведите список workloads, которые в настоящее время используют Java auto-instrumentation:

      kubectl get pods -A -o json \
        | jq -r '
          .items[]
          | select(.metadata.annotations["instrumentation.opentelemetry.io/inject-java"])
          | "\(.metadata.namespace)/\(.metadata.name)"'

    Создание резервной копии ресурсов v1

    Экспортируйте ресурсы v1, чтобы затем можно было восстановить их в v2 (и при необходимости выполнить rollback).

    mkdir -p ./otel-v1-backup
    
    kubectl get opentelemetrycollector -A -o yaml > ./otel-v1-backup/collectors.yaml
    kubectl get instrumentation -A -o yaml > ./otel-v1-backup/instrumentations.yaml
    
    kubectl get subscription -n opentelemetry-operator opentelemetry-operator -o yaml \
      > ./otel-v1-backup/subscription.yaml || true
    kubectl get csv -n opentelemetry-operator -o yaml \
      > ./otel-v1-backup/csv.yaml || true
    
    kubectl -n cpaas-system get servicemonitor otel-collector-monitoring -o yaml \
      > ./otel-v1-backup/servicemonitor-otel-collector-monitoring.yaml || true
    kubectl -n cpaas-system get servicemonitor otel-collector -o yaml \
      > ./otel-v1-backup/servicemonitor-otel-collector.yaml || true
    kubectl -n cpaas-system get serviceaccount otel-collector -o yaml \
      > ./otel-v1-backup/serviceaccount-otel-collector.yaml || true
    kubectl get clusterrolebinding otel-collector:cpaas-system:cluster-admin -o yaml \
      > ./otel-v1-backup/clusterrolebinding-otel-collector.yaml || true
    NOTE

    Файлы резервной копии используются только как эталон конфигурации и как артефакт для rollback. Резервные копии ServiceMonitor, ServiceAccount и ClusterRoleBinding в cpaas-system нужны только в том случае, если позже вы будете откатывать интеграции, зависящие от этих ресурсов v1. При восстановлении ресурсов на v2 следуйте соглашениям v2, описанным в Установка Alauda Build of OpenTelemetry v2, и при необходимости вносите изменения.

    Подготовка образа Java agent

    В v1 Alauda поставляет вместе с Operator кастомизированный образ Java auto-instrumentation, и Operator автоматически внедряет его; обычно пользователи оставляют Instrumentation.spec.java.image не заданным. В v2 Operator больше не поставляет образ Java agent, и вы должны явно задать spec.java.image для каждого ресурса Instrumentation, который применяется к Java workloads. Подробности см. в Java Auto-instrumentation.

    OptionКогда использоватьExample
    Upstream community imageУ кластера есть доступ к публичным registryghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java:2.26.1
    Self-built or mirrored imageAir-gapped кластеры или среды с требованиями к соответствию поставки образовregistry.example.com/otel/autoinstrumentation-java:2.26.1
    NOTE

    OpenTelemetry Java agent перешёл с серии 1.x на серию 2.x. Некоторые автоматически сгенерированные имена метрик и атрибуты отличаются от тех, которые создавались в v1. Если ваши dashboards или alerts зависят от конкретных имён метрик, изучите изменения в upstream release notes для Java agent и обновите их соответствующим образом.

    Проверка совместимости конфигурации Collector

    Alauda Build of OpenTelemetry v2 поддерживает компоненты, перечисленные в v2.0.0 Release Notes. Проверьте каждый receiver, processor, exporter, connector и extension, указанный в существующих ресурсах OpenTelemetryCollector, и убедитесь, что:

    • Каждый компонент включён в списки поддерживаемых компонентов v2.
    • Синтаксис конфигурации соответствует схеме upstream 0.147.0. В диапазоне upstream-версий некоторые поля изменились. Например, структура конфигурации spec.config.service.telemetry.metrics отличается между двумя версиями.

    Если у вас есть staging environment, примените конфигурацию v1 к freshly installed v2 Operator там — это хороший способ выявить несовместимости до миграции production.

    Процедура миграции

    Удаление ресурсов Instrumentation v1

    1. Выведите список существующих ресурсов Instrumentation:

      kubectl get instrumentation -A
    2. Удалите каждый ресурс Instrumentation. Замените <namespace> и <name> значениями из предыдущего шага:

      kubectl -n <namespace> delete instrumentation <name>
      TIP

      Удаление Instrumentation не влияет на pod’ы приложений, которые уже были изменены webhook’ом — ранее внедрённый init container, переменные окружения и JAVA_TOOL_OPTIONS остаются в работающих pod’ах. Удаление лишь предотвращает внедрение этих настроек v1 Operator в новые создаваемые pod’ы.

    Удаление ресурсов OpenTelemetryCollector v1

    1. Выведите список существующих ресурсов OpenTelemetryCollector:

      kubectl get opentelemetrycollector -A
    2. Удалите каждый ресурс OpenTelemetryCollector:

      kubectl -n <namespace> delete opentelemetrycollector <name>
    WARNING

    После этого шага OTLP, Jaeger и Zipkin endpoints, предоставляемые v1 Collector, будут недоступны. Pod’ы приложений, которые продолжают экспортировать телеметрию, будут получать ошибки экспорта до тех пор, пока в Шаге 5 не будет создан v2 Collector.

    Удаление v1 Operator

    1. Удалите Subscription:

      kubectl delete subscription opentelemetry-operator -n opentelemetry-operator
    2. Удалите RBAC и monitoring resources, которые v1 deployment создал в cpaas-system (пропустите этот шаг, если ваше v1 deployment их не создавало). Эти ресурсы сохранены в Создание резервной копии ресурсов v1 для rollback.

      kubectl -n cpaas-system delete servicemonitor otel-collector-monitoring otel-collector
      kubectl -n cpaas-system delete sa otel-collector
      kubectl delete clusterrolebinding otel-collector:cpaas-system:cluster-admin
    3. Дождитесь, пока в кластере не останется ни одного CSV v1 Operator. Эта проверка важна — если какой-либо CSV v1 всё ещё присутствует, OLM отклонит установку v2 Operator в Шаге 4 из-за конфликта владельца CRD.

      kubectl get csv -A | grep '^opentelemetry-operator '

      Ожидаемый вывод — пустой.

    NOTE

    Не удаляйте CRD opentelemetrycollectors.opentelemetry.io и instrumentations.opentelemetry.io. v2 Operator подхватывает и обновляет эти CRD при установке. Их сохранение также позволяет выполнить rollback на v1, используя файлы резервной копии, созданные в Создание резервной копии ресурсов v1.

    Установка v2 Operator

    Следуйте инструкции Установка Operator Alauda Build of OpenTelemetry v2. Сокращённый поток CLI выглядит так:

    1. Проверьте доступные версии v2 Operator:

      kubectl get packagemanifest opentelemetry-operator2 -o json | jq -r '
        .status.channels[]
        | .name as $channel
        | .entries[]
        | [$channel, .name, .version] | @tsv
      ' | column -t
    2. Создайте namespace Operator:

      kubectl get namespace opentelemetry-operator2 || \
        kubectl create namespace opentelemetry-operator2
    3. Создайте Subscription. Замените startingCSV на версию, возвращённую на шаге 1.

      kubectl apply -f - <<EOF
      apiVersion: operators.coreos.com/v1alpha1
      kind: Subscription
      metadata:
        annotations:
          cpaas.io/target-namespaces: ""
        labels:
          catalog: platform
        name: opentelemetry-operator2
        namespace: opentelemetry-operator2
      spec:
        channel: stable
        installPlanApproval: Manual
        name: opentelemetry-operator2
        source: platform
        sourceNamespace: cpaas-system
        # startingCSV example: opentelemetry-operator2.v0.147.0-r0
        startingCSV: {step-1-operator-csv-version}
      EOF
    4. Одобрите InstallPlan:

      kubectl -n opentelemetry-operator2 wait \
        --for=condition=InstallPlanPending subscription opentelemetry-operator2 --timeout=2m
      
      PLAN="$(kubectl -n opentelemetry-operator2 get subscription opentelemetry-operator2 \
        -o jsonpath='{.status.installPlanRef.name}')"
      kubectl -n opentelemetry-operator2 patch installplan "$PLAN" --type=json \
        -p='[{"op": "replace", "path": "/spec/approved", "value": true}]'
    5. Дождитесь, пока CSV v2 не перейдёт в состояние Succeeded:

      kubectl wait --for=jsonpath='{.status.phase}'=Succeeded csv \
        --all -n opentelemetry-operator2 --timeout=3m

    Воссоздание ресурсов OpenTelemetryCollector

    Что меняется в этой миграции

    При восстановлении манифестов OpenTelemetryCollector из резервной копии v1 необходимо внести следующие изменения, прежде чем применять их в v2.

    • Namespace Collector. Namespace Collector должен отличаться от namespace Operator (opentelemetry-operator2). Выберите namespace в зависимости от сценария развертывания:

      • Standalone Collector: отдельный namespace, например opentelemetry-collector.
      • Интеграция Alauda Container Platform Tracing: продолжайте использовать тот же namespace Collector (обычно cpaas-system), чтобы downstream services, ссылающиеся на service Collector, не требовали изменений.
      • Интеграция Alauda Service Mesh v2: оставьте Collector в istio-system, чтобы существующий Istio meshConfig.extensionProviders[].opentelemetry.service оставался действительным.
    • Совместимость компонентов. Каждый компонент, используемый в spec.config, должен поддерживаться в v2. Для рекомендуемой конфигурации Collector при интеграции с Alauda Distributed Tracing см. Развёртывание OpenTelemetry Collector в документации Alauda Distributed Tracing. Для других сценариев следуйте Развёртывание OpenTelemetry Collector и адаптируйте пример под вашу среду.

    • Feature gates. v1 Collectors часто передают Collector feature gates через spec.args.feature-gates. Многие из этих gates либо были стабилизированы (и, следовательно, больше не могут переключаться), либо полностью удалены в более новых версиях Collector, поэтому повторное использование списка v1 может помешать запуску pod Collector в v2. Удалите spec.args.feature-gates из резервной копии и добавьте только те gates, которые явно документированы для используемой версии v2 Collector.

    • Внутренний Prometheus endpoint метрик. Поле service.telemetry.metrics.address больше не является поддерживаемым способом экспонирования внутреннего Prometheus endpoint метрик. Настройте его через service.telemetry.metrics.readers[].pull.exporter.prometheus, как описано в OpenTelemetry Collector internal telemetry documentation. Типичный backup v1 выглядит так:

      service:
        telemetry:
          logs:
            level: info
          metrics:
            address: 0.0.0.0:8888
            level: detailed
    • Подробность внутренних метрик. level: detailed включает histogram buckets и labels по каждому экземпляру для внутренних метрик самого Collector, что существенно увеличивает cardinality в Prometheus и стоимость хранения — особенно в развертываниях Gateway-mode с большим количеством экземпляров receiver/exporter. Для production рекомендуется значение по умолчанию level: normal: оно по-прежнему показывает использование ресурсов процесса и счётчики sent/received/refused/dropped по каждому компоненту, чего достаточно для большинства требований SRE по alerting и capacity. Возвращайтесь к detailed только временно при исследовании распределений задержек exporter или размера batch.

    • Метаданные, управляемые сервером. Поля, записываемые API server (metadata.creationTimestamp, metadata.resourceVersion, metadata.uid, metadata.generation, metadata.managedFields, metadata.finalizers, annotation kubectl.kubernetes.io/last-applied-configuration и status), нельзя повторно использовать при create; их необходимо удалить из резервной копии.

    • RBAC и scraping Prometheus, управляемые Operator. v2 Operator автоматически создаёт ресурсы ServiceAccount и ClusterRoleBinding, необходимые Collector. Удалите поле v1 spec.serviceAccount из резервной копии, чтобы Operator мог создать новый ServiceAccount с корректными правами; обычно не требуется вручную воссоздавать ресурсы RBAC v1. Чтобы Operator также создавал ServiceMonitor для внутреннего Prometheus endpoint, установите spec.observability.metrics.enableMetrics: true и добавьте discovery label (например, prometheus: kube-prometheus) в metadata.labels, чтобы ваш Prometheus Operator подхватил ресурс. Если компонент Collector требует дополнительных cluster-level RBAC (например, processor k8sattributes или receiver k8sobjects), следуйте инструкции Автоматическое создание необходимых RBAC ресурсов.

    Процедура миграции

    1. Воссоздайте ресурс OpenTelemetryCollector из резервной копии. В следующем примере ./otel-v1-backup/collectors.yaml копируется в новый рабочий каталог, удаляются server-managed metadata, поля v1 spec.serviceAccount и spec.args.feature-gates, значение level: detailed понижается до стандартного level: normal, устаревшее поле address заменяется новой конфигурацией readers, включается scraping метрик под управлением Operator через установку spec.observability.metrics.enableMetrics: true и добавление label prometheus: kube-prometheus, чтобы стек kube-prometheus подхватил автоматически созданный ServiceMonitor, после чего результат применяется.

      jq не читает YAML напрямую, поэтому в примере kubectl patch --local -p='[]' -o json используется только как локальный декодер YAML-to-JSON перед передачей ресурсов в jq.

      RESTORE_DIR=./otel-v2-restore
      
      mkdir -p "$RESTORE_DIR"
      cp ./otel-v1-backup/collectors.yaml "$RESTORE_DIR/collectors.yaml"
      
      kubectl patch --local -f "$RESTORE_DIR/collectors.yaml" --type=json -p='[]' -o json \
        | jq -s '
            {
              apiVersion: "v1",
              kind: "List",
              items: map(
                del(
                  .metadata.annotations."kubectl.kubernetes.io/last-applied-configuration",
                  .metadata.creationTimestamp,
                  .metadata.finalizers,
                  .metadata.generation,
                  .metadata.managedFields,
                  .metadata.resourceVersion,
                  .metadata.uid,
                  .status,
                  .spec.serviceAccount,
                  .spec.args."feature-gates"
                )
                | .spec.config.service.telemetry.metrics = (
                    (.spec.config.service.telemetry.metrics // {})
                    | del(.address)
                    | if .level == "detailed" then .level = "normal" else . end
                    | .readers = [
                        {
                          pull: {
                            exporter: {
                              prometheus: {
                                host: "0.0.0.0",
                                port: 8888,
                                without_scope_info: true,
                                without_type_suffix: true,
                                without_units: true
                              }
                            }
                          }
                        }
                      ]
                  )
                | .spec.observability.metrics.enableMetrics = true
                | .metadata.labels.prometheus = "kube-prometheus"
              )
            }
          ' > "$RESTORE_DIR/collectors.json"
      
      kubectl apply -f "$RESTORE_DIR/collectors.json"
    2. Дождитесь, пока pod’ы Collector не станут ready:

      kubectl wait --for=condition=Ready pod \
        -l app.kubernetes.io/managed-by=opentelemetry-operator \
        -n <collector-namespace> --timeout=3m

    Воссоздание ресурсов Instrumentation

    Для каждого ресурса Instrumentation, который вы сохранили в резервной копии, воссоздайте его на v2, указав новое поле spec.java.image. Endpoint экспортера и другие переменные окружения имеют ту же структуру, что и в v1, но Java auto-instrumentation теперь использует образ autoinstrumentation-java серии 2.x. В этой версии протокол OTLP exporter по умолчанию — http/protobuf, поэтому endpoints, которые ранее указывали на gRPC port Collector 4317, необходимо изменить на HTTP port Collector 4318, если только вы явно не настроите OTEL_EXPORTER_OTLP_PROTOCOL=grpc. При необходимости обновите также значение host, если изменились namespace Collector или имя service.

    Используйте тот же рабочий каталог, созданный на предыдущем шаге. В следующем примере ./otel-v1-backup/instrumentations.yaml копируется, spec.java.image задаётся из переменной JAVA_AUTO_INSTRUMENTATION_IMAGE, сохранённое значение OTEL_EXPORTER_OTLP_ENDPOINT изменяется с порта 4317 на 4318, после чего создаются ресурсы Instrumentation:

    RESTORE_DIR=./otel-v2-restore
    JAVA_AUTO_INSTRUMENTATION_IMAGE="ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java:2.26.1"
    
    mkdir -p "$RESTORE_DIR"
    cp ./otel-v1-backup/instrumentations.yaml "$RESTORE_DIR/instrumentations.yaml"
    
    kubectl patch --local -f "$RESTORE_DIR/instrumentations.yaml" --type=json -p='[]' -o json \
      | jq -s --arg javaAutoInstrumentationImage "$JAVA_AUTO_INSTRUMENTATION_IMAGE" '
          {
            apiVersion: "v1",
            kind: "List",
            items: map(
              del(
                .metadata.annotations."kubectl.kubernetes.io/last-applied-configuration",
                .metadata.creationTimestamp,
                .metadata.finalizers,
                .metadata.generation,
                .metadata.managedFields,
                .metadata.resourceVersion,
                .metadata.uid,
                .status
              )
              | .spec.java.image = $javaAutoInstrumentationImage
              | (.spec.env[]? | select(.name == "OTEL_EXPORTER_OTLP_ENDPOINT").value) |= sub(":4317"; ":4318")
              | (.spec.java.env[]? | select(.name == "OTEL_EXPORTER_OTLP_ENDPOINT").value) |= sub(":4317"; ":4318")
            )
          }
        ' > "$RESTORE_DIR/instrumentations.json"
    
    kubectl apply -f "$RESTORE_DIR/instrumentations.json"
    NOTE
    • Установите JAVA_AUTO_INSTRUMENTATION_IMAGE в образ, подготовленный в Подготовка образа Java agent. Команда запишет это значение в spec.java.image. Без этого поля Java agent не внедряется, и Java workloads не будут инструментированы.
    • autoinstrumentation-java 2.x по умолчанию экспортирует с http/protobuf, поэтому endpoint должен использовать OTLP HTTP receiver Collector, обычно порт 4318. Если вы намеренно оставляете gRPC receiver на порту 4317, добавьте OTEL_EXPORTER_OTLP_PROTOCOL=grpc в конфигурацию переменных окружения Java.

    Перевод application pods на новый rollout

    Pod’ы приложений, которые ранее были инструментированы v1 Operator, по-прежнему содержат v1 init container, путь к agent и JAVA_TOOL_OPTIONS. Поскольку Collector, на который опирались эти pod’ы, был заменён, экспорт телеметрии из них больше не работает. Выполните rollout затронутых workloads, чтобы mutating webhook v2 внедрил новый образ Java agent и переменные окружения.

    1. Выведите список deployments, которые включили Java auto-instrumentation:

      kubectl get deploy -A -o json | jq -r '
        .items[]
        | select(.spec.template.metadata.annotations["instrumentation.opentelemetry.io/inject-java"])
        | "\(.metadata.namespace) \(.metadata.name)"'
    2. Перезапустите каждый instrumented deployment и дождитесь завершения rollout. Выберите один из двух подходов ниже в зависимости от того, насколько осторожно вам нужно выполнить проверку.

      Option A — По одному deployment за раз. Выполняйте rollout для каждого Deployment отдельно. Для крупных наборов ресурсов перезапускайте deployments волнами, упорядоченными по критичности, чтобы можно было приостановиться и выполнить проверку после каждой волны.

      kubectl -n <namespace> rollout restart deployment/<name>
      kubectl -n <namespace> rollout status deployment/<name>

      Option B — Все instrumented deployments одной командой. Пройдитесь по каждому Deployment, который включил Java auto-instrumentation. Это быстрее, но не даёт встроенной точки паузы, поэтому подходит для небольших наборов ресурсов или после проверки изменения на canary.

      kubectl get deploy -A -o json | jq -r '
        .items[]
        | select(.spec.template.metadata.annotations["instrumentation.opentelemetry.io/inject-java"])
        | [.metadata.namespace, .metadata.name] | @tsv
      ' | while IFS=$'\t' read -r namespace name; do
        kubectl -n "$namespace" rollout restart deployment/"$name"
        kubectl -n "$namespace" rollout status deployment/"$name"
      done

    Проверка миграции

    1. Убедитесь, что существует только CSV v2 Operator и что он достиг фазы Succeeded:

      kubectl get csv -A | grep -i opentelemetry
    2. Убедитесь, что workloads v2 Operator работают:

      kubectl -n opentelemetry-operator2 get csv,deploy
    3. Убедитесь, что ресурсы OpenTelemetryCollector здоровы и сообщают версию v2:

      kubectl get opentelemetrycollector -A
    4. Убедитесь, что у ресурсов Instrumentation настроено spec.java.image:

      kubectl get instrumentation -A \
        -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}{"\t"}{.spec.java.image}{"\n"}{end}'
    5. Убедитесь, что instrumented application pod использует новый init container Java agent:

      kubectl -n <namespace> get pod <pod-name> \
        -o jsonpath='{.spec.initContainers[*].image}'

      В выводе должно присутствовать изображение, настроенное в Instrumentation.spec.java.image.

    6. Убедитесь, что в pod spec присутствуют переменные окружения OpenTelemetry. Эта проверка выполняется непосредственно на Kubernetes object и не требует, чтобы application container поддерживал kubectl exec или включал команду env.

      kubectl -n <namespace> get pod <pod-name> -o json | jq -r '
        .spec.containers[]
        | .name as $container
        | (.env // [])
        | map(select(.name == "JAVA_TOOL_OPTIONS" or (.name | startswith("OTEL_"))))
        | select(length > 0)
        | "container=" + $container,
          (.[] | "\(.name)=\(.value // (.valueFrom | tostring))")
      '
    7. Отправьте тестовый запрос в instrumented application и подтвердите, что полученные traces и metrics отображаются в вашем tracing backend (например, Jaeger UI или консоль Tracing платформы) и в Prometheus.

    Rollback

    Если проблема обнаружена во время миграции или вскоре после неё, вы можете откатиться к развертыванию v1. То же ограничение OLM по владению CRD действует и в обратную сторону: перед повторной установкой v1 необходимо полностью удалить v2 Operator.

    Удаление ресурсов v2

    kubectl delete instrumentation -A --all
    kubectl delete opentelemetrycollector -A --all
    kubectl delete subscription opentelemetry-operator2 -n opentelemetry-operator2
    kubectl delete csv -n opentelemetry-operator2 --all

    Дождаться полного удаления v2 Operator

    kubectl get csv -A | grep -i opentelemetry-operator2

    Ожидаемый вывод — пустой.

    Повторная установка v1 Operator

    Следуйте процедуре установки v1, описанной в Установка OpenTelemetry Operator.

    Воссоздание ресурсов v1 из резервной копии

    Воссоздайте ресурсы OpenTelemetryCollector, Instrumentation, ServiceAccount, ClusterRoleBinding и ServiceMonitor из YAML-файлов, сохранённых в Создание резервной копии ресурсов v1.

    Повторный rollout application pods

    Перезапустите workloads с помощью kubectl rollout restart, чтобы mutating webhook v1 повторно внедрил v1 Java agent.

    Устранение неполадок

    SymptomВероятная причинаРешение
    OLM отклоняет установку v2 Operator из-за конфликта владельца CRDВ кластере всё ещё существует ClusterServiceVersion v1Дождитесь, пока kubectl get csv -A | grep '^opentelemetry-operator ' не вернёт пустой результат; вручную удалите все оставшиеся CSV v1
    Pod v2 Collector застрял в CrashLoopBackOffКонфигурация Collector использует компонент, который v2 не поддерживает, или поле, схема которого изменилась в 0.147.0Проверьте логи pod Collector; сопоставьте каждый компонент с v2.0.0 Release Notes и обновите или удалите неподдерживаемые элементы
    Application pods перезапускаются, но init container не внедряетсяMutating webhook не готов, ресурс Instrumentation отсутствует, либо аннотация pod ссылается на неверный InstrumentationПроверьте kubectl get mutatingwebhookconfigurations, убедитесь, что Instrumentation существует в ожидаемом namespace, и проверьте значение instrumentation.opentelemetry.io/inject-java
    Application pods запускаются, но traces не создаютсяНеверно задан OTEL_EXPORTER_OTLP_ENDPOINT, Collector не готов или NetworkPolicy блокируют порты 4317 / 4318Проверьте соединение из pod (например, nc -vz <collector-svc> 4318); проверьте ресурсы NetworkPolicy; посмотрите логи pod Collector

    Для более глубокого устранения неполадок в потоке auto-instrumentation см. Устранение неполадок в instrumentation.