使用 OpenTelemetry 为非容器化 Java 服务提供可追踪性
目录
Overview
本方案将指导您如何修改部署在虚拟机或物理机上的非容器化 Java 服务,以便在平台上查看其与容器化服务的调用链。请注意,本方案仅提供可追踪性功能,不支持查看日志。
Prerequisites
- 您的 Java 服务部署在虚拟机或物理机上,且需要可追踪性功能。
- 集群中已创建服务网格。
- 您可以访问 Kubernetes 集群的控制节点,并且已安装
kubectl
工具。
Steps
1. 下载并配置 OpenTelemetry Java Agent
首先,您需要将 OpenTelemetry Java Agent 的 jar 包复制到创建服务网格的集群控制节点的 ./agent
目录下。
根据集群的运行时组件选择并执行对应脚本
-
Containerd 运行时组件
-
在控制节点安装 nerdctl
工具。下载后,解压包,赋予执行权限,并复制到 /usr/local/bin
目录:
chmod +x nerdctl
cp ./nerdctl /usr/local/bin
-
登录集群使用的镜像仓库,替换 <image_registry_address>
为实际地址:
nerdctl login <image_registry_address>
-
执行以下脚本,将 Java Agent jar 包从镜像复制到本地:
#!/bin/sh
TAG=$(kubectl -n istio-system get cm otel-java-agent -oyaml | grep versions -A1 | grep -v versions | awk '{print substr($0, 7)}')
CONTAINERID=$(nerdctl run -d <image_registry_address>/asm/otel-java-instrumentation:$TAG sleep 9999)
echo "copy agent from $CONTAINERID"
mkdir -p agent
nerdctl cp $CONTAINERID:/opentelemetry-javaagent-ext.jar ./agent/opentelemetry-javaagent-ext.jar
nerdctl container stop $CONTAINERID
-
Docker 运行时组件
-
登录集群使用的镜像仓库:
docker login <image_registry_address>
-
执行以下脚本,将 Java Agent jar 包从镜像复制到本地:
#!/bin/sh
TAG=$(kubectl -n istio-system get cm otel-java-agent -oyaml | grep versions -A1 | grep -v versions | awk '{print substr($0, 7)}')
CONTAINERID=$(docker run -d <image_registry_address>/asm/otel-java-instrumentation:$TAG sleep 9999)
echo "copy agent from $CONTAINERID"
mkdir -p agent
docker cp $CONTAINERID:/opentelemetry-javaagent-ext.jar ./agent/opentelemetry-javaagent-ext.jar
docker container stop $CONTAINERID
2. 将 Java Agent 分发到 Java 服务节点
将步骤 1 中获得的 opentelemetry-javaagent-ext.jar
复制到所有运行 Java 服务的节点的 ./agent
目录下。
3. 设置环境变量
在所有 Java 服务节点上配置以下环境变量:
环境变量 | 说明 |
---|
OTEL_PROPAGATORS | Trace 数据的传播格式。可选值:b3 、b3multi 。多个值用逗号分隔。 |
OTEL_TRACES_EXPORTER | Trace 数据导出器。该值必须为 otlp 。 |
OTEL_EXPORTER_OTLP_ENDPOINT | OTLP 数据上报地址,格式为 http://<ASM_OTEL_COLLECTOR_IP>:4317 ,其中 ASM_OTEL_COLLECTOR_IP 为服务网格组件可访问的 IP。 |
OTEL_RESOURCE_ATTRIBUTES | 自定义标签。必填字段:service.name 、vm.name 。例如:service.name=myservice.ns,vm.name=vm-test 。vm.name 指服务所在虚拟机的名称,service.name 指调用链中显示的服务名称。您可以添加其他自定义标签,建议使用 vm 前缀区分虚拟机服务。多个键值对用逗号分隔。 |
4. 修改 Java 服务启动脚本
在 Java 服务的启动脚本中添加以下参数:
-javaagent:{AGENT_PATH}/opentelemetry-javaagent-ext.jar
5. 创建 ConfigMap
在需要启用可追踪性功能的命名空间下,创建 ConfigMap,用于存储非容器化 Java 服务的地址与名称映射关系。示例:
apiVersion: v1
data:
vms: |-
- host: 192.168.189.136
port: 8081
serviceName: otel-demo-consumer-vm
- host: 192.168.189.136
port: 9081
serviceName: otel-demo-provider-vm
kind: ConfigMap
metadata:
labels:
asm.cpaas.io/vm-config-enabled: "true"
name: virtualmachine-config
NOTE
host
、port
和 serviceName
必须对应非容器化服务的访问地址、端口和服务名称。serviceName
必须与 OTEL_RESOURCE_ATTRIBUTES
环境变量中定义的 service.name
保持一致。
6. 重启 Java 服务
完成上述配置后,重启 Java 服务使配置生效。