Docker 容器日志与监控体系搭建:日志驱动、Prometheus 指标采集与告警

容器化部署让应用的交付效率大幅提升,但也带来了新的可观测性挑战:日志分散在无数个短生命周期的容器中,资源指标转瞬即逝,传统基于主机的监控手段在动态调度面前几乎失效。要真正掌控 Docker 环境,必须从日志采集和指标监控两条线同时入手,构建一套完整的可观测性体系。

一、Docker 日志驱动:从 json-file 到集中式采集

Docker 默认使用 json-file 日志驱动,将容器的标准输出和标准错误以 JSON 格式写入宿主机文件。这种方式在单机调试时足够方便,但在多容器、多主机的生产环境中,日志文件会迅速膨胀,且难以跨节点检索。

Docker 提供了多种日志驱动,常见的有:

  • json-file:默认驱动,支持 docker logs 命令,但需要配合日志轮转防止磁盘写满。
  • local:Docker 18.09 引入,采用更高效的二进制格式,同样支持 docker logs,推荐替代 json-file。
  • syslog / journald:将日志转发到系统日志服务,适合已有集中式日志基础设施的团队。
  • fluentd / gelf / awslogs:直接将日志推送到外部聚合系统,适合云原生环境。
  • none:禁用日志,仅在对日志毫无需求的场景使用。

选择日志驱动时,核心考量是:日志是否需要长期保留、是否需要跨主机检索、是否已有日志聚合平台。对于大多数生产环境,推荐将日志驱动设置为 fluentdlocal,再由 Fluent Bit / Fluentd 统一转发到 Elasticsearch 或 Loki。

配置方式有两种。全局配置修改 /etc/docker/daemon.json

{
  "log-driver": "local",
  "log-opts": {
    "max-size": "50m",
    "max-file": "5"
  }
}

单容器配置则在 docker run 或 Compose 文件中指定:

services:
  app:
    image: myapp:latest
    logging:
      driver: fluentd
      options:
        fluentd-address: "localhost:24224"
        tag: "docker.{{.Name}}"

需要特别注意:日志驱动一旦在容器创建时确定,就无法通过重启容器更改,必须重新创建容器。因此建议在项目初期就规划好日志策略。

二、Prometheus 指标采集:cAdvisor 与应用埋点

日志解决的是“发生了什么”,指标解决的是“系统状态如何”。Prometheus 已成为容器监控的事实标准,其拉取模型和强大的查询语言非常适合动态环境。

2.1 容器资源指标:cAdvisor

cAdvisor 是 Google 开源的容器资源采集器,能够自动发现宿主机上的所有容器,并暴露 CPU、内存、网络、文件系统等指标。部署方式非常简单:

services:
  cadvisor:
    image: gcr.io/cadvisor/cadvisor:latest
    ports:
      - "8080:8080"
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
      - /dev/disk/:/dev/disk:ro
    privileged: true
    devices:
      - /dev/kmsg

启动后访问 http://localhost:8080/metrics 即可看到 Prometheus 格式的指标。在 Prometheus 配置中加入抓取任务:

scrape_configs:
  - job_name: 'cadvisor'
    static_configs:
      - targets: ['cadvisor:8080']

2.2 应用层指标:Client Library 埋点

cAdvisor 只能提供容器级别的资源指标,业务层面的 QPS、延迟、错误率等需要应用自身暴露。Prometheus 提供了多语言客户端库,以 Go 为例:

httpRequestsTotal := prometheus.NewCounterVec(
    prometheus.CounterOpts{
        Name: "http_requests_total",
        Help: "Total number of HTTP requests",
    },
    []string{"method", "path", "status"},
)
prometheus.MustRegister(httpRequestsTotal)

http.Handle("/metrics", promhttp.Handler())

Python、Java、Node.js 等语言也有对应的客户端库。关键原则是:指标命名遵循 <namespace>_<subsystem>_<name> 规范,标签基数不宜过高,避免使用用户 ID 等高基数字段作为标签。

