头图

简介

虽然 Kubernetes 已经成为行业容器编排的事实标准,但是当组织处于从 Docker 向 Kubernetes 过度的阶段或者不想引入 Kubernetes 带来的复杂性时仍然会有很多使用 Docker 做容器编排的情况,观测云现已支持对 Docker 部署的 Java 应用注入 APM 探针。

安装或者升级 DataKit

Docker 环境下的 Java 探针自动注入由 DataKit 在 1.66.0 版本中引入,在 1.69.0 版本中完善了 JVM 指标的导出机制,启用自动注入需执行 DataKit 安装或者升级操作,然后重新部署 Docker 应用。

全新安装 DataKit

登录观测云控制台,点击「集成」 -「DataKit」 - 「Linux」,复制安装命令。

图片

在命令中增加环境变量 DK_APM_INSTRUMENTATION_ENABLED,如下所示:

DK_APM_INSTRUMENTATION_ENABLED="docker" DK_DATAWAY="https://openway.guance.com?token=tkn_xxx" bash -c "$(curl -L https://static.guance.com/datakit/install.sh)" 

在 Linux 主机中以 root 权限执行以上命令即可完成 DataKit 安装。

升级已有的 DataKit

登录已经安装 DataKit 的 Linux 主机,以 root 权限执行以下命令,注意,即使已经安装了最新版本的 DataKit,仍然需要通过升级的方式打开自动注入。

DK_APM_INSTRUMENTATION_ENABLED="docker" DK_UPGRADE=1 bash -c "$(curl -L https://static.guance.com/datakit/install.sh)"

启用必要插件

安装或升级完成后,如未开启 ddtrace、profile、statsd 插件,需执行以下步骤打开插件,允许 DataKit 收集并处理追踪、剖析和 JVM 指标数据。

# 进入配置文件目录
cd /usr/local/datakit/conf.d/statsd/
# 打开配置文件
cp ddtrace/ddtrace.conf.sample ddtrace/ddtrace.conf
cp profile/profile.conf.sample profile/profile.conf
cp statsd/statsd.conf.sample statsd/statsd.conf
# 确认文件变更后重启 Datakit
datakit service -R

注意, statsd 插件的配置文件在 1.67.0 版本后存在变更,增加了 statsd 插件的 socket 监听方式,因此升级前的版本小于 1.67.0,且已经打开了 statsd 插件的情况下,需要执行 statsd 插件的配置变更。

# 进入配置文件目录
cd /usr/local/datakit/conf.d/statsd/
# 复制新的默认配置到临时文件
cp statsd.conf.sample statsd.conf.temp
# 将已有 statsd.conf 文件中的自定义配置变更至 statsd.conf.temp文件中
# 启用新配置
cp -i statsd.conf.temp statsd.conf
# 确认文件变更后重启 Datakit
datakit service -R

启用自动注入

进入应用的 Docker Compose 目录,执行以下操作重新部署应用。

docker compose up -d

当应用被访问时即可登录观测云控制台,点击「应用性能监测」查看上报的链路追踪数据,对于 SpringBoot 应用, 默认服务名来自 spring.application.name

图片

如需通过环境和版本区分程序的性能差异,或者通过 Profile 分析慢调用的栈追踪,需要通过环境变量在 docker-compose.yml 中做进一步配置,举例如下:

services:
  springboot-demo-openjdk21:
    image: xxx:springboot-demo-openjdk21-1.0.0
    environment:
      # 如需自定义服务名称,请设置 DD_SERVICE
      - DD_SERVICE=springboot-demo
      # 如需自定义环境名称,请设置 DD_ENV,建议配置
      - DD_ENV=test
      # 如需自定义版本名称,请设置 DD_VERSION,建议配置
      - DD_VERSION=1.0.0
      # 如需开启 Profile 采集,请设置 DD_PROFILING_ENABLED
      - DD_PROFILING_ENABLED=true
      # 如需开启 Profile 采集,且 JDK 版本小于等于 8u131 时,请增加
      - DD_PROFILING_DDPROF_ENABLED=true
      # 如需自定义采样率,请设置 DD_TRACE_SAMPLE_RATE,取值范围 0-1.0,默认值为 1.0
      - DD_TRACE_SAMPLE_RATE=1.0
    ports:
      - 8080:8080

配置完成后重新部署应用即可,一般来说区分数据的环境和版本是必须的,可以将以上配置集成至 CICD 流水线中,避免手动修改 Compose 文件。

停用自动注入

