升级自动插桩 Agent

每个 Instrumentation 资源都会指定其注入到 spec.<language>.image 中的智能体镜像。Operator 在 Pod 准入时注入一个 init container,并通过该容器将智能体复制到应用 Pod 中。因此,升级智能体需要分两步进行:

  1. 更新 Instrumentation 资源中的镜像引用
  2. 重启已插桩的工作负载,因为正在运行的 Pod 会继续使用其启动时的智能体版本

以下示例将 Java 智能体从 2.26.1 升级到 2.30.0。将相应字段替换为其他受支持语言的字段,也适用相同的操作步骤:spec.python.image、spec.nodejs.image、spec.dotnet.image、spec.go.image 或 spec.apacheHttpd.image。

为什么 Operator 不会替你完成此操作

Operator 会在 instrumentation.opentelemetry.io/default-auto-instrumentation-<language>-image 注解中记录其默认注入的镜像,并在启动时重写 spec.<language>.image 中仍与该记录的默认镜像匹配的语言对应项。你自行提供的镜像永远不会匹配,因此不会被修改。本例始终如此,因为 Operator 仅提供注入机制,不包含预构建的插桩镜像:每个 spec.<language>.image 中的镜像都是你自行构建或获取的。

先决条件

  • Alauda Container Platform Application Observability(原 Alauda Build of OpenTelemetry v2)Operator 已升级到 0.157.0,具体说明请参阅升级 Alauda Build of OpenTelemetry v2。
  • 要升级到的智能体镜像由你自行构建或获取,并且可从集群拉取。Operator 不包含预构建的插桩库或容器镜像;请参阅插桩选项。
  • 由具有 cluster-admin 角色的集群管理员建立的有效 ACP CLI (kubectl) 会话。

更新插桩资源

  1. 列出 Instrumentation 资源,以及每个资源注入的 Java 智能体镜像:

    kubectl get instrumentation -A \
      -o custom-columns=NAMESPACE:.metadata.namespace,NAME:.metadata.name,JAVA_IMAGE:.spec.java.image

    示例输出

    NAMESPACE          NAME              JAVA_IMAGE
    otelv2-java-demo   acp-common-java   <registry>/opentelemetry-operator/autoinstrumentation-java:2.26.1
  2. 设置后续命令使用的环境变量:

    # Namespace and name of the Instrumentation resource to upgrade
    export INSTR_NS="otelv2-java-demo"
    export INSTR_NAME="acp-common-java"
    # Java agent image to upgrade to
    export JAVA_AGENT_IMAGE="<registry>/opentelemetry-operator/autoinstrumentation-java:2.30.0"
  3. 更新镜像引用:

    kubectl -n ${INSTR_NS} patch instrumentation ${INSTR_NAME} --type=merge \
      -p "{\"spec\":{\"java\":{\"image\":\"${JAVA_AGENT_IMAGE}\"}}}"
    NOTE

    只有在 Pod 准入时才会读取 Instrumentation 资源,因此此补丁不会影响已在运行的 Pod,也不会触发任何 Pod 重启。

    Operator 会为其支持的每种语言填入默认镜像,不仅限于你配置的语言;如果某个默认镜像版本过旧,无法自动升级,Operator 会发出警告,例如 dotnet image ... 1.2.0 is at a version that cannot be automatically upgraded。该警告与正在升级的语言无关,也不会阻止补丁应用。

重启已插桩的工作负载

  1. 列出更新后的 Instrumentation 资源适用的工作负载:

    kubectl -n ${INSTR_NS} get deployment -o json | jq -r '
      .items[]
      | select(.spec.template.metadata.annotations["instrumentation.opentelemetry.io/inject-java"])
      | .metadata.name'
    NOTE

    注入注解也可以设置在命名空间上,此时该命名空间中的每个工作负载都会进行插桩,上述命令不会返回任何内容。请根据部署中启用注入的方式调整选择,并以相同方式涵盖 DaemonSet 和 StatefulSet 工作负载。

  2. 重启每个工作负载,并等待其就绪:

    for DEPLOY in $(kubectl -n ${INSTR_NS} get deployment -o json | jq -r '
      .items[]
      | select(.spec.template.metadata.annotations["instrumentation.opentelemetry.io/inject-java"])
      | .metadata.name'); do
      kubectl -n ${INSTR_NS} rollout restart deployment/"${DEPLOY}"
      kubectl -n ${INSTR_NS} rollout status deployment/"${DEPLOY}" --timeout=300s
    done
    WARNING

    重启工作负载会中断其提供的流量。如果应用程序无法容忍滚动重启,请在维护窗口期间逐步部署,或一次重启一个工作负载。

验证

  1. 确认注入的 init 容器运行的是新的 Agent 镜像:

    kubectl -n ${INSTR_NS} get pods \
      -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.initContainers[*].image}{"\n"}{end}'

    示例输出

    otel-demo-consumer-for-test-7f69ffbbd6-fvgnv    <registry>/opentelemetry-operator/autoinstrumentation-java:2.30.0
    otel-demo-provider-for-test-9d648d8ff-mn9rx     <registry>/opentelemetry-operator/autoinstrumentation-java:2.30.0

    列出的 Pod 如果没有镜像,则未进行插桩,原因可能是该 Pod 没有注入注解,或者是在添加注解之前已被准入。

  2. 确认 Agent 已加载到应用程序 JVM 中。Operator 会将 Agent 挂载到以其所插桩容器命名的目录下:

    kubectl -n ${INSTR_NS} get pods \
      -o jsonpath='{range .items[*].spec.containers[*].env[?(@.name=="JAVA_TOOL_OPTIONS")]}{.value}{"\n"}{end}'

    示例输出

     -javaagent:/otel-auto-instrumentation-java-otel-demo-consumer-for-test/javaagent.jar
     -javaagent:/otel-auto-instrumentation-java-otel-demo-provider-for-test/javaagent.jar
  3. 生成应用程序流量,并确认 traces 仍能到达 Collector。如果 Collector 使用 debug exporter,则 span 批次会显示在其日志中:

    kubectl logs deployment/otel-collector -n opentelemetry-collector --tail=50 | grep '"spans":'

    示例输出

    2026-08-28T11:05:30.145Z  info  Traces  {..., "otelcol.component.id": "debug", "otelcol.signal": "traces", "resource spans": 1, "spans": 8}

版本注意事项

  • Instrumentation API 在此版本中未发生变化。新增了两个可选字段:spec.initContainerSecurityContext,用于设置注入的 init 容器的安全上下文;以及 spec.go.securityContext,用于覆盖 Go sidecar 的默认值。请参阅安全上下文配置。
  • Agent 的发布独立于 Operator,并遵循各自的版本流。在将 Agent 部署到生产环境之前,请查看要升级的 Agent 的 release notes,了解行为变化,例如新增或重命名的 span 属性。
  • 在 spec.exporter.endpoint 中配置的 exporter 端点不受升级影响。Java Agent 仍默认使用 http/protobuf 协议,因此除非显式设置了 OTEL_EXPORTER_OTLP_PROTOCOL=grpc,否则该端点必须指向端口为 4318 的 Collector OTLP HTTP receiver。