OneUptime Docker Agent 部署与运维完全指南:一条命令接入 Docker 主机遥测监控
2026/9/17 13:40:08 网站建设 项目流程

OneUptime Docker Agent 部署与运维完全指南:一条命令接入 Docker 主机遥测监控

【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime

本指南围绕 OneUptime 开源仓库中的 Docker Agent 展开,讲解如何用一条命令部署一个预配置的 OpenTelemetry Collector 容器,自动发现宿主机上的全部 Docker 容器,采集 CPU、内存、网络、块 I/O 指标与容器日志,并通过 OTLP 协议汇入 OneUptime 平台。读完本文,你将掌握 Docker Agent 的快速部署、环境变量调优、升级卸载、日志严重性推导原理以及常见故障排查,可直接在生产 Docker 主机上落地使用。

OneUptime Docker Agent 是什么

OneUptime Docker Agent 是一个预构建的容器镜像(oneuptime/docker-agent),镜像内打包了一份经过调优的 OpenTelemetry Collector 配置。把它与现有容器一起运行在同一宿主机上,它会自动完成以下工作:

  • 自动发现宿主机上的每个容器
  • 采集容器的CPU / 内存 / 网络 / 块 I/O 指标
  • 采集容器日志(stdout/stderr);
  • 将指标与日志统一通过OTLP协议转发到 OneUptime。

从镜像构建层面看,该镜像基于otel/opentelemetry-collector-contrib:0.154.0构建(见 DockerAgent/Dockerfile.tpl),将预调优的 DockerAgent/otel-collector-config.yaml 烘焙进/etc/otelcol-contrib/config.yaml,并在启动时通过环境变量注入(${ONEUPTIME_URL}${ONEUPTIME_SERVICE_TOKEN}等)。因此用户只需要“一个镜像、一个命令、几个环境变量”。

容器启动时,入口脚本 DockerAgent/entrypoint.sh 会在后台启动一个库存快照轮询器(inventory poller),然后以前台方式exec启动 OTel Collector——Collector 是受监督的主进程,一旦退出容器即重启。

本文是安装指南。如需基于 Agent 采集到的数据配置 Docker 监控器与告警通知,参见 Docker Monitor(Docker 监控器配置文档)。

前置条件

部署前请确认满足以下条件:

  1. Docker Engine 20.10+(宿主机);
  2. 可以访问宿主机上的/var/run/docker.sock(Docker 套接字);
  3. 拥有一个OneUptime Telemetry Ingestion Token(遥测摄取令牌)——在 OneUptime 控制台的项目设置 → 遥测与 APM → Ingestion 密钥中创建,并复制其值。

需要特别注意的是:Agent 通过挂载 Docker 套接字获取容器元数据与指标,通过挂载/var/lib/docker/containers目录读取容器日志文件,因此两个卷都是必需的。

快速开始(单命令部署)

YOUR_ONEUPTIME_URLYOUR_TELEMETRY_INGESTION_TOKEN和主机名替换为你的环境值。主机名(DOCKER_HOST_NAME)是此 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

就这些。Agent 建立连接后,你的 Docker 主机将自动出现在 OneUptime 控制台的 Docker 区域中,无需手动注册。

关于上述命令的几个关键点,可从源码得到印证:

  • --user 0:0:必须以 root 运行才能访问/var/run/docker.sock。基础镜像默认的非 root 用户(UID 10001)在大多数主机上无法读取套接字与容器日志目录(见 DockerAgent/Dockerfile.tpl 中的USER 0:0)。
  • -v ...:ro:两个卷均以只读方式挂载,Agent 只读不写宿主机状态。
  • --restart unless-stopped:保证 Agent 随 Docker 守护进程自愈重启。

镜像标签

标签说明
oneuptime/docker-agent:release最新稳定版(社区版)
oneuptime/docker-agent:enterprise-release最新稳定版(企业版)
oneuptime/docker-agent:<version>固定版本,例如10.0.31
ghcr.io/oneuptime/docker-agent:release同一镜像在 GHCR 的镜像副本

