ACK环境下Java应用接入ARMS无数据排查指南

更新时间:
复制为 MD 格式

场景描述

本文档提供了ACK(容器服务Kubernetes版)环境下ARMS Java应用接入后无数据的完整排查步骤。

排查思路概览

  • 基础检查:

    • 数据采集开关是否关闭。

    • 是否为试用版本。

    • 应用是否有实际请求或流量。

  • ACK接入相关检查:

    • initContainer是否正常注入。

    • pod YAML标签是否正常配置。

    • 应用是否在ack-onepilot安装后启动。

    • k8s集群中是否有Addon配置。

    • 应用JVM堆大小配置。

  • 特殊场景排查:

    • 应用启动命令是否存在`sudo -u` 用户切换。

  • 网络连通性检查:

    • 网络连通性是否存在问题。

排查步骤

一、基础检查(优先执行)

1.1 控制台基础配置检查

  1. 检查数据采集开关

    • 进入ARMS控制台 → 应用列表 → 右上角设置 → 应用启停设置。

    • 确认数据采集是否被关闭。

  2. 检查Agent总开关

    • 确认Agent总开关是否被关闭。

  3. 检查试用期

    • 如果是试用版,确认试用期是否已到期。

1.2 JVM监控数据检查

  • 进入应用详情 → JVM监控页面。

  • 如果没有JVM监控数据:可能是节点与控制台断连,需要检查网络连通性。

  • 如果有JVM监控数据,但没有接口监控数据

    • 确认当前应用有流量访问。

    • 确认应用内使用组件版本在ARMS支持范围内,ARMS支持Java组件版本支持范围参考文档:Java组件版本支持范围

    • 如果探针版本较老(低于2.7.3.5),建议升级探针版本。

二、ACK接入相关检查

2.1 检查initContainer是否注入

Kubernetes集群中,执行以下命令:

kubectl get {podName} -n {namespace} -oyaml

检查PodYAML配置中是否存在 one-pilot-initcontainer 这个init容器。

  • 如果有:表示initContainer正常注入,继续执行步骤2.2。

  • 如果没有:跳转到步骤2.3。

2.2 检查initContainer日志

查看initContainer的日志,确认是否有异常退出:

kubectl logs {podName} -n {namespace} -c one-pilot-initcontainer

正常情况:日志中应该出现以下内容,表示initContainer正常结束,探针已挂载成功:

[init] ack-onepilot k8s init ended. cost: 12.90225787s, error: <nil>

异常情况

  • 如果日志中有错误信息,需要根据具体错误进行排查。

  • 如果出现 Error: container has runAsNonRoot and image will run as root 错误,说明Pod配置了非root运行,需要去掉 securityContext.runAsNonRoot: true 配置。

2.3 检查应用标签配置

检查应用的YAML配置,确认是否添加了必要的标签:

labels: armsPilotAutoEnable: "on" armsPilotCreateAppName: "your-app-name"

或者在annotation中配置:

annotations: armsPilotAutoEnable: "on" armsPilotCreateAppName: "your-app-name"

2.4 检查应用重启时间

确认应用的重启时间是否在 ack-onepilot 安装之后:

  • 如果应用重启时间在ack-onepilot安装之前:需要重启应用,让ack-onepilot重新注入探针。

  • 如果应用重启时间在ack-onepilot安装之后:继续执行步骤2.5。

2.5 检查ack-onepilot日志

查看ack-onepilotPod日志,确认是否有报错信息:

# 查看ack-onepilot的Pod kubectl get pod -n ack-onepilot # 查看具体Pod的日志 kubectl logs {podName} -n ack-onepilot

常见错误及解决方法

  1. SDK error,没有对应权限

  2. 集群内node设置了污点

    • 如果集群内Node设置了污点,导致Pilot无法调度启动,也会导致接入失败。

    • 需要调整node的污点配置或pilot的容忍度配置。

  3. 网络访问被拦截

    • 如果日志中出现 Public network access is not permitted 字样,说明创建appPOP请求被安全拦截。

    • 建议使用组件中心接入,不要使用Helm安装同时自己填写AK的方式接入。

2.6 检查探针日志目录

进入业务容器,检查是否存在探针日志目录:

# 进入Pod容器 kubectl exec -it {podName} -n {namespace} -- /bin/bash # 检查探针目录 ls -la /home/admin/.opt/AliyunJavaAgent/logs # 或 ls -la /home/admin/.opt/ArmsAgent/logs

如果没有相关目录,可能是以下原因:

  1. 堆内存不足

    • 检查业务容器日志的前几行,确认是否有堆内存相关的错误。

    • JVM参数不能配置太小,一般堆内存需要大于500M才能使用ARMS进行监控。

  2. JAVA_TOOL_OPTIONS环境变量过长

    • JAVA_TOOL_OPTIONS环境变量超过了Java规定的1024字节最大长度限制。

    • 检查是否有多个pilot同时注入导致环境变量过长。

