OpenTelemetry Java 代理有多种安装方法,可以将该代理安装到 Java 应用程序中。如果您在 Kubernetes Pod 中运行 Java 应用程序,则有一种单独的机制(在底层使用 JAVA_TOOL_OPTIONS 和其他环境变量)来自动插桩 Java 应用程序。这种自动插桩无需对应用程序和 Pod 进行任何配置更改即可实现!
在 Kubernetes 中实现 Java 应用程序零配置自动插桩的机制是通过 Kubernetes 的 OpenTelemetry Operator。此 Operator 具有许多功能,完整的文档(当然还有源代码)可在项目本身中找到。在本博客中,我将介绍如何使用 OpenTelemetry Operator 在 Kubernetes 中安装、设置和运行 Java 应用程序的零配置自动插桩。
安装 OpenTelemetry Operator
在撰写本博客时,OpenTelemetry Operator 需要安装证书管理器,然后才能安装该 Operator。从 Web 安装很简单。首先安装
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.14.4/cert-manager.yaml
然后,当证书管理器准备就绪时(
NAMESPACE NAME READY
cert-manager cert-manager-67c98b89c8-rnr5s 1/1
cert-manager cert-manager-cainjector-5c5695d979-q9hxz 1/1
cert-manager cert-manager-webhook-7f9f8648b9-8gxgs 1/1
…您可以安装 OpenTelemetry Operator
kubectl apply -f https://github.com/open-telemetry/opentelemetry-operator/releases/latest/download/opentelemetry-operator.yaml
当然,您可以使用 Operator 的特定版本,而不是
Instrumentation 资源
现在,您只需添加一个 Kubernetes 资源即可启用自动插桩:一个
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
name: banana-instr
namespace: banana
spec:
exporter:
endpoint: "https://my.endpoint"
propagators:
- tracecontext
- baggage
- b3
sampler:
type: parentbased_traceidratio
argument: "1.0"
java:
image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java:2.5.0
env:
- name: OTEL_EXPORTER_OTLP_HEADERS
value: "Authorization=Bearer MyAuth"
创建此资源(例如,使用
metadata:
annotations:
instrumentation.opentelemetry.io/inject-java: "true"
尚未将
apiVersion: v1
kind: Namespace
metadata:
name: banana
annotations:
instrumentation.opentelemetry.io/inject-java: "banana-instr"
...
现在,我们有一个命名空间,它将使用 2.5.0 OpenTelemetry Java 代理自动插桩部署在
尝试一下
在 docker.elastic.co/demos/apm/k8s-webhook-test 中有一个简单的 Java 应用程序示例,它只是重复调用链
apiVersion: v1
kind: Pod
metadata:
name: banana-app
namespace: banana
labels:
app: banana-app
spec:
containers:
- image: docker.elastic.co/demos/apm/k8s-webhook-test
imagePullPolicy: Always
name: banana-app
env:
- name: OTEL_INSTRUMENTATION_METHODS_INCLUDE
value: "test.Testing[methodB]"
会导致应用程序自动插桩,而无需更改任何配置!生成的应用程序会显示在任何 APM UI 中,例如 Elastic APM
正如您所看到的,对于这个示例,我还将此 env 变量添加到 Pod yaml 中,
自动插桩背后的技术
要使用自动插桩,无需特别了解底层机制,但对于那些感兴趣的人,这里有一个简单的概述。
- Kubernetes 的 OpenTelemetry Operator 安装了一个变更 Webhook,这是一个标准的 Kubernetes 组件。
- 部署时,Kubernetes 首先将所有定义发送到变更 Webhook。
- 如果变更 Webhook 发现应该应用自动插桩的条件(即
- 该命名空间有一个 Instrumentation 资源,并且
- 该 Instrumentation 的正确注释以某种方式应用于定义,无论是来自定义本身还是来自命名空间),
- 则变更 Webhook 会“变更”该定义以包含 Instrumentation 资源定义的环境。
- 该环境包括 env 中定义的显式值,以及一些隐式的 OpenTelemetry 值(有关完整详细信息,请参阅 Kubernetes 的 OpenTelemetry Operator 文档)。
- 最重要的是,Operator 会
- 拉取 Instrumentation 资源中定义的镜像,
- 提取路径/javaagent.jar中的文件(使用 shell 命令cp)
- 将其插入到 pod 中的路径/otel-auto-instrumentation-java/javaagent.jar
- 并添加环境变量JAVA_TOOL_OPTIONS=-javaagent:/otel-auto-instrumentation-java/javaagent.jar.
- JVM 会在启动时自动获取该 JAVA_TOOL_OPTIONS 环境变量,并将其应用于 JVM 命令行。
下一步
此演练可以在任何 Kubernetes 集群中重复进行,以演示和试验自动检测(您需要首先创建 banana 命名空间)。在本系列两部分中的第 2 部分中,《使用 OpenTelemetry Operator 为 Kubernetes 注入自定义代理》中,我将展示如何通过 OpenTelemetry operator 安装任何 Java 代理,并以 Elastic Java 代理为例。