Jack Shirazi

在 Kubernetes 中使用 OpenTelemetry Operator 的自定义 Agent

Using a custom agent with the OpenTelemetry Operator for Kubernetes

这是由两部分组成的系列文章的第二部分。第一部分可在Kubernetes Java 应用程序的零配置 OpenTelemetry 自动检测中找到。在第一部分中,我将介绍如何设置和安装 Kubernetes 的 OpenTelemetry Operator,并配置它以使用 OpenTelemetry Java agent 对 Java 应用程序进行自动检测。

在第二部分中,我将展示如何通过 OpenTelemetry Operator 安装任何 Java agent,并以 Elastic Java agent 为例。

安装和配置回顾

本系列的第 1 部分,Kubernetes Java 应用程序的零配置 OpenTelemetry 自动检测,详细介绍了 OpenTelemetry Operator 和 Instrumentation 资源的安装和配置。以下是步骤概要,作为提醒

  1. 安装 cert-manager,例如
    kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.14.4/cert-manager.yaml
  2. 安装 Operator,例如
    kubectl apply -f https://github.com/open-telemetry/opentelemetry-operator/releases/latest/download/opentelemetry-operator.yaml
  3. 创建 Instrumentation 资源
  4. 向部署或命名空间添加注解
  5. 照常部署应用程序

在第一部分中,步骤 3、4 和 5 是针对 OpenTelemetry Java agent 实现的。在本博客中,我将使用 Elastic APM agent 作为示例来实现它们。我假设上面概述的步骤 1 和 2 已经完成,即 Operator 现在已安装。我将继续使用

banana
命名空间作为示例,因此请确保该命名空间存在 (
kubectl create namespace banana
)。根据第 1 部分,如果您使用以下任何示例检测定义,则需要替换
my.apm.server.url
my-apm-secret-token
,并使用适合您的收集器的值。

使用 Elastic OpenTelemetry Java 发行版

从 0.4.0 版本开始,Elastic OpenTelemetry Java 发行版 在 docker 镜像中包含路径

/javaagent.jar
处的 agent jar — 这基本上是 OpenTelemetry Operator 可用于自动检测的 docker 镜像所需的全部内容。这意味着 Instrumentation 资源很容易定义,并且由于它是 OpenTelemetry Java agent 的发行版,因此所有 OpenTelemetry 环境都适用

apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: elastic-otel
  namespace: banana
spec:
  exporter:
    endpoint: https://my.apm.server.url
  propagators:
    - tracecontext
    - baggage
    - b3
  sampler:
    type: parentbased_traceidratio
    argument: "1.0"
  java:
    image: docker.elastic.co/observability/elastic-otel-javaagent:1.1.0
    env:
      - name: OTEL_EXPORTER_OTLP_HEADERS
        value: "Authorization=Bearer my-apm-secret-token"
      - name: ELASTIC_OTEL_INFERRED_SPANS_ENABLED
        value: "true"
      - name: ELASTIC_OTEL_SPAN_STACK_TRACE_MIN_DURATION
        value: "50"

我已包含用于打开 agent 中几个特性的环境,包括

  1. ELASTIC_APM_PROFILING_INFERRED_SPANS_ENABLED,用于打开此博客中描述的推断 span 实现特性
  2. 如果 span 耗时超过 ELASTIC_OTEL_SPAN_STACK_TRACE_MIN_DURATION(默认值为 5 毫秒),则会自动捕获 span 堆栈跟踪

添加注解 ...

metadata:
  annotations:
    instrumentation.opentelemetry.io/inject-java: "elastic-otel"

... 到 pod yaml 中可使应用程序被跟踪,并在 Elastic APM UI 中显示,包括推断的子 span 和堆栈跟踪

上面提到的特性的添加内容以红色圈出 — 左下角的推断 span(用于 methodC 和 methodD)和右上角的堆栈跟踪。(请注意,pod 包括

OTEL_INSTRUMENTATION_METHODS_INCLUDE
环境变量设置为
"test.Testing[methodB]"
,以便显示 methodB 的跟踪;有关 pod 配置,请参阅第 1 部分中的“尝试一下”部分)

使用 Elastic APM Java agent

从 1.50.0 版本开始,Elastic APM Java agent 在 docker 镜像中包含路径 /javaagent.jar 处的 agent jar — 这基本上是 OpenTelemetry Operator 可用于自动检测的 docker 镜像所需的全部内容。这意味着 Instrumentation 资源很容易定义

apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: elastic-apm
  namespace: banana
spec:
  java:
    image: docker.elastic.co/observability/apm-agent-java:1.52.1
    env:
      - name: ELASTIC_APM_SERVER_URL
        value: "https://my.apm.server.url"
      - name: ELASTIC_APM_SECRET_TOKEN
        value: "my-apm-secret-token"
      - name: ELASTIC_APM_LOG_LEVEL
        value: "INFO"
      - name: ELASTIC_APM_PROFILING_INFERRED_SPANS_ENABLED
        value: "true"
      - name: ELASTIC_APM_LOG_SENDING
        value: "true"

我已包含用于打开 agent 中几个特性的环境,包括

  • ELASTIC_APM_LOG_LEVEL 设置为默认值 (INFO),可以轻松切换到 DEBUG
  • ELASTIC_APM_PROFILING_INFERRED_SPANS_ENABLED 用于打开与 此博客中描述的特性等效的推断 span 实现
  • ELASTIC_APM_LOG_SENDING 开启将日志发送到 APM UI 的功能,日志会自动与事务关联(适用于所有常见的日志框架)

添加注解 ...

metadata:
  annotations:
     instrumentation.opentelemetry.io/inject-java: "elastic-apm"

... 添加到 Pod 的 YAML 文件中,即可将应用程序进行追踪,并显示在 Elastic APM UI 中,包括推断的子 Span。

(请注意,该 Pod 包含了

ELASTIC_APM_TRACE_METHODS
环境变量设置为
"test.Testing#methodB"
,以便显示 methodB 的跟踪;有关 pod 配置,请参阅第 1 部分中的“尝试一下”部分)

使用 OpenTelemetry Java 代理的扩展

为 OpenTelemetry Java 代理设置 Instrumentation 资源非常简单,在这一系列文章的第一部分中已经完成。从上面的示例可以看出,只需要确定要使用的 Docker 镜像 URL 即可。但是,如果要在部署中包含扩展,则会稍微复杂一些,不过 operator 也支持这种方式。基本上,你想和代理一起包含的扩展需要放在 Docker 镜像中,或者你必须构建一个包含镜像中尚未存在的扩展的镜像。然后在 Instrumentation 资源中声明镜像和扩展所在的目录。例如,我将展示一个 Instrumentation,它使用 OpenTelemetry Java 代理 的 2.5.0 版本,以及来自 Elastic OpenTelemetry Java 发行版推断的 Span 扩展。该发行版镜像在路径

/extensions/elastic-otel-agentextension.jar
中包含该扩展。Instrumentation 资源允许指定目录或文件路径,这里我将列出目录

apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: otel-plus-extension-instrumentation
  namespace: banana
spec:
  exporter:
    endpoint: https://my.apm.server.url
  propagators:
    - tracecontext
    - baggage
    - b3
  sampler:
    type: parentbased_traceidratio
    argument: "1.0"
  java:
    image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java:2.5.0
    extensions:
      - image: "docker.elastic.co/observability/elastic-otel-javaagent:1.1.0"
        dir: "/extensions"
    env:
      - name: OTEL_EXPORTER_OTLP_HEADERS
        value: "Authorization=Bearer my-apm-secret-token"
      - name: ELASTIC_OTEL_INFERRED_SPANS_ENABLED
        value: "true"

请注意,您可以拥有多个

镜像 … 目录
对,即从不同的镜像包含多个扩展。另请注意,如果您正在测试此特定配置,此处包含的推断 Span 扩展将在本文发布后的某个时候贡献给 OpenTelemetry contrib 代码库,之后该扩展可能不再出现在所引用的镜像的更高版本中(因为它将可以从 contrib 代码库获得)。

下一步

这里,我展示了如何将任何代理与 Kubernetes 的 OpenTelemetry Operator 一起使用,并针对你的系统进行配置。特别是,这些示例展示了如何使用 Elastic Java 代理自动检测在 Kubernetes 集群中运行的 Java 应用程序,以及如何使用 Instrumentation 资源启用功能。你可以针对部署设置零配置,或者只使用一个注解,这通常是一种更灵活的机制(你可以拥有多个 Instrumentation 资源定义,并且部署可以选择适用于其应用程序的定义)。

本文中描述的任何特性或功能的发布和时间安排均由 Elastic 自行决定。任何当前不可用的特性或功能可能无法按时交付,或者根本不会交付。

分享这篇文章