使用 OpenTelemetry 为非容器化 Java 服务提供可追溯性

概述

本解决方案将指导您如何修改部署在虚拟机或物理机上的非容器化 Java 服务,以便在平台上查看其与容器化服务的调用链。请注意,本解决方案仅提供可追溯性功能,不支持查看日志。

先决条件

  • 您的 Java 服务已部署在虚拟机或物理机上,并且需要可追溯性功能。
  • 集群中已创建服务网格。
  • 您可以访问 Kubernetes 集群的控制节点,并且已安装 kubectl 工具。

步骤

1. 下载和配置 OpenTelemetry Java Agent

首先,您需要将 OpenTelemetry Java Agent jar 文件复制到集群的控制节点中的 ./agent 目录,服务网格是在此节点上创建的。

根据集群的运行时组件选择并执行相应的脚本

  • Containerd 运行时组件

    1. 在控制节点上安装 nerdctl 工具。下载,解压包,授予执行权限,并复制到 /usr/local/bin 目录:

      chmod +x nerdctl  
      cp ./nerdctl /usr/local/bin  
      
    2. 登录到集群使用的镜像库,替换 <image_registry_address> 为实际地址:

      nerdctl login <image_registry_address>  
      
    3. 运行以下脚本,复制镜像中的 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 运行时组件

    1. 登录到集群使用的镜像库:

      docker login <image_registry_address>
      
    2. 运行以下脚本,复制镜像中的 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用于追踪数据的传播格式。可用值:b3b3multi。多个值可以用逗号分隔。
OTEL_TRACES_EXPORTER追踪数据的出口。值必须为 otlp
OTEL_EXPORTER_OTLP_ENDPOINTOTLP 数据报告地址,格式为 http://<ASM_OTEL_COLLECTOR_IP>:4317,其中 ASM_OTEL_COLLECTOR_IP 是可以被服务网格组件访问的 IP。
OTEL_RESOURCE_ATTRIBUTES自定义标签。必填字段:service.namevm.name。例如:service.name=myservice.ns,vm.name=vm-testvm.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
  • hostportserviceName 必须对应非容器化服务的访问地址、端口和服务名称。serviceName 必须与 OTEL_RESOURCE_ATTRIBUTES 环境变量中定义的 service.name 匹配。

6. 重启 Java 服务

应用上述配置后,重启 Java 服务以使更改生效。