使用 OpenTelemetry 为非容器化 Java 服务提供可追溯性
概述
本解决方案将指导您如何修改部署在虚拟机或物理机上的非容器化 Java 服务,以便在平台上查看其与容器化服务的调用链。请注意,本解决方案仅提供可追溯性功能,不支持查看日志。
先决条件
- 您的 Java 服务已部署在虚拟机或物理机上,并且需要可追溯性功能。
- 集群中已创建服务网格。
- 您可以访问 Kubernetes 集群的控制节点,并且已安装
kubectl
工具。
步骤
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 "从 $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 "从 $CONTAINERID 复制代理"
mkdir -p agent
docker cp $CONTAINERID:/opentelemetry-javaagent-ext.jar ./agent/opentelemetry-javaagent-ext.jar
docker container stop $CONTAINERID
2. 将 Java Agent 分发到 Java 服务节点
将第一步中获得的 opentelemetry-javaagent-ext.jar
复制到所有运行 Java 服务的节点上的 ./agent
目录。
3. 设置环境变量
在所有 Java 服务节点上配置以下环境变量:
环境变量 | 描述 |
---|
OTEL_PROPAGATORS | 用于追踪数据的传播格式。可用值:b3 ,b3multi 。多个值可以用逗号分隔。 |
OTEL_TRACES_EXPORTER | 追踪数据的出口。值必须为 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 服务以使更改生效。