Docker 容器探针自动注入通过修改 Docker 的默认容器运行时为 dk-runc 实现,此运行时会为容器进程添加环境变量、挂载相关文件,最终以劫持 Bash 命令的方式修改 Java 进程启动参数,从而完成探针自动注入,探针采集的数据发送至 /var/run/datakit/datakit.sock/var/run/datakit/statsd.sock,因此停止自动注入需要完成以下步骤:

1、修改 Datakit 配置文件 /usr/local/datakit/conf.d/datakit.confinstrumentation_enabled 的值为 "no";

2、执行命令 datakit tool --remove-apm-auto-inject 还原 DataKit 对 /etc/docker/daemon.json 所作的修改;

3、执行命令 datakit service -R 重启 DataKit;

4、执行命令 systemctl daemon-reloadsystemctl restart docker 重启 dockerd;

5、进入应用 Docker Compose 目录执行命令 docker compose up -d 重新部署应用;

6、确保应用已正常启动,容器是否自动重启与其重启策略有关。

如需卸载开启自动注入的 DataKit,需完成以下步骤:

1、执行命令 datakit tool --remove-apm-auto-inject 还原 DataKit 对 /etc/docker/daemon.json 所作的修改;

2、执行命令 datakit service -U 卸载 DataKit 服务;

3、执行命令 systemctl daemon-reload; systemctl restart docker 重启 dockerd;

4、进入应用 Docker Compose 目录执行命令 docker compose up -d 重新部署应用;

5、确保应用已正常启动,容器是否自动重启与其重启策略有关。

一般来说卸载 DataKit 无需移除 /usr/local/datakit 目录,如果未按照以上步骤执行操作直接移除了此目录,可能导致容器启动报错,例如:

[+] Running 0/1
⠙ Container compose-springboot-demo-openjdk21-1  Starting 0.2s 
Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: unable to retrieve OCI runtime error (open /run/containerd/io.containerd.runtime.v2.task/moby/4e5898b3617736e2d0f43cc7f8555f5a3e47138fd9665473a5fedcfefd5ad3c1/log.json: no such file or directory): fork/exec /usr/local/datakit/apm_inject/inject/dkrunc: no such file or directory: unknown

此时,需确认 Docker 配置文件 /etc/docker/daemon.json 是否已经恢复、dockerd 是否已重启,以及应用是否已重新部署,预期情况下通过 docker inspect <container name> | grep Runtime 查询到的容器运行时应该为 runc。无法执行 datakit tool --remove-apm-auto-inject 命令时,可手动恢复 Docker 配置文件,举例如下:

{
  "default-runtime": "dk-runc",                              # 移除此行
  "runtimes": {
    "dk-runc": {                                             # 移除此行
      "path": "/usr/local/datakit/apm_inject/inject/dkrunc"  # 移除此行
    }                                                        # 移除此行
  }
}

问题排查

如果探针自动注入失败,请按照以下步骤进行问题排查:

1、执行命令件 docker inspect <container name> | grep Runtime,检查当前容器的运行时是否为dk-runc,如果仍然为 runc 请检查是否正确开启自动注入;

2、找到容器的 PID,假设 PID 为 xxx,执行命令 cat /proc/xxx/environ,检查是否包含以下环境变量:

DD_TRACE_AGENT_URL=unix:///var/run/datakit/datakit.sock
DD_JMXFETCH_STATSD_HOST=/var/run/datakit/statsd.sock
DD_JMXFETCH_STATSD_PORT=0
ENV_DATAKIT_SOCKET_ADDR=/var/run/datakit/datakit.sock
LD_PRELOAD=/usr/local/datakit/apm_inject/inject/apm_launcher.so

3、如果不包含 LD_PRELOADENV_DATAKIT_SOCKET_ADDR,说明 dk-runc 注入环境变量失败,执行命令 mkdir -p /usr/local/datakit/apm_inject/log/ 开启 dk-runc 日志,重新执行 docker compose up -d,即可在此路径下查看环境变量注入与文件挂载相关的日志;

4、如果包含 LD_PRELOADENV_DATAKIT_SOCKET_ADDR,不包含DD_TRACE_AGENT_URL 等,则可能是容器进程启动命令拦截失败导致相关环境变量注入异常,请通过观测云反馈渠道报告。

总结

使用 Docker 容器部署 Java 应用时,采用探针自动注入能够减少可观测数据采集所需的配置量,不过,需要确保在应用的开发、测试、生产环境注入相同版本的探针,把探针作为代码的一部分集成,而不是仅在生产环境注入。其实,在现代的 CICD 管道中集成探针是一种更好的自动化方案,有利于构建一个透明的系统。


观测云
21 声望85 粉丝

云时代的系统可观测平台