从 Alauda Build of OpenTelemetry 迁移到 Alauda Build of OpenTelemetry v2

本文档介绍如何将现有的 Alauda Build of OpenTelemetry(基于上游 OpenTelemetry Operator/Collector 0.108.0 构建)部署迁移到 Alauda Build of OpenTelemetry v2(基于上游 Operator 0.157.0 和 Collector 0.158.0 构建)。

这两个发行版通过不同的 OLM 包交付——opentelemetry-operatoropentelemetry-operator2——但它们拥有相同的 Custom Resource Definitions(OpenTelemetryCollectorInstrumentation)。OLM 不允许两个 Operator 同时拥有相同的 CRD,因此迁移必须按 先卸载 v1,再安装 v2 的方式进行,而不能进行并行升级。

概览

v1 与 v2 的变化

项目v1v2
上游 OpenTelemetry Operator 版本0.108.00.157.0
上游 OpenTelemetry Collector 版本0.108.00.158.0
OLM 包 / Subscription 名称opentelemetry-operatoropentelemetry-operator2
推荐的 Operator 命名空间opentelemetry-operatoropentelemetry-operator2
默认 subscription channelalphastable
Java 自动注入镜像由 Alauda 提供。可以省略 Instrumentation.spec.java.image不提供。用户必须配置 Instrumentation.spec.java.image(开源镜像或自建镜像)。
Collector 和 Operator 命名空间可以共用同一个命名空间。必须位于不同的命名空间。
与 Alauda Service Mesh 的兼容性与 Alauda Service Mesh (v1) 兼容。与 Alauda Service Mesh (v1) 不兼容;仅与 Alauda Service Mesh v2 兼容。
WARNING
  • 由于 v1 Operator(opentelemetry-operator)和 v2 Operator(opentelemetry-operator2)共享 CRD 所有权,你必须先完全卸载 v1,才能安装 v2。迁移过程中 CRD 本身会被保留;v2 Operator 在安装时会接管并升级这些 CRD。

迁移停机窗口

从删除 v1 OpenTelemetryCollector 到 v2 OpenTelemetryCollector 变为 ready 这段时间内,遥测采集会中断。应用 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

前提条件

  • 集群管理员已使用 cluster-admin 角色登录 ACP CLI(kubectl)会话。
  • 已安装 jq 命令行 JSON 处理器。
  • 集群中当前已安装 Alauda Build of OpenTelemetry (v1)。
  • 如果有任何服务使用 OTel Java 自动注入,则需要准备一个可从集群访问的 registry 中的 Java 自动注入镜像。请参阅准备 Java agent 镜像。未使用 OTel Java 自动注入的服务不需要此镜像。
  • 已通知遥测数据使用方(例如 Jaeger、Prometheus、平台 Tracing 控制台)和应用所有者计划中的停机窗口。

迁移前任务

清点现有部署

在进行任何更改之前,请先采集当前状态,以便了解迁移范围并为回滚准备备份。

  1. 列出 v1 Operator 资源:

    kubectl get subscription -A | grep opentelemetry
    kubectl get csv -A | grep -i opentelemetry
  2. 列出现有的 OpenTelemetry 自定义资源:

    kubectl get opentelemetrycollector -A
    kubectl get instrumentation -A
  3. 列出当前依赖 Java 自动注入的工作负载:

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

备份 v1 资源

导出 v1 资源,以便在 v2 中重新创建它们(以及在需要时回滚)。

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

这些备份文件仅用于配置参考和回滚工件。cpaas-system 中的 ServiceMonitorServiceAccountClusterRoleBinding 备份,仅在你之后需要回滚依赖这些 v1 资源的集成时才需要。在 v2 上重建资源时,请遵循安装 Alauda Build of OpenTelemetry v2 中描述的 v2 约定,并按需调整。

准备 Java agent 镜像

在 v1 中,Alauda 会随 Operator 提供一个定制的 Java 自动注入镜像,并由 Operator 自动注入;用户通常不设置 Instrumentation.spec.java.image。在 v2 中,Operator 不再提供 Java agent 镜像,你必须在每个面向 Java 工作负载的 Instrumentation 资源上显式设置 spec.java.image。详细信息请参阅Java 自动注入

选项适用场景示例
上游社区镜像集群可访问公共 registryghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java:2.30.0
自建或镜像同步后的镜像隔离网络集群,或对镜像供应链合规有要求的环境registry.example.com/otel/autoinstrumentation-java:2.30.0
NOTE

