Docker 主机突然变慢,先别急着搭监控栈:用 Netdata 从逐秒指标定位 CPU、I/O 与容器异常
一台承载 API、队列和定时任务的 Docker 主机突然变慢,常见的第一反应是打开 top、查看容器日志,或者着手部署 Prometheus 和 Grafana。前两者只能看到某一个瞬间,后一种则需要先决定采集器、存储、仪表盘和告警规则。对于“现在到底是哪一层拖慢了机器”的排障问题,更实用的起点是先拿到连续、逐秒且能关联主机与容器的观测数据。
Netdata 是一个 GPL-3.0 开源的实时基础设施监控项目。它的 Agent 会自动发现许多系统与容器指标,并在本地提供 Web 界面;Netdata Cloud 是可选组件,项目明确说明数据可以留在自己的基础设施中。它并不取代已有的长期指标平台,但很适合作为单机或小规模环境的第一观察层:先缩小故障范围,再决定是否要把问题固化为 Prometheus 查询、告警规则或容量计划。
先定义这次排障要回答什么
不要从“CPU 高”直接跳到重启容器。一次变慢至少要分成三个层面看:主机是否饱和、哪个容器或进程在消耗资源、以及资源消耗是否已经传导到请求延迟或错误。Netdata 的价值在于让这些时间线尽量对齐。
例如,CPU 曲线升高本身并不能说明是计算任务过多:如果 iowait 同时抬升,瓶颈可能在磁盘;如果网络重传增加,应用线程也可能是在等待网络;如果某个容器内存接近限制后频繁回收,CPU 波动可能只是连锁反应。排障时应先固定异常发生的时间窗口,再沿同一窗口查看 CPU、内存、磁盘、网络和容器维度,而不是在不同命令的即时输出之间猜因果。
Netdata README 列出的能力包含逐秒采集、实时可视化、系统/容器/硬件传感器等数据收集,以及自动异常检测。它也支持分层保留:Tier 0 是逐秒分辨率、Tier 1 是逐分钟、Tier 2 是逐小时;查询时会按缩放级别自动选取。这意味着刚发生的尖峰可以先用高分辨率查看,回溯更长周期时则不必把每秒数据全量呈现。
用官方 Docker 方式启动:先理解权限,再复制命令
官方 Docker 文档给出了下面的启动方式。示例使用 netdata/netdata:stable,避免未指定标签时默认拉取 latest 的不确定性。
docker run -d --name=netdata \ --pid=host \ --network=host \ -v netdataconfig:/etc/netdata \ -v netdatalib:/var/lib/netdata \ -v netdatacache:/var/cache/netdata \ -v /:/host/root:ro,rslave \ -v /proc:/host/proc:ro \ -v /sys:/host/sys:ro \ -v /var/log:/host/var/log:ro \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ --restart unless-stopped \ --cap-add SYS_PTRACE \ --cap-add SYS_ADMIN \ --security-opt apparmor=unconfined \ netdata/netdata:stable
启动后,可在部署机器访问 http://localhost:19999;从其他机器访问时,官方 README 给出的形式是 http://NODE:19999。在将端口暴露到非受信网络之前,应先在反向代理、防火墙或 VPN 层处理访问控制;监控界面通常会泄露主机名、服务名、进程和资源使用模式,不应当作普通公开页面。
更重要的是,不要把上面的命令当成无害的“看板容器”。--pid=host、--network=host、宿主机根目录及 /proc、/sys 挂载,都是为了让 Agent 看见宿主机;只读 Docker socket 也使它能够识别容器。官方文档还将 SYS_PTRACE 与本地服务发现关联,将 SYS_ADMIN 与网络 socket 观察关联。它们提升了诊断能力,也扩大了容器的可见范围。生产环境应由平台团队评审这些挂载和 capabilities,确认这台机器、这个运行账户以及界面访问者都在信任边界内;若只需要部分指标,应按官方采集器配置减少不必要的可见性。
一套从现象到根因的查看顺序
第一步,在总览中圈定异常分钟。观察 CPU 的 user、system 和 iowait,而不只是总使用率。user 持续高通常提示应用计算密集;system 高可继续检查内核、网络或频繁系统调用;iowait 高则先转向磁盘吞吐、延迟和队列。这里的关键是比较异常前后的基线:短暂 90% 不一定有问题,持续偏离平时模式才值得追。
第二步,检查内存和磁盘是否共同变化。内存使用升高不必然是泄漏,Linux 文件缓存也会占用可用内存;但如果可用内存下降、swap 活动增加,并且容器重启或延迟同时出现,就应进入对应容器和进程的指标。对于磁盘,优先对照 I/O 延迟、队列和写入量,而不是只看空间占用。空间快满与设备忙是两类不同问题,修复动作也不同。
第三步,回到 Docker 容器视角。找到异常窗口中 CPU、内存或网络变化最明显的容器,再把它的启动、部署、批处理或流量变化记录与时间线对齐。假如总 CPU 升高但单个业务容器都很平稳,应继续看宿主进程、日志处理、备份任务或邻居容器;假如单个容器的网络流量陡增,则需要结合应用日志与上游流量确认是正常高峰、重试风暴还是异常调用。
最后,把一次性观察转成可重复的运行手册。记录“异常时间、先看哪张图、触发进一步检查的阈值、需要联系的服务负责人”,比仅保存一张截图更有用。若团队已有 Prometheus,Netdata 可以承担快速定位的界面,而长期容量报表和跨集群 SLO 仍留在原有体系中。两个工具的边界应由保留周期、查询需求、权限模型和运维成本决定,不应把“安装更快”误解成“自动解决所有可观测性问题”。
把观察结果接到日常运维动作
一次排障结束后,最容易丢失的是上下文:谁先发现异常、异常从什么时候开始、部署与流量是否同时变化、最后确认的瓶颈是什么。可以把这四项写进值班记录,并为最常见的三类信号建立固定分流:CPU user 高时先核对业务计算、批处理和热点请求;iowait 高时先核对磁盘延迟、队列、备份及日志写入;网络曲线和重传异常时先核对入口流量、连接数和上游依赖。这样,下次不必从一排没有含义的图表重新开始。
需要注意,时间相关性不是因果关系。某个容器的内存上升与接口变慢同时发生,可能是泄漏,也可能只是缓存预热、流量上升或被其他进程挤压。把 Netdata 中的时间窗口与部署记录、应用日志、数据库慢查询及系统日志相互核对,才能把“值得怀疑的对象”推进到“可验证的根因”。对于不能立即复现的问题,保留异常窗口、关键指标名称和后续验证命令,通常比直接调整资源限制更能避免重复事故。
从权限治理看,监控 Agent 也应纳入资产清单:明确镜像版本、谁能修改挂载参数、谁能打开 UI、日志和指标保存多久,以及卸载时如何处理持久卷。尤其在共享 Docker 主机上,Docker socket 与宿主机路径的可见性意味着它不是一个普通业务容器。将这些决策与普通服务的发布审批同样对待,才能在获得排障效率的同时控制观测面带来的风险。
适用边界
Netdata 官方 README 宣称有 800 多项集成,并给出逐秒采集和自动异常检测等特性;这些是项目能力范围,不等于每个环境都会自动获得完整的应用语义。自定义业务指标、鉴权、跨集群关联和告警路由仍要单独验证。资源开销也应在自己的负载上测试:项目 README 中的 CPU、内存参考值是其默认生产配置的说明,不应直接当成所有宿主机的容量承诺。
如果当前痛点是“单台 Docker 主机偶发变慢,但没有足够线索判断从哪里开始看”,Netdata 是成本较低的第一步。如果目标是多年留存、复杂多租户权限或大规模全局聚合,则应将它视为现有可观测性体系的补充,并提前设计数据出口与访问控制。