- 可观测性
- 后端
- 运维
- 前端
- 云原生
- 微服务
- AI Agent
【免费下载链接】oneuptime
Complete open-source monitoring and observability platform.
导读
OneUptime Docker Agent 是一个预构建的容器镜像,内置一套经过调优的 OpenTelemetry Collector 配置。将它部署在现有容器旁边,即可自动发现主机上的每一个容器,采集 CPU / 内存 / 网络 / 块 I/O 指标与容器日志,并通过 OTLP 协议将全部数据转发至 OneUptime。本文是完整的安装与运维指南,覆盖一行命令快速启动、Docker Compose 方式、全部环境变量说明、采集数据清单、升级与卸载,以及各类典型故障(如 Docker Socket 权限、API 版本不匹配、无日志、主机断连)的排查方法。
本文对应仓库文档:Docker Agent 安装指南(en),以及配套的 Agent 源码与配置目录 agents/DockerAgent。关于在采集数据之上配置 Docker 监控器与告警,见 Docker Monitor 文档。
概览:一个镜像、一条命令
Docker Agent 的核心设计是"单镜像、单命令":无需手工编写或维护 OpenTelemetry Collector 配置,Agent 镜像已经打包好完整的otel-collector-config.yaml,并内置 inventory 快照轮询器。其工作链路如下:
- 自动发现:通过挂载进容器的
/var/run/docker.sock与 Docker Engine API 通信,自动发现主机上全部容器; - 指标采集:
docker_statsreceiver 按固定间隔(默认 30s)抓取每个容器的 CPU、内存、网络、块 I/O 等指标; - 日志采集:
filelogreceiver 读取/var/lib/docker/containers/*/*-json.log(即 Docker 默认json-file日志驱动写入的 JSON 行文件),并补充容器元数据与推导出的严重级别; - 转发上报:经过 resource 打标、batch 批处理、memory_limiter 内存保护后,由
otlphttpexporter 将指标与日志 POST 到 OneUptime 的/otlp端点。
从仓库中的 Collector 配置(agents/DockerAgent/otel-collector-config.yaml)可以看到三条管线:
service: pipelines: metrics: receivers: [docker_stats] processors: [memory_limiter, resourcedetection, resource, batch] exporters: [otlphttp] logs: receivers: [filelog] processors: [memory_limiter, filter/drop_self_logs, resourcedetection, resource, batch] exporters: [otlphttp] logs/inventory: receivers: [filelog/inventory] processors: [memory_limiter, resourcedetection, resource, batch] exporters: [otlphttp]指标、运行时日志与库存快照各走一条独立管线;其中logs/inventory单独成管线,是为了避免按正文内容匹配的filter/drop_self_logs过滤器误吞库存快照。Agent 启动后由 entrypoint.sh 在后台拉起 inventory 轮询器,随后exec /otelcol-contrib将 Collector 作为前台受监督进程运行——Collector 一旦退出,容器便会重启。
Agent 连接成功后,该 Docker 主机将自动出现在 OneUptime 控制台的 Docker 区域,无需手动创建主机条目(Docker Monitor 文档对此有明确说明:主机在 Agent 首次上报遥测数据时自动注册)。
前提条件
在部署前请确认以下条件:
- Docker Engine 20.10 或更高版本(文档明确的最低版本要求);
- 宿主机上可访问
/var/run/docker.sock:Agent 依赖该 Unix Socket 与 Docker Engine API 通信; - 一个 OneUptime 遥测采集 Token(Telemetry Ingestion Token):在Project Settings → Telemetry & APM → Ingestion Keys中创建并复制其值,部署时作为
ONEUPTIME_SERVICE_TOKEN传入。
需要特别提醒的日志前提:Agent 的filelogreceiver 只能解析 Docker 的json-file日志驱动(Docker 默认驱动)写出的*-json.log文件,无法读取local驱动(二进制 protobuf 格式)或journald、syslog、fluentd、gelf等远程驱动。若某些容器改用了其他驱动,它们将没有日志上报。详情见下文 日志驱动要求。
快速开始(单命令)
将YOUR_ONEUPTIME_URL、YOUR_TELEMETRY_INGESTION_TOKEN与主机名替换为你的环境值。主机名决定该 Docker 主机在 OneUptime 中的显示名称,建议取稳定的标识,例如prod-docker-01:
docker run -d \ --name oneuptime-docker-agent \ --user 0:0 \ --restart unless-stopped \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ -v /var/lib/docker/containers:/var/lib/docker/containers:ro \ -e ONEUPTIME_URL="YOUR_ONEUPTIME_URL" \ -e ONEUPTIME_SERVICE_TOKEN="YOUR_TELEMETRY_INGESTION_TOKEN" \ -e DOCKER_HOST_NAME="my-docker-host" \ oneuptime/docker-agent:release命令要点解析:
| 参数 | 作用 |
|---|---|
--user 0:0 | 以 root 运行,否则无权访问/var/run/docker.sock(见故障排查) |
-v /var/run/docker.sock:/var/run/docker.sock:ro | 只读挂载 Docker Socket,供docker_statsreceiver 抓取指标 |
-v /var/lib/docker/containers:/var/lib/docker/containers:ro | 只读挂载容器日志目录,供filelogreceiver 读取*-json.log |
--restart unless-stopped | 保证 Collector 异常退出后自动重启 |
执行完这一步即可——Agent 一旦连接,主机便会自动出现在 OneUptime 控制台的Docker区域。
备选方案 — Docker Compose
偏好 Docker Compose 时,将以下内容写入docker-compose.yml:
services: oneuptime-docker-agent: image: oneuptime/docker-agent:release container_name: oneuptime-docker-agent user: "0:0" restart: unless-stopped volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - /var/lib/docker/containers:/var/lib/docker/containers:ro environment: - ONEUPTIME_URL=YOUR_ONEUPTIME_URL - ONEUPTIME_SERVICE_TOKEN=YOUR_TELEMETRY_INGESTION_TOKEN - DOCKER_HOST_NAME=my-docker-host logging: driver: json-file options: max-size: "10m" max-file: "3"启动:
docker compose up -d仓库自带版本 agents/DockerAgent/docker-compose.yml 与之等价,并体现了两个可复用的细节:
DOCKER_HOST_NAME=${DOCKER_HOST_NAME:-docker-host}:允许通过.env注入,缺省时回落为docker-host;DOCKER_API_VERSION=${DOCKER_API_VERSION-1.44}:刻意使用${VAR-default}而非${VAR:-default}——冒号形式会把显式设置为空字符串的变量也替换成默认值,从而吞掉"设为空串以自动协商 API 版本"这条逃生通道。
# 来自 agents/DockerAgent/docker-compose.yml - DOCKER_API_VERSION=${DOCKER_API_VERSION-1.44}环境变量
| 变量 | 必填 | 说明 |
|---|---|---|
ONEUPTIME_URL | 是 | OneUptime 实例地址(例如https://oneuptime.com或你的自托管地址) |
ONEUPTIME_SERVICE_TOKEN | 是 | 遥测采集 Token,来自Project Settings → Telemetry & APM → Ingestion Keys |
DOCKER_HOST_NAME | 否 | 该主机的友好名称,默认docker-host;每个主机建议设置为稳定的值(如prod-docker-01) |
DOCKER_API_VERSION | 否 | Agent 与 Docker Engine API 通信使用的 API 版本,默认1.44;较旧守护进程上应调低,或置空以自动协商(见故障排查) |
这些变量在 Collector 配置中的落地方式(agents/DockerAgent/otel-collector-config.yaml):
ONEUPTIME_URL决定 OTLP exporter 端点:endpoint: "${env:ONEUPTIME_URL}/otlp";ONEUPTIME_SERVICE_TOKEN作为请求头:x-oneuptime-service-token: "${env:ONEUPTIME_SERVICE_TOKEN}";DOCKER_HOST_NAME被打到资源属性上:host.name: "${env:DOCKER_HOST_NAME}"——这正是 Docker 主机页按主机过滤日志/指标所依赖的字段(见故障排查"主机名显示为容器 ID");DOCKER_API_VERSION传给docker_statsreceiver:api_version: "${env:DOCKER_API_VERSION}"。
镜像标签
仓库 agents/DockerAgent/README.md 列出的可用镜像标签:
| 标签 | 说明 |
|---|---|
oneuptime/docker-agent:release | 最新稳定版(社区) |
oneuptime/docker-agent:enterprise-release | 最新稳定版(企业版) |
oneuptime/docker-agent:<version> | 固定版本,如10.0.31 |
ghcr.io/oneuptime/docker-agent:release | 同一镜像在 GHCR 上的镜像副本 |
验证安装
- 检查 Agent 是否在运行:
docker ps --filter name=oneuptime-docker-agent- 查看 Agent 日志:
docker logs -f oneuptime-docker-agent- 在日志中寻找启动成功标记:
"Everything is ready. Begin running and processing data."
大约一分钟后,主机应出现在 OneUptime 控制台中,并有指标与日志持续流入。
采集的数据
指标清单
| 类别 | 数据(每容器) |
|---|---|
| CPU | 总使用量、使用百分比、cgroup 限流时间(throttling time) |
| 内存 | 使用量、限额、百分比、RSS、缓存 |
| 网络 | 接收/发送的字节数与包数 |
| 块 I/O | 读/写字节数与操作数 |
| 容器信息 | 运行时长(uptime)、重启次数、进程数 |
Agent 使用 OpenTelemetry 的docker_statsreceiver,默认每 30 秒抓取一次 Docker Engine API。Docker Monitor 文档(packages/App/FeatureSet/Docs/Content/en/monitor/docker-monitor.md)给出了对应的具体指标名,可供配置监控器查询时直接使用:
- CPU:
container.cpu.utilization(docker stats的 CPU% 列,100% 等于一个完整 CPU 核)、container.cpu.usage.total(生命周期累计计数器)、container.cpu.throttling_data.throttled_time(累计被 cgroup 限流的纳秒数)、container.cpu.throttling_data.throttled_periods(限流周期数); - 内存:
container.memory.usage.total、container.memory.usage.limit、container.memory.percent; - 网络:
container.network.io.usage.rx_bytes、container.network.io.usage.tx_bytes; - 块 I/O:
container.blockio.io_service_bytes_recursive.read、container.blockio.io_service_bytes_recursive.write; - 容器信息:
container.uptime(秒)、container.restarts(生命周期计数器)、container.pids.count(cgroup pids 控制器统计的任务数)。
注意:container.restarts与container.cpu.throttling_data.throttled_time是单调递增的生命周期计数器,因此 Docker Monitor 的高重启/高限流告警模板评估的是窗口内计数器的增量而非绝对值,否则任何重启过的容器都会永远触发告警。这些计数器在每次 30s 抓取之间取差,若把collection_interval提高到 60s 以上,每个时间桶只剩一个样本,增量恒为 0,会静默禁用这两个告警模板——如需修改抓取间隔请务必留意。
在 Collector 配置中,这类依赖告警模板的指标(重启、运行时长、进程数、CPU 限流)在 contrib 版docker_statsreceiver 里默认是关闭的,Agent 的配置中显式开启(agents/DockerAgent/otel-collector-config.yaml):
metrics: container.cpu.utilization: enabled: true container.cpu.throttling_data.throttled_periods: enabled: true container.cpu.throttling_data.throttled_time: enabled: true container.memory.percent: enabled: true container.pids.count: enabled: true container.restarts: enabled: true container.uptime: enabled: true日志采集
容器日志自动从/var/lib/docker/containers/*/*-json.log采集,并经过一系列 Operator 处理(json_parser解析 Docker JSON 信封 →regex_parser从文件路径提取容器 ID → 多层move把log移入 body、stream移入log.iostream属性 →recombine合并多行堆栈 → severity 推导)。最终以原生 OpenTelemetry 日志记录格式上报,severityText、severityNumber、body、attributes、traceId、spanId均被填充。
两个值得注意的实现细节:
- 多行日志合并:Docker
json-file驱动按行写 JSON 信封,多行堆栈(如 Node.js 的" at ..."帧)会被拆成多条记录。Agent 的recombineOperator 以body matches "^[^\s\}\)\]]"判断新纪录起点,把同一容器日志文件中以空白或右括号开头的行与前一条合并,并以log.file.path作为source_identifier防止跨容器串并,force_flush_period: 5s、max_log_size: 1048576兜底; - 排除自身日志:
filelogreceiver 通过exclude前缀通配/var/lib/docker/containers/${env:HOSTNAME}*/*-json.log(容器内HOSTNAME默认是短容器 ID,而 Docker 以完整 ID 命名日志目录),避免 Collector 采集并上报自己的抓取/导出堆栈形成回环;配置中还额外以filter/drop_self_logs处理器丢弃特征性的 Collector 自日志。
严重级别推导是日志链路中较精巧的一环。Dockerjson-file驱动本身不记录严重级别,而 OTel 日志记录依赖severity_number/severity_text做过滤,因此 Agent 使用router+regex_parser+severity_parser的组合进行最佳努力推导:
- 级别关键字只在其"该在的位置"才被采信,有两种形态(按序匹配):
- 行首前导(preamble):关键字位于记录首行,且其前的都是前导字符——标点、数字及以结构分隔符(
.]=-:/|)})结尾的单词 token。即[ERROR] ...、Monolog 的app.INFO: ...、2026-08-31 07:25:04 INFO ...、Python 的... - myapp - INFO - ...、logfmt 的level=error ...均命中;而散文式表述Connection error, retrying不会被误判。重复匹配是惰性的,取前导中第一个关键字; - 级别字段:行内任意位置形如
level/lvl/severity/severity_text/levelname/log.level/log_level的键,以:或=分隔的值。即 zap、logrus 的 JSON({"level":"info"})与非首字段的 logfmt(ts=... level=error msg=...)。
- 行首前导(preamble):关键字位于记录首行,且其前的都是前导字符——标点、数字及以结构分隔符(
- 无关键字时回退到流:stderr →
ERROR,stdout →INFO; - 文本级别再经
severity_parser(preset: default + 自定义映射)提升到 LogRecord 的severity_number;自定义映射覆盖了 stanza 内建预设缺失的级别:warning→warn、error→err/crit/critical、fatal→panic/alert/emerg/emergency(nginx 会输出[emerg])、info→notice。
该行为的边界用例(含不得被误判的行)由测试 Tests/Ops/ContainerAgentLogSeverity.test.js 固化约束。
升级 Agent
docker pull oneuptime/docker-agent:release docker rm -f oneuptime-docker-agent # 重新执行上面的 docker run 命令或使用 Docker Compose:
docker compose pull docker compose up -d卸载 Agent
docker rm -f oneuptime-docker-agent若使用 Docker Compose:
docker compose down自托管 OneUptime
自托管场景下,把ONEUPTIME_URL指向自己的实例:
-e ONEUPTIME_URL="https://your-oneuptime-host.example.com"如果实例仅提供 HTTP,使用http://并带上对应端口。
日志驱动要求
Agent 只采集使用 Dockerjson-file日志驱动的容器日志。虽然这是 Docker 默认驱动,但部分安装会改成local(二进制 protobuf 写入local-logs/而非*-json.log)或远程驱动(journald、syslog、fluentd、gelf等)——filelogreceiver 都无法读取。
检查某个容器的当前日志驱动:
docker inspect <container> --format '{{.HostConfig.LogConfig.Type}}'检查守护进程默认驱动:
docker info --format '{{.LoggingDriver}}'将 Compose 服务切换为json-file并配置合理的轮转,为每个服务添加logging块:
services: my-app: image: my-app:latest logging: driver: "json-file" options: max-size: "100m" max-file: "5"修改守护进程默认值(影响之后创建的所有容器),编辑/etc/docker/daemon.json:
{ "log-driver": "json-file", "log-opts": { "max-size": "100m", "max-file": "5" } }随后重启 Docker,并**重新创建(而非仅重启)**受影响的容器——日志驱动在容器创建时即被绑定,已存在的容器必须删除重建才会切换到新驱动:
# Docker Compose docker compose up -d --force-recreate <service> # 纯 Docker docker rm -f <container> docker run ... <image>注意:Agent 自身在 Compose 中也配置了
logging: json-file并限制max-size: 10m、max-file: 3,避免 Agent 自己的日志无限增长。
故障排查
Docker Socket 权限被拒绝
Agent 容器必须以 root(--user 0:0)运行才能访问/var/run/docker.sock。请确认--user 0:0标志(或 Compose 中的user: "0:0")存在。
Agent 以 "client version is too new" 反复重启
Error: cannot start pipelines: failed to start "docker_stats" receiver: Error response from daemon: client version 1.44 is too new. Maximum supported API version is 1.41守护进程会拒绝比自己最大值更新的客户端,导致 receiver 无法启动,Collector 随之退出——容器因此进入重启循环。查看守护进程支持的最大 API 版本并传给 Agent:
docker version --format '{{ .Server.APIVersion }}' # 例如 Engine 20.10 上为 1.41然后将-e DOCKER_API_VERSION=1.41(或你查到的值)加入docker run,或在 Compose 中设置DOCKER_API_VERSION。较新的守护进程仍会提供旧版 API,因此该设置在守护进程升级后依然有效,可在合适时机移除。
如果不想手动查版本号,把DOCKER_API_VERSION设为空字符串即可。此时 Agent 会让 Docker SDK 与守护进程协商版本(一次HEAD /_ping,随后采用守护进程自己的最大值),兼容新旧守护进程:
docker run -d ... -e DOCKER_API_VERSION= ...仓库中 Collector 配置对该空值做了特别设计(agents/DockerAgent/otel-collector-config.yaml):api_version使用不带默认值的${env:DOCKER_API_VERSION}而非${env:DOCKER_API_VERSION:-1.44}——因为 confmap 的:-默认值只在变量未设置时生效,无法捕获 Compose 对缺失.env条目注入的空字符串,而未设置的情况本来就会退化为自动协商,这恰是两者中更安全的行为。
Agent 显示为断连
- 检查 Agent 是否在运行:
docker ps --filter name=oneuptime-docker-agent - 检查 Agent 日志:
docker logs oneuptime-docker-agent | grep -i error - 核实 OneUptime URL 与服务 Token 是否正确
- 确保 Docker 主机能在网络上访问 OneUptime 实例
没有任何指标出现
- 确认 Docker Socket 在 Agent 容器内可访问:
docker exec oneuptime-docker-agent ls -la /var/run/docker.sock - 检查 Collector 日志中的导出错误:
docker logs oneuptime-docker-agent | tail -100 - 确保服务 Token 有效且未过期
指标正常但日志为空
若指标已出现而Logs页为空(或只有 Agent 自身日志),最常见原因是容器未使用json-file日志驱动。
诊断步骤:
# 1. 检查 Agent 的 filelog receiver 正在监视哪些文件 docker logs oneuptime-docker-agent 2>&1 | grep -E "Started watching file|no files match" # 2. 检查容器实际使用的日志驱动 docker inspect <container> --format '{{.HostConfig.LogConfig.Type}}' # 3. 检查 receiver 期望的日志文件是否真的存在 docker run --rm --volumes-from oneuptime-docker-agent alpine:3.19 \ sh -c 'ls /var/lib/docker/containers/*/*-json.log 2>&1 | head'若第 1 步显示no files match the configured criteria,或第 3 步对相关容器返回空列表,则这些容器未使用json-file驱动,按上文 日志驱动要求 切换即可。修改后必须重建容器。
日志已采集但不出现在特定 Docker 主机页
Docker 主机页按resource.host.name(等于主机的hostIdentifier)过滤,该值取自传给 Agent 的DOCKER_HOST_NAME环境变量。如果你在主机自动注册后修改了DOCKER_HOST_NAME,OneUptime 会以新名称创建第二条主机记录,日志将出现在新记录下。
# 确认 Agent 正在打上的主机名 docker inspect oneuptime-docker-agent --format '{{range .Config.Env}}{{println .}}{{end}}' | grep DOCKER_HOST_NAME主机名显示为容器 ID
将DOCKER_HOST_NAME环境变量设为友好名称并重新创建容器。
常用命令速查
# 查看 Agent 状态 docker ps --filter name=oneuptime-docker-agent # 查看 Agent 日志 docker logs -f oneuptime-docker-agent # 验证 Docker Socket 访问 docker exec oneuptime-docker-agent ls -la /var/run/docker.sock进阶:本地构建镜像
如需自行构建镜像(开发或离线环境),在仓库根目录执行:
npm run prerun # 从 Dockerfile.tpl 生成 Dockerfile docker build -f ./agents/DockerAgent/Dockerfile -t oneuptime/docker-agent:local .镜像对应的模板与入口见 agents/DockerAgent/Dockerfile.tpl 与 agents/DockerAgent/entrypoint.sh。此外,仓库还提供 systemd 单元 agents/DockerAgent/systemd/oneuptime-docker-agent.service 与安装脚本 agents/DockerAgent/install.sh,可用于以 systemd 方式托管 Agent(适用于 Docker 由 systemd 管理的服务器)。
下一步
- 配置Docker 监控器,对容器 CPU / 内存 / 重启等条件告警——见 Docker Monitor 文档;
- 对于 Kubernetes 集群(而非独立 Docker 主机),使用 OneUptime Kubernetes Agent;
- 对于非容器化主机(Linux / macOS / Windows 虚拟机与裸金属),使用 主机 OpenTelemetry Collector。
- 可观测性
- 后端
- 运维
- 前端
- 云原生
- 微服务
- AI Agent
【免费下载链接】oneuptime
Complete open-source monitoring and observability platform.
相关推荐
OneUptime Docker Agent 实战指南:一条命令把 Docker 主机指标、容器日志接入 OneUptime
OneUptime Docker Agent 实战指南:一条命令把 Docker 主机指标、容器日志接入 OneUptime OneUptime Docker
可观测性后端运维前端云原生微服务AI AgentOneUptime Docker Agent:一条命令完成 Docker 主机监控、容器日志采集与 OTLP 数据上报
OneUptime Docker Agent:一条命令完成 Docker 主机监控、容器日志采集与 OTLP 数据上报 OneUptime Docker Age
可观测性后端运维前端云原生微服务AI AgentOneUptime Docker Agent 部署与运维完全指南:一条命令接入 Docker 主机遥测监控
OneUptime Docker Agent 部署与运维完全指南:一条命令接入 Docker 主机遥测监控 本指南围绕 OneUptime 开源仓库中的 Doc
可观测性后端运维前端云原生微服务AI Agent
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考