OpenTelemetry Java agent 已从 1.x 系列迁移到 2.x 系列。某些自动生成的指标名称和属性与 v1 生成的结果不同。如果你的仪表盘或告警依赖特定的指标名称,请查看上游 Java agent release notes 中的变更,并相应更新。

检查 Collector 配置兼容性

Alauda Build of OpenTelemetry v2 支持 v2.1.0 Release Notes 中列出的组件。请检查现有 OpenTelemetryCollector 资源中引用的每个 receiverprocessorexporterconnectorextension,并确认:

  • 每个组件都包含在 v2 支持的组件列表中。
  • 组件类型名称与当前上游拼写一致。在上游发布范围内,大多数组件类型都已改为 snake_case——例如 k8sattributes 已变为 k8s_attributes。旧名称仍然可以作为已弃用别名使用,但 v2.1.0 Release Notes 中列出了每个组件当前的拼写。
  • 配置语法与上游 Collector 0.158.0 schema 一致。部分字段在上游发布范围内已发生变化。例如,spec.config.service.telemetry.metrics 的配置结构在两个版本之间不同,并且 Kafka exporter 不再接受顶层 topicencoding 字段。

如果你有 staging 环境,在那里将 v1 配置应用到新安装的 v2 Operator 上,是在生产迁移前暴露不兼容项的好方法。

迁移操作步骤

删除 v1 Instrumentation 资源

  1. 列出现有的 Instrumentation 资源:

    kubectl get instrumentation -A
  2. 删除每个 Instrumentation 资源。请将 <namespace><name> 替换为上一步中的值:

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

    删除 Instrumentation 不会影响已经由 webhook 修改过的应用 Pod——此前注入的 init container、环境变量和 JAVA_TOOL_OPTIONS 仍会保留在运行中的 Pod 中。删除操作只会阻止 v1 Operator 将这些内容注入到新创建的 Pod 中。

删除 v1 OpenTelemetryCollector 资源

  1. 列出现有的 OpenTelemetryCollector 资源:

    kubectl get opentelemetrycollector -A
  2. 删除每个 OpenTelemetryCollector 资源:

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

执行此步骤后,v1 Collector 暴露的 OTLP、Jaeger 和 Zipkin endpoint 将不再可用。继续导出遥测数据的应用 Pod 会看到导出错误,直到在步骤 5 中创建 v2 Collector。

卸载 v1 Operator

  1. 删除 Subscription

    kubectl delete subscription opentelemetry-operator -n opentelemetry-operator
  2. 删除 v1 部署在 cpaas-system 中创建的 RBAC 和监控资源(如果你的 v1 部署未创建这些资源,则跳过此步骤)。这些资源已在备份 v1 资源中备份,以便回滚使用。

    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. 等待集群中不再存在任何 v1 Operator CSV。此检查非常重要——如果仍有任何 v1 CSV 存在,由于 CRD 所有权冲突,OLM 会在步骤 4 中拒绝安装 v2 Operator。

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

    预期输出为空。

NOTE

不要删除 opentelemetrycollectors.opentelemetry.ioinstrumentations.opentelemetry.io CRD。v2 Operator 安装时会接管并升级这些 CRD。保留它们也使你可以根据备份 v1 资源中保存的备份文件从 v1 回滚。

安装 v2 Operator

请按照安装 Alauda Build of OpenTelemetry v2 Operator中的说明进行操作。精简后的 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. 创建 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.157.0-r1
      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. 等待 v2 CSV 进入 Succeeded 状态:

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

重新创建 OpenTelemetryCollector 资源

本次迁移会更改什么

