简介
虽然 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.conf
中 instrumentation_enabled
的值为 "no";
2、执行命令 datakit tool --remove-apm-auto-inject
还原 DataKit 对 /etc/docker/daemon.json
所作的修改;
3、执行命令 datakit service -R
重启 DataKit;
4、执行命令 systemctl daemon-reload
;systemctl 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_PRELOAD
和 ENV_DATAKIT_SOCKET_ADDR
,说明 dk-runc 注入环境变量失败,执行命令 mkdir -p /usr/local/datakit/apm_inject/log/
开启 dk-runc 日志,重新执行 docker compose up -d
,即可在此路径下查看环境变量注入与文件挂载相关的日志;
4、如果包含 LD_PRELOAD
和 ENV_DATAKIT_SOCKET_ADDR
,不包含DD_TRACE_AGENT_URL
等,则可能是容器进程启动命令拦截失败导致相关环境变量注入异常,请通过观测云反馈渠道报告。
总结
使用 Docker 容器部署 Java 应用时,采用探针自动注入能够减少可观测数据采集所需的配置量,不过,需要确保在应用的开发、测试、生产环境注入相同版本的探针,把探针作为代码的一部分集成,而不是仅在生产环境注入。其实,在现代的 CICD 管道中集成探针是一种更好的自动化方案,有利于构建一个透明的系统。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。