三、特殊场景排查

3.1 检查是否有sudo切换用户

问题现象:init-container成功注入,Pod中也确认被注入了JAVA_TOOL_OPTIONS环境变量,但是没有数据上报。

排查方法

  1. 进入Pod容器,检查探针目录是否有log目录。

  2. 如果没有log目录,检查用户启动应用的脚本中是否有 sudo -u xxx 此类切换用户的动作。

解决方法

  • Dockerfile中添加 USER xxx:xxx 命令,将pod的默认用户直接切换过去。

  • 原因:如果在容器启动后再执行 sudo -u,ack-onepilot给应用pod注入的环境变量在切换后都会丢失。

3.2 检查是否同时安装了arms-pilot

如果同时安装了 arms-pilotack-onepilot(3.1.0版本以上),会导致冲突。

检查方法

kubectl get ns | grep -E "arms-pilot|mse-pilot"

解决方法

3.3 检查是否手动注入和ACK接入同时存在

如果用户已经通过手动接入方式接入了ARMS,同时又使用了ACK接入,将会注入两个探针。

检查方法: 在业务容器中执行 java -version,查看标准输出中的JAVA_TOOL_OPTIONS,如果出现两个 -javaagent,说明存在重复注入。

解决方法

  • 手动接入和ACK接入二选一,建议选择ACK接入方式。

  • 如果选择ACK接入,需要去掉手动接入的配置。

3.4 检查探针版本

检查方法

# 进入Pod容器 kubectl exec -it {podName} -n {namespace} -- /bin/bash # 检查探针目录 ls -la /home/admin/.opt/AliyunJavaAgent/logs # 或 ls -la /home/admin/.opt/ArmsAgent/logs
  1. 如果存在 version 文件,则执行cat version查看探针版本。

  2. 如果不存在 version 文件,则查看业务容器的日志前几行,Load Aliyun Java Agent version,检索该日志查看应用加载的探针版本。

版本要求

  • 探针版本低于2.7.3.5的,可能需要提供探针日志进行排查。

  • 建议升级到最新版本。

四、网络和权限检查

4.1 检查网络连通性

  1. 检查节点与ARMS服务端的网络连通性

  2. 检查POP调用域名的网络连通性

    • 如果ack-onepilot日志中有POP调用相关的错误,需要检查相关域名的网络连通性。

4.2 检查AK/SK权限

  1. 确认AK/SK类型

    • 自建Kubernetes或注册集群:必须使用主账号的AK/SK,子账号的AK/SK无法上报数据。

  2. 检查AK/SK权限

    • 确认AK/SK有创建应用的权限

    • 如果是注册集群方式接入,检查ack-onepilot对应的helm value.yaml文件中是否填入了正确的accessKeyaccessSecretKey。

4.3 检查License Key

如果探针日志中出现 license key is invalid 错误:

  1. 首次接入:服务端的角色创建与app的创建是并行的,可能需要等待一下再重新启动应用。

  2. 手动接入:检查是否正确填写了license key。

  3. 自动接入:检查用户是否有自己覆盖arms自动填写的license key(可能是误用了其他区域的license key)。

  4. 开源K8s接入:确认one-pilot安装包的values.yaml里填写的aksk是否属于填写的uid。

五、探针日志分析

如果以上步骤都正常,但仍然无数据,需要查看探针日志进行详细分析:

5.1 获取探针日志

探针日志位置:

  • /home/admin/.opt/AliyunJavaAgent/logs

  • /home/admin/.opt/ArmsAgent/logs(旧版本)。

5.2 常见日志错误

  1. license key is invalid:参考步骤4.3。

  2. responsebody_StoreFailed:可能是数据上报失败,需要检查网络和权限。

  3. agent library failed to init:探针初始化失败,可能是探针包损坏或路径错误。

六、其他可能原因

6.1 应用没有流量

  • 确认应用是否有实际的HTTP请求流量。

  • 可以通过Arthas工具监控接口是否有流量。

6.2 组件版本不支持

6.3 探针版本过旧

  • 探针版本低于2.7.3.5的,建议升级探针版本。

  • 升级方式参考:探针升级文档

七、调试技巧

7.1 开启debug日志

ack-onepilot的配置中添加环境变量:

ONEPILOT_LOG_LEVEL: "debug"

7.2 检查JAVA_TOOL_OPTIONS

在业务容器中执行:

echo $JAVA_TOOL_OPTIONS

确认环境变量是否正确注入,是否包含 -javaagent 参数。

7.3 检查探针文件

在业务容器中检查探针文件是否存在:

ls -la /home/admin/.opt/AliyunJavaAgent/ # 或 ls -la /home/admin/.opt/ArmsAgent/