当你根据 v1 备份重建 OpenTelemetryCollector 清单时,在将其应用到 v2 之前必须调整以下方面。

  • Collector 命名空间。Collector 命名空间必须与 Operator 命名空间(opentelemetry-operator2)不同。请根据部署场景选择命名空间:

    • 独立 Collector:使用专用命名空间,例如 opentelemetry-collector
    • Alauda Container Platform Tracing 集成:继续使用相同的 Collector 命名空间(通常为 cpaas-system),这样引用 Collector service 的下游服务就无需更改。
    • Alauda Service Mesh v2 集成:将 Collector 保持在 istio-system 中,这样现有的 Istio meshConfig.extensionProviders[].opentelemetry.service 仍然有效。
  • 组件兼容性spec.config 中使用的每个组件都必须在 v2 中受支持。关于与 Alauda Distributed Tracing 集成时推荐的 Collector 配置,请参阅 Alauda Distributed Tracing 文档中的部署 OpenTelemetry Collector。对于其他场景,请遵循部署 OpenTelemetry Collector 并根据你的环境调整示例。

  • Feature gate。v1 Collector 通常通过 spec.args.feature-gates 传递 Collector feature gate。许多 gate 要么已经稳定(因此不再可切换),要么在较新的 Collector 版本中已被完全移除,因此重复使用 v1 列表可能会导致 v2 Collector Pod 无法启动。请从备份中移除 spec.args.feature-gates,并仅重新引入 v2 Collector 当前版本明确记录的 gate。

  • 内部指标 Prometheus endpointservice.telemetry.metrics.address 字段不再是暴露内部指标 Prometheus endpoint 的受支持方式。请改为在 service.telemetry.metrics.readers[].pull.exporter.prometheus 下进行配置,如 OpenTelemetry Collector internal telemetry 文档 所述。典型的 v1 备份如下:

    service:
      telemetry:
        logs:
          level: info
        metrics:
          address: 0.0.0.0:8888
          level: detailed
  • 内部指标详细级别level: detailed 会为 Collector 自身的内部指标启用 histogram buckets 和按实例标签,这会显著增加 Prometheus 的 cardinality 和存储成本——尤其是在具有大量 receiver/exporter 实例的 Gateway 模式部署中。生产环境推荐使用默认的 level: normal:它仍会暴露进程资源使用情况以及按组件划分的 sent/received/refused/dropped 计数器,这对大多数 SRE 告警和容量需求已经足够。仅在调查 exporter 延迟分布或 batch 大小设置时,才临时切回 detailed

  • 由服务器管理的元数据。API server 写入的字段(metadata.creationTimestampmetadata.resourceVersionmetadata.uidmetadata.generationmetadata.managedFieldsmetadata.finalizerskubectl.kubernetes.io/last-applied-configuration 注解以及 status)不能在创建时复用,必须从备份中移除。

  • Operator 管理的 RBAC 和 Prometheus 抓取。v2 Operator 会自动创建 Collector 所需的 ServiceAccountClusterRoleBinding 资源。请从备份中删除 v1 的 spec.serviceAccount 字段,以便 Operator 可以使用正确权限创建新的 ServiceAccount;通常你不需要手动重建 v1 RBAC 资源。若还希望 Operator 为内部 Prometheus endpoint 创建 ServiceMonitor,请设置 spec.observability.metrics.enableMetrics: true,并在 metadata.labels 中添加一个发现标签(例如 prometheus: kube-prometheus),以便你的 Prometheus Operator 实例拾取该资源。如果某个 Collector 组件需要额外的集群级 RBAC(例如 k8s_attributes processor 或 k8s_objects receiver),请遵循自动创建所需的 RBAC 资源。请注意,v2 Operator 还会验证创建 OpenTelemetryCollector 的用户是否拥有将要生成的权限,因此请使用权限足够的用户执行迁移。

迁移操作步骤

  1. 根据备份重新创建 OpenTelemetryCollector 资源。下面的示例将 ./otel-v1-backup/collectors.yaml 复制到新的工作目录中,去除服务器管理的元数据,删除 v1 的 spec.serviceAccountspec.args.feature-gates 字段,将 level: detailed 降级为默认的 level: normal,用新的 readers 配置替换已弃用的 address 字段,通过设置 spec.observability.metrics.enableMetrics: true 并添加 prometheus: kube-prometheus 标签来启用由 Operator 管理的 metrics 抓取,从而让 kube-prometheus stack 拾取自动创建的 ServiceMonitor,最后应用结果。

    jq 不能直接读取 YAML,因此示例仅使用 kubectl patch --local -p='[]' -o json 作为本地的 YAML 到 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
                            }
                          }
                        }
                      }
                    ]
                )
              | .spec.observability.metrics.enableMetrics = true
              | .metadata.labels.prometheus = "kube-prometheus"
            )
          }
        ' > "$RESTORE_DIR/collectors.json"
    
    kubectl apply -f "$RESTORE_DIR/collectors.json"
  2. 等待 Collector Pod 变为 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 字段。exporter endpoint 和其他环境变量的结构与 v1 相同,但 Java 自动注入现在使用 autoinstrumentation-java 2.x 镜像。在此版本中,默认的 OTLP exporter 协议为 http/protobuf,因此此前指向 Collector gRPC 端口 4317 的 endpoint 必须改为 Collector HTTP 端口 4318,除非你显式配置 OTEL_EXPORTER_OTLP_PROTOCOL=grpc。如果 Collector 命名空间或 service 名称已更改,也请更新 host 值。