以上标签说明见 DockerAgent/README.md。

替代方案: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

仓库自带的 DockerAgent/docker-compose.yml 展示了同样的结构,并在注释中特别说明了一个易错点:DOCKER_API_VERSION=${DOCKER_API_VERSION-1.44}使用的是${VAR-default}而非${VAR:-default}写法,目的是保留“空字符串”这一逃生通道——若用冒号写法,显式传入的空值会被默认值吞掉。

环境变量详解

变量是否必需说明
ONEUPTIME_URL你的 OneUptime 实例 URL(例如https://oneuptime.com或自托管地址)
ONEUPTIME_SERVICE_TOKEN来自项目设置 → 遥测与 APM → Ingestion 密钥的 Telemetry Ingestion Token
DOCKER_HOST_NAME该主机的可读名称,默认值为docker-host。建议为每台主机设置稳定值(如prod-docker-01
DOCKER_API_VERSIONAgent 使用的 Docker Engine API 版本,默认1.44。旧版守护进程主机上应下调,或设为空字符串以自动协商(见故障排查)

源码视角:DOCKER_API_VERSION 的底层行为

在 DockerAgent/otel-collector-config.yaml 中,docker_statsreceiver 的api_version直接绑定该环境变量:

receivers: docker_stats: endpoint: unix:///var/run/docker.sock api_version: "${env:DOCKER_API_VERSION}" collection_interval: 30s

配置中特意使用plain ${env:...}而非${env:...:-1.44},原因是 confmap 的:-默认值只在变量未设置时生效,无法捕获 Compose 注入的空字符串;而未设置时本来就会退化为自动协商,那反而是更安全的行为。

该 receiver 在 0.154.0 版本下的行为(配置注释中已验证):

  • 守护进程会拒绝比其自身最大版本更新的客户端(报错client version 1.44 is too new),且被拒绝的 receiver 启动失败会拖垮整个 Collector;
  • api_version留空是安全而非损坏的:receiver 会请求 Docker SDK 自动协商(先发一次HEAD /_ping,然后采用守护进程自身的最大版本),兼容新旧任何守护进程。

源码视角:被显式开启的指标

docker_statsreceiver 中还有一组默认关闭、必须显式开启的指标,因为 OneUptime 的 Docker 监控器告警模板依赖它们(容器重启次数、运行时长、PID 数、CPU 节流):

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

验证安装

检查 Agent 是否运行:

docker ps --filter name=oneuptime-docker-agent

查看 Agent 日志:

docker logs -f oneuptime-docker-agent

重点关注日志中的这一行就绪标记:

"Everything is ready. Begin running and processing data."

看到该行后,通常一分钟内,主机就会出现在 OneUptime 控制台中,指标与日志开始流入。

Agent 更新与卸载

更新(docker run 方式)

docker pull oneuptime/docker-agent:release docker rm -f oneuptime-docker-agent # 重新执行上面的 docker run 命令

更新(Docker Compose 方式)

docker compose pull docker compose up -d

卸载(docker run 方式)

docker rm -f oneuptime-docker-agent

卸载(Docker Compose 方式)

docker compose down

仓库说明(DockerAgent/README.md)还提供了本地构建镜像的方法(用于开发或离线环境):在仓库根目录执行npm run prerun生成 Dockerfile,再docker build -f ./DockerAgent/Dockerfile -t oneuptime/docker-agent:local .

Agent 收集哪些数据

下表汇总了 Agent 采集的数据类别:

类别数据
CPU 指标总用量、使用百分比、节流(throttling)时间(按容器)
内存指标使用量、限制、百分比、RSS、Cache(按容器)
网络指标接收/发送的字节数与数据包数(按容器)
块 I/O 指标读/写的字节数与操作次数(按容器)
容器信息运行时长(uptime)、重启次数、进程数
容器日志所有容器的 stdout/stderr 日志

在 DockerAgent/README.md 中可以找到这些指标对应的 OpenTelemetry 指标名:

  • CPUcontainer.cpu.usage.totalcontainer.cpu.percentcontainer.cpu.throttling_data.throttled_time
  • 内存container.memory.usage.totalcontainer.memory.usage.limitcontainer.memory.percent
  • 网络container.network.io.usage.rx_bytescontainer.network.io.usage.tx_bytes
  • 块 I/Ocontainer.blockio.io_service_bytes_recursive.readcontainer.blockio.io_service_bytes_recursive.write
  • 容器信息container.uptimecontainer.restartscontainer.pids.count

容器日志的处理链路

日志通过filelogreceiver 从/var/lib/docker/containers/*/*-json.log读取,并经过一串操作符(operators)处理(见 DockerAgent/otel-collector-config.yaml):

  1. json_parser:解析 Docker JSON 日志信封,提取时间戳;
  2. regex_parser:从文件路径中提取容器 ID,并提升为resource.container.id,用于与 docker_stats 指标关联;
  3. move:把log字段移动到body、把stream移动到log.iostream
  4. recombine:把同一容器日志文件中连续的多行记录合并为一条(处理多行堆栈信息,如 Node.js 异常栈帧),source_identifier防止不同容器的记录被错误合并;
  5. severity 推导链(router → regex_parser → add 兜底 → severity_parser → remove);
  6. 日志以原生 OpenTelemetry 日志记录格式发出,severityTextseverityNumberbodyattributestraceIdspanId字段全部填充。

日志严重性(severity)推导机制

Docker 的 json-file 日志驱动本身不记录严重级别,因此 Agent 必须自行推导。其策略是:优先从日志行正文中读取级别关键字,读取不到时才回退到 stdout/stderr 流(stderr → ERROR,stdout → INFO)。

级别关键字只有在符合以下两种“真正的级别位置”时才被采信(详见配置注释与 Tests/Ops/ContainerAgentLogSeverity.test.js 中的语料库):

  1. 行首前导(LINE PREAMBLE):关键字位于记录首行,其前全部是标点、数字或以结构化分隔符(.]=-:/|)}等)结尾的词元。例如[ERROR] ...、Monolog 的app.INFO: ...2026-08-31 07:25:04 INFO ...、logfmt 的level=error ...。普通叙述性文本不算前导——Connection error, retrying会在Connection处被截停,不会误判。
  2. 级别字段(LEVEL FIELD):关键字是行内 level 类键(level/lvl/severity/severity_text/levelname/log.level/log_level)的值,无论是否加引号、以:=分隔。例如 zap/logrus 的{"level":"info"}以及 logfmt 的非首字段级别。

这套推导链的边界行为(均由测试锁定):

  • 普通消息顺带提及"error"、"panic" 等词不会被采信(如{"status":"ok","error":null}仍是 Info,Recovered from panic不会变成 Fatal);
  • 前导级别优先于行内级别字段;
  • 支持 PSR-3 全部八个级别(含ALERTEMERGENCY),nginx 的[emerg]也映射到 Fatal;
  • 配置中的mapping:块补充了 stanza 内置 preset 不认识的别名(notice/crit/critical/panic/alert/emerg/emergency)。

库存快照(Inventory)

除了指标与日志,Agent 还通过 DockerAgent/inventory-snapshot.sh 每 300 秒(可通过DOCKER_INVENTORY_INTERVAL_SECONDS调整)轮询一次 Docker 守护进程,抓取全部状态的容器、镜像、网络与卷,以{"oneuptime.docker.kind":"Container","data":{...}}的 JSON 信封逐行写入/var/log/oneuptime-docker-inventory.log,再由 collector 的filelog/inventoryreceiver 读取并沿独立的logs/inventory管道转发。写盘时先写.tmp再原子重命名,避免 collector 读到写了一半的文件。

日志驱动要求(重要)

Agent只能摄取使用 Dockerjson-file日志驱动的容器日志(这是 Docker 默认驱动)。若安装被覆盖为local(二进制 protobuf,写入local-logs/)、或journaldsyslogfluentdgelf等远程驱动,filelog receiver 将无法读取。

检查单个容器的日志驱动:

docker inspect <container> --format '{{.HostConfig.LogConfig.Type}}'

检查守护进程默认驱动:

docker info --format '{{.LoggingDriver}}'

为 Compose 服务切换为json-file并配置合理的轮转:

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 并**重建(而非仅重启)**相关容器——日志驱动在容器创建时即被绑定,已存在的容器会保留旧驱动直到被删除重建。

自托管 OneUptime

如果你自托管 OneUptime,将ONEUPTIME_URL设置为自己的实例:

-e ONEUPTIME_URL="https://your-oneuptime-host.example.com"

如果实例仅支持 HTTP,则使用http://并带上相应端口。

在 Collector 配置中,数据出口为${env:ONEUPTIME_URL}/otlp,并通过请求头x-oneuptime-service-token携带摄取令牌(见 DockerAgent/otel-collector-config.yaml 的exporters.otlphttp配置)。出口前还有batch(10s/1024 条)与memory_limiter(512 MiB,尖峰 128 MiB)处理器,以及一条过滤规则,用于丢弃 Collector 自身的噪音日志,避免自采集反馈循环。

故障排查

访问 Docker 套接字被拒绝

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 版本:

docker version --format '{{ .Server.APIVersion }}'

然后将结果传给 Agent(例如):

docker run -d ... -e DOCKER_API_VERSION=1.41 ...

或在 Compose 中设置DOCKER_API_VERSION。由于较新的守护进程仍会服务较旧的 API 版本,该设置即使在后端升级后依然有效,可在自己安排的时间移除。

如果不想查版本号,可将DOCKER_API_VERSION设为空字符串,Agent 会请求 Docker SDK 与守护进程自动协商(一次HEAD /_ping,随后采用守护进程自身的最大值),新旧守护进程均适用:

docker run -d ... -e DOCKER_API_VERSION= ...

Agent 显示为“已断开”

  1. 检查 Agent 是否运行:docker ps --filter name=oneuptime-docker-agent
  2. 检查 Agent 日志:docker logs oneuptime-docker-agent | grep -i error
  3. 核对 OneUptime URL 与服务令牌是否正确
  4. 确保 Docker 主机能通过网络访问 OneUptime 实例

没有指标显示

  1. 检查 Docker 套接字在 Agent 内部是否可访问:docker exec oneuptime-docker-agent ls -la /var/run/docker.sock
  2. 检查 Collector 日志是否有导出错误:docker logs oneuptime-docker-agent | tail -100
  3. 确保服务令牌有效且未过期

主机名显示为容器 ID

将环境变量DOCKER_HOST_NAME设置为可读名称,然后重新创建容器。此外,若在主机自动注册后更改DOCKER_HOST_NAME,OneUptime 会以新名称创建第二个主机行,日志会显示在新的主机条目下——因为 Docker 主机页面按resource.host.name(取自该环境变量)过滤。可用以下命令确认 Agent 实际写入的主机名:

docker inspect oneuptime-docker-agent --format '{{range .Config.Env}}{{println .}}{{end}}' | grep DOCKER_HOST_NAME

控制台没有容器日志(有指标但 Logs 页为空)

最常见原因是容器未使用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。切换到json-file后,必须重建(而非仅重启)每个容器:

# Docker Compose docker compose up -d --force-recreate <service> # 纯 Docker docker rm -f <container> docker run ... <image>

下一步

  • 配置Docker Monitors,针对容器 CPU / 内存 / 重启次数等条件触发告警——参见 Docker Monitor;
  • 若监控的是 Kubernetes 集群而非独立 Docker 主机,使用 OneUptime Kubernetes Agent;
  • 若是非容器化主机(Linux / macOS / Windows 虚拟机与裸金属),使用 Host OpenTelemetry Collector;
  • 需要深入了解 Agent 的完整行为、镜像标签与日志驱动要求,可继续阅读仓库中的 DockerAgent/README.md;其日志严重性推导的边界行为与回归用例,参见 Tests/Ops/ContainerAgentLogSeverity.test.js。

【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询