2.3 可视化:Grafana

Prometheus 自带的表达式浏览器适合调试,但日常监控需要 Grafana。导入社区维护的 Dashboard(如 cAdvisor 的 Dashboard ID 14282),几分钟内就能获得完整的容器监控视图。建议至少配置以下面板:

  • 容器 CPU 使用率与 throttling 次数
  • 容器内存使用量与 OOM 事件
  • 网络收发速率与丢包
  • 应用请求速率、P95/P99 延迟、错误率

三、告警规则:从指标到行动

监控的价值最终体现在告警上。Prometheus 的告警由 Alertmanager 负责路由和去重,规则则在 Prometheus 中定义。

3.1 编写告警规则

以下是一组实用的容器告警规则示例:

groups:
  - name: container_alerts
    rules:
      - alert: ContainerHighCpuUsage
        expr: sum(rate(container_cpu_usage_seconds_total{name!=""}[5m])) by (name) > 0.8
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "容器 {{ $labels.name }} CPU 使用率过高"
          description: "CPU 使用率已持续 10 分钟超过 80%"

      - alert: ContainerMemoryNearLimit
        expr: container_memory_usage_bytes / container_spec_memory_limit_bytes > 0.9
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "容器 {{ $labels.name }} 内存接近上限"

      - alert: ContainerRestarting
        expr: rate(container_last_seen{name!=""}[5m]) < 0.5
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "容器 {{ $labels.name }} 可能频繁重启"

3.2 告警分级与路由

告警不是越多越好。建议按严重程度分级:

  • critical:需要立即人工介入,如服务不可用、内存 OOM、磁盘写满。通过电话或即时通讯工具直接通知值班人员。
  • warning:需要关注但不必立即处理,如 CPU 持续偏高、延迟上升。通过邮件或低优先级频道通知。
  • info:仅记录,用于趋势分析,不主动推送。

Alertmanager 的 route 配置支持按标签匹配路由到不同接收器,inhibit_rules 可以在严重告警触发时抑制相关次要告警,避免告警风暴。

3.3 避免常见陷阱

  • 阈值不宜过紧:CPU 短时冲高是正常现象,for 子句能有效过滤抖动。
  • 标签基数控制:告警规则中避免使用容器 ID 等易变标签,否则告警分组会爆炸。
  • 定期回顾:每月审查一次告警历史,删除从未触发或频繁误报的规则。

四、体系整合与最佳实践

将日志和监控整合为统一的可观测性平台,建议遵循以下实践:

  1. 统一采集层:用 Fluent Bit 采集日志,用 Prometheus 采集指标,两者独立运行但共享标签体系(如 serviceenvversion),便于关联分析。
  2. 日志与指标联动:在 Grafana 中配置数据源关联,从指标面板一键跳转到对应时间段的日志查询。
  3. 资源限制与监控配合:为容器设置合理的 memorycpu 限制,监控告警阈值应略低于限制值,留出缓冲。
  4. 基础设施即代码:将 Prometheus 配置、告警规则、Grafana Dashboard 全部纳入 Git 管理,通过 CI/CD 自动部署。
  5. 容量规划:Prometheus 本地存储默认保留 15 天,生产环境建议配置远程存储(如 Thanos、VictoriaMetrics)以支持长期查询。

Docker 的可观测性建设不是一次性任务,而是伴随业务演进的持续过程。从日志驱动选型到指标采集,再到告警规则调优,每一步都需要结合自身业务特点做取舍。起步阶段不必追求大而全,先把核心指标和关键告警跑通,再逐步扩展覆盖范围,才能让监控体系真正服务于稳定性目标。

未经允许不得转载:任鹏个人博客 » Docker 容器日志与监控体系搭建:日志驱动、Prometheus 指标采集与告警

赞 (0) 打赏

评论 0

取消
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