使用与上一步相同的工作目录。下面的示例将 ./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.30.0"

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 工作负载也不会被注入。
  • autoinstrumentation-java 2.x 默认使用 http/protobuf 导出,因此 endpoint 必须使用 Collector OTLP HTTP receiver,通常是端口 4318。如果你有意继续使用 gRPC receiver 的 4317 端口,请在 Java 环境配置中添加 OTEL_EXPORTER_OTLP_PROTOCOL=grpc

重新部署应用 Pod

之前由 v1 Operator 注入的应用 Pod 仍会保留 v1 init container、agent 路径和 JAVA_TOOL_OPTIONS。由于这些 Pod 所依赖的 Collector 已被替换,这些 Pod 的遥测导出已无法正常工作。请重新部署受影响的工作负载,以便 v2 mutating webhook 注入新的 Java agent 镜像和环境变量。

  1. 列出启用 Java 自动注入的 Deployment:

    kubectl get deploy -A -o json | jq -r '
      .items[]
      | select(.spec.template.metadata.annotations["instrumentation.opentelemetry.io/inject-java"])
      | "\(.metadata.namespace) \(.metadata.name)"'
  2. 重启每个已注入的 Deployment,并等待 rollout 完成。请根据你需要的验证谨慎程度,在下面两种方式中选择一种。

    选项 A — 一次处理一个 Deployment。 对每个 Deployment 单独执行 rollout。对于大型集群,建议按重要性分批重启 Deployment,并在每一批之后暂停验证。

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

    选项 B — 一次性处理所有已注入的 Deployment。 遍历所有启用 Java 自动注入的 Deployment。此方式更快,但没有内置的暂停点,因此更适合小规模集群,或者在你已在金丝雀环境中验证变更之后使用。

    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. 验证仅存在 v2 Operator CSV,并且已进入 Succeeded 阶段:

    kubectl get csv -A | grep -i opentelemetry
  2. 验证 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. 验证某个已注入的应用 Pod 使用新的 Java agent init container:

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

    输出中必须包含配置在 Instrumentation.spec.java.image 中的镜像。

  6. 验证 Pod spec 中存在 OpenTelemetry 环境变量。此检查直接查看 Kubernetes 对象,不要求应用容器支持 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. 向一个已注入的应用发送测试请求,并确认生成的 traces 和 metrics 出现在你的 tracing backend(例如 Jaeger UI 或平台 Tracing 控制台)以及 Prometheus 中。

回滚

如果在迁移期间或迁移后不久发现问题,你可以回滚到 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

请遵循 安装 OpenTelemetry Operator 中记录的 v1 安装操作步骤。

根据备份重新创建 v1 资源

根据备份 v1 资源中保存的 YAML 文件,重新创建 OpenTelemetryCollectorInstrumentationServiceAccountClusterRoleBindingServiceMonitor 资源。

再次重新部署应用 Pod

使用 kubectl rollout restart 重启工作负载,以便 v1 mutating webhook 重新注入 v1 Java agent。

故障排查

症状可能原因解决办法
OLM 以 CRD 所有权冲突拒绝安装 v2 Operator集群中仍存在 v1 ClusterServiceVersion等待 kubectl get csv -A | grep '^opentelemetry-operator ' 为空;手动删除任何残留的 v1 CSV
v2 Collector Pod 卡在 CrashLoopBackOffCollector 配置使用了 v2 不支持的组件,或者使用了 Collector 0.158.0 中 schema 已变更的字段检查 Collector Pod 日志;将每个组件与 v2.1.0 Release Notes 对照,并更新或移除不受支持的项
应用 Pod 重启,但未注入 init containermutating webhook 尚未就绪,Instrumentation 资源缺失,或者 Pod 注解引用了错误的 Instrumentation检查 kubectl get mutatingwebhookconfigurations,确认 Instrumentation 存在于预期的命名空间中,并验证 instrumentation.opentelemetry.io/inject-java 的值
应用 Pod 已启动,但未生成 tracesOTEL_EXPORTER_OTLP_ENDPOINT 错误,Collector 尚未就绪,或者网络策略阻止了端口 4317 / 4318从 Pod 内测试连通性(例如,nc -vz <collector-svc> 4318);检查 NetworkPolicy 资源;查看 Collector Pod 日志

如需进一步排查自动注入流程,请参阅排查 instrumentation 问题