Docker 下的 Prometheus:安装与配置详解
随着微服务架构和云原生技术的兴起,有效的系统监控变得前所未有的重要。Prometheus 作为一款开源的监控和告警系统,凭借其强大的多维数据模型、灵活的查询语言 (PromQL) 和高效的时间序列数据存储,已成为云原生监控领域的实际标准。与此同时,Docker 容器技术以其轻量级、可移植和环境一致性的特点,极大地简化了应用的部署和管理。
将 Prometheus 部署在 Docker 中,能够充分利用两者的优势:Docker 提供了一个隔离、可复现的环境来运行 Prometheus 及其相关的组件(如 Exporters, Alertmanager, Grafana),简化了安装过程,避免了依赖冲突,并且易于扩展和管理。
本文将详细介绍如何在 Docker 环境下安装、配置和运行 Prometheus,包括数据持久化、配置抓取目标、与 Grafana 集成以及使用 Docker Compose 进行多服务管理等关键环节。
引言:Prometheus 与 Docker 的结合优势
在深入安装细节之前,我们先回顾一下 Prometheus 的核心工作原理以及为何选择在 Docker 中运行它。
Prometheus 核心概念回顾:
Prometheus 的核心是一个时间序列数据库,它通过“拉取”(pull) 的方式定期从配置好的目标(Targets)那里获取(scrape)指标数据。这些目标通常是运行在应用或主机上的 Exporter(导出器),它们将系统、应用或服务的内部指标暴露成 Prometheus 能够理解的格式(文本格式,通常通过 HTTP 端口暴露)。
- 指标 (Metrics): 具有时间戳和键值对标签(Labels)的时间序列数据。
- Exporter: 收集特定系统或应用指标并将其暴露给 Prometheus 的工具。例如,Node Exporter 收集主机系统指标,cAdvisor 收集容器指标。
- Target: 一个暴露了指标的终端节点(通常是
hostname:port
)。 - Scraping: Prometheus 定期从 Target 拉取指标数据的过程。
- PromQL: Prometheus 的查询语言,用于对时间序列数据进行灵活查询、聚合和分析。
- Alertmanager: 处理由 Prometheus 服务器发送的告警,进行去重、分组、路由到不同的接收方(如邮件、Slack 等)。
在 Docker 中运行 Prometheus 的优势:
- 简化安装与依赖管理: Docker 镜像包含了 Prometheus 运行所需的一切,无需在主机系统上手动安装依赖,避免了版本冲突问题。
- 环境一致性: 无论在开发、测试还是生产环境,Prometheus 都运行在相同的 Docker 容器中,保证了行为的一致性。
- 隔离性: Prometheus 及其数据、配置都封装在容器内部,与其他系统进程隔离,提高了安全性,减少了对宿主机环境的污染。
- 可移植性: 可以轻松地将 Prometheus 容器从一个 Docker 主机迁移到另一个。
- 易于管理: Docker 提供了标准的命令(
run
,stop
,start
,logs
,rm
等)来管理 Prometheus 容器的生命周期。结合 Docker Compose 或 Swarm/Kubernetes,可以更方便地部署和管理复杂的监控栈。 - 快速部署和扩展: 基于 Docker 镜像,可以快速启动 Prometheus 实例,并通过容器编排工具实现弹性扩展。
准备工作
在开始之前,请确保您的系统已经安装并配置好了 Docker。
- 安装 Docker Engine: 访问 https://docs.docker.com/get-docker/ 根据您的操作系统(Linux, Windows, macOS)选择对应的安装方法。
- 基础终端/命令行知识: 熟悉如何在终端中执行命令。
Docker 下的基本安装
最简单的在 Docker 中运行 Prometheus 的方式是直接拉取官方镜像并启动一个容器。
1. 拉取 Prometheus 镜像
首先,打开终端,拉取 Prometheus 的官方镜像。默认会拉取最新版本(latest
标签),您也可以指定特定版本,例如 v2.40.0
。
bash
docker pull prom/prometheus
这个命令会从 Docker Hub 下载 Prometheus 镜像到您的本地。
2. 运行 Prometheus 容器(临时版)
接下来,使用 docker run
命令启动一个 Prometheus 容器。
bash
docker run \
-d \
--name prometheus \
-p 9090:9090 \
prom/prometheus
-d
: 让容器在后台运行。--name prometheus
: 给容器指定一个易于识别的名称prometheus
。-p 9090:9090
: 将容器内部的 9090 端口映射到宿主机的 9090 端口。Prometheus 默认监听 9090 端口提供 Web UI 和/metrics
端点。prom/prometheus
: 指定要运行的镜像名称。
运行成功后,您应该能看到一串容器 ID。
3. 验证运行
打开您的浏览器,访问 http://localhost:9090
。您应该能看到 Prometheus 的 Web UI。
在 UI 中,您可以浏览“Status”->“Targets”页面,虽然此时还没有配置任何外部抓取目标,但 Prometheus 会默认抓取自己的指标 (prometheus
job)。您应该能看到一个 up
的目标,指向 Prometheus 自身的地址(在容器内部看是 localhost:9090
,对外暴露是宿主机的 9090 端口)。
这个基本安装存在的问题:
上面的方法虽然简单,但存在严重问题:
- 无配置: 容器使用的是 Prometheus 默认的内置配置,这非常有限,通常只能抓取自身指标。
- 无数据持久化: 所有指标数据都存储在容器的可写层。如果容器被删除或重新创建,所有数据都会丢失。这对于监控系统来说是不可接受的。
因此,我们需要一种方式来管理 Prometheus 的配置文件和数据,并确保它们能够持久化。
持久化配置与数据
为了在 Docker 中可靠地运行 Prometheus,我们需要使用 Docker 的卷(Volumes)机制来挂载外部目录或具名卷,以便存储配置文件和时间序列数据。
1. 理解 Docker Volume
Docker Volume 是推荐用于持久化容器生成和使用的数据的方法。它独立于容器的生命周期,即使容器被删除,Volume 中的数据也会保留。有两种主要类型:
- 绑定挂载 (Bind Mounts): 将宿主机文件系统上的一个路径挂载到容器中的一个路径。这非常适合用于挂载配置文件,您可以直接在宿主机上编辑文件。
- 具名卷 (Named Volumes): Docker 管理宿主机文件系统上的一个区域。您只需要指定卷的名称,Docker 会负责创建和管理卷的实际存储位置。这非常适合用于存储数据库文件或 Prometheus 的时间序列数据,因为您通常不需要直接访问这些文件的内部结构。
在 Prometheus 的场景下,我们通常使用绑定挂载来管理配置文件(因为它经常需要修改),使用具名卷来存储时间序列数据(因为数据量大,由 Prometheus 内部管理格式,且需要持久化)。
2. 创建 Prometheus 配置文件 (prometheus.yml
)
Prometheus 的核心配置是一个 YAML 文件,通常命名为 prometheus.yml
。它定义了全局参数、抓取目标、告警规则等。
首先,在宿主机上选择一个合适的目录(例如 /opt/prometheus/config
或 ~/prometheus/config
)来存放您的配置文件。创建这个目录并在其中创建一个名为 prometheus.yml
的文件。
“`bash
例如,在您的家目录下创建目录结构
mkdir -p ~/prometheus/config
touch ~/prometheus/config/prometheus.yml
“`
编辑 ~/prometheus/config/prometheus.yml
文件,写入以下基本内容:
“`yaml
global configuration
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is 1m.
evaluation_interval: 15s # Evaluate rules every 15 seconds. Default is 1m.
# scrape_timeout: 10s # scrape_timeout is set to the global default of 10s unless otherwise specified.
Alertmanager configuration
alerting:
alertmanagers:
– static_configs:
– targets:
# – alertmanager:9093 # Replace with your Alertmanager address if needed
Load rules once and periodically evaluate them according to the default retrieval interval.
rule_files:
# – “first_rules.yml”
# – “second_rules.yml”
A scrape configuration containing exactly one endpoint to scrape:
Here it’s Prometheus itself.
scrape_configs:
# The job name is added as a label job=<job_name>
to any timeseries scraped from this config.
– job_name: ‘prometheus’
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['localhost:9090']
“`
对 prometheus.yml
基本结构的解释:
global
: 定义全局参数,如抓取间隔 (scrape_interval
) 和规则评估间隔 (evaluation_interval
)。alerting
: 配置与 Alertmanager 的集成。暂时可以注释掉或保留示例。rule_files
: 指定告警规则文件的位置。scrape_configs
: 这是最重要的部分,定义了 Prometheus 需要从哪些目标抓取指标。job_name
: 定义一个作业名称,作为标签添加到从该配置抓取到的所有指标上。static_configs
: 一个简单的配置抓取目标列表的方式。targets
: 目标地址列表(hostname:port
)。默认配置中是['localhost:9090']
,这是 Prometheus 容器 内部 访问自身/metrics
的地址。
3. 创建用于存储数据的具名卷
使用 docker volume create
命令创建一个具名卷来存放 Prometheus 的时间序列数据库 (TSDB) 数据:
bash
docker volume create prometheus_data
这个命令会在 Docker 的卷管理区域创建一个名为 prometheus_data
的卷。
4. 使用配置文件和数据卷运行 Prometheus
现在,我们可以使用 docker run
命令,通过绑定挂载来挂载配置文件,并通过具名卷来挂载数据存储目录。
假设您的 prometheus.yml
位于 ~/prometheus/config/prometheus.yml
。
bash
docker run \
-d \
--name prometheus \
-p 9090:9090 \
-v ~/prometheus/config/prometheus.yml:/etc/prometheus/prometheus.yml \
-v prometheus_data:/prometheus \
prom/prometheus \
--config.file=/etc/prometheus/prometheus.yml \
--storage.tsdb.path=/prometheus \
--web.console.libraries=/usr/share/prometheus/console_libraries \
--web.console.html=/usr/share/prometheus/console_html
-v ~/prometheus/config/prometheus.yml:/etc/prometheus/prometheus.yml
: 将宿主机路径~/prometheus/config/prometheus.yml
文件绑定挂载到容器内部的/etc/prometheus/prometheus.yml
文件。Prometheus 容器默认查找/etc/prometheus/prometheus.yml
作为配置文件。-v prometheus_data:/prometheus
: 将名为prometheus_data
的具名卷挂载到容器内部的/prometheus
目录。Prometheus 默认将 TSDB 数据存储在/prometheus
目录。prom/prometheus
: 镜像名称。--config.file=/etc/prometheus/prometheus.yml
: explicitly tells the Prometheus process inside the container where to find the config file. While the image often defaults to this path, it’s good practice to specify it when providing a custom config via volume.--storage.tsdb.path=/prometheus
: 同上,指定数据存储路径。--web.console.libraries
和--web.console.html
: 这两个参数通常需要添加,以确保 Prometheus Web UI 中的一些内置控制台页面能够正常工作,因为它们依赖于容器内特定路径下的文件。
运行此命令后,Prometheus 容器将使用您提供的 prometheus.yml
配置文件启动,并将数据存储在 prometheus_data
具名卷中。您可以再次访问 http://localhost:9090
验证。
如果需要修改配置,只需编辑宿主机上的 ~/prometheus/config/prometheus.yml
文件,然后重启 Prometheus 容器即可加载新配置:
bash
docker restart prometheus
或者,Prometheus 支持在不重启的情况下重新加载配置(通过发送 SIGHUP 信号或调用 Web API)。在 Docker 中,您可以通过 docker exec
或更高级的方式(如集成到容器管理平台)来发送信号。对于简单的测试或非关键环境,重启容器是最直接的方式。对于生产环境,建议配置 Prometheus 的热加载。一种常见的方法是在容器内部启用 reload API,然后在宿主机上调用该 API:
“`bash
修改 prometheus.yml 文件后
确保prometheus启动时带有 –web.enable-lifecycle 参数
docker run … prom/prometheus –web.enable-lifecycle …
然后调用reload API
curl -X POST http://localhost:9090/-/reload
“`
监控目标:配置 Scrape
Prometheus 的核心功能是抓取目标。前面我们只配置了抓取 Prometheus 自身。现在,我们将配置 Prometheus 抓取其他服务。最常见的第一个抓取目标是 Node Exporter,用于监控主机系统的指标。
1. 在 Docker 中运行 Node Exporter
Node Exporter 也是一个轻量级的 Exporter,它需要访问宿主机的 /proc
, /sys
, /dev
等目录来收集硬件和操作系统指标。因此,运行 Node Exporter 容器时需要特别的卷挂载和配置。
bash
docker run \
-d \
--name node_exporter \
-p 9100:9100 \
-v "/proc:/host/proc:ro" \
-v "/sys:/host/sys:ro" \
-v "/:/rootfs:ro" \
quay.io/prometheus/node-exporter:latest \
--path.procfs=/host/proc \
--path.sysfs=/host/sys \
--collector.filesystem.mounted-filesystem-types="ext[34]|xfs|zfs" \
--collector.textfile.directory /etc/node-exporter/textfile.d
-p 9100:9100
: Node Exporter 默认监听 9100 端口。-v "/proc:/host/proc:ro"
等:将宿主机的/proc
,/sys
,/
(根文件系统)以只读方式挂载到容器内部的特定路径。注意容器内的路径前缀/host/
或/rootfs
是为了区分宿主机和容器自身的文件系统。quay.io/prometheus/node-exporter
: Node Exporter 的官方镜像位于 Quay.io 而非 Docker Hub。--path.procfs
,--path.sysfs
: 告诉 Node Exporter 在容器内部的哪个路径找到宿主机挂载的/proc
和/sys
。--collector.filesystem.mounted-filesystem-types
: 限制文件系统采集器只监控指定的类型,避免监控 Docker 内部的虚拟文件系统等。--collector.textfile.directory
: (可选) 指定一个目录,Node Exporter 会读取该目录下的文本文件并解析其中的指标。
Node Exporter 运行后,您可以通过浏览器访问 http://localhost:9100/metrics
来查看它暴露的原始指标数据。
2. 配置 Prometheus 抓取 Node Exporter
现在,我们需要修改 ~/prometheus/config/prometheus.yml
文件,添加一个抓取 Node Exporter 的配置。
编辑 ~/prometheus/config/prometheus.yml
文件,在 scrape_configs
部分添加一个新的 job_name
:
“`yaml
… (前面的 global, alerting, rule_files 不变)
scrape_configs:
– job_name: ‘prometheus’
static_configs:
– targets: [‘localhost:9090’] # 这是Prometheus自身
- job_name: ‘node_exporter’ # 新增的作业名称
static_configs:
# 这里的 IP 和端口是 Prometheus 容器如何访问 Node Exporter 容器
# 如果两个容器都在默认 bridge 网络下,可以直接使用宿主机 IP 或 host.docker.internal
# 如果使用 docker-compose 或自定义网络,可以使用服务名称或容器名称- targets: [‘HOST_IP_OR_DOCKER_HOST_INTERNAL:9100’] # <—- 请替换这里的地址
# 如果Node Exporter是运行在宿主机上且端口映射到宿主机,这里写宿主机IP或localhost都可以
# 如果Node Exporter和Prometheus都在同一个Docker网络,且Node Exporter容器名称是node_exporter,这里可以写 ‘node_exporter:9100’
# 如果 Node Exporter 使用 network_mode: host 运行,则直接写宿主机 IP 或 localhost
“`
- targets: [‘HOST_IP_OR_DOCKER_HOST_INTERNAL:9100’] # <—- 请替换这里的地址
如何确定 targets
地址?
这取决于您的网络模式:
- 默认 Bridge 网络 (非 Compose): 如果 Prometheus 和 Node Exporter 都运行在默认的 bridge 网络下,并且 Node Exporter 的 9100 端口映射到了宿主机,那么 Prometheus 容器需要通过宿主机的 IP 地址或特殊的
host.docker.internal
(Docker Desktop for Windows/macOS) 来访问 Node Exporter。在 Linux 上,您可能需要找到宿主机的 bridge 网卡 IP,或者考虑使用network_mode: host
或自定义网络。简单起见,如果 Node Exporter 的 9100 端口映射到了宿主机,通常可以使用宿主机的 IP 或localhost
(如果 Prometheus 使用network_mode: host
),或者在 Docker Desktop 上使用host.docker.internal
。 - 自定义网络或 Docker Compose: 这是推荐的方式。创建一个自定义网络,将 Prometheus 和 Node Exporter 都连接到这个网络。在这种情况下,它们可以通过容器名称互相访问。例如,如果 Node Exporter 的容器名称是
node_exporter
并且在同一个自定义网络中,Prometheus 的 target 就是node_exporter:9100
。我们将稍后详细介绍 Docker Compose。
对于简单测试,假设您的 Node Exporter 端口 9100 已经映射到宿主机,并且您在 Linux 主机上:
- 查找宿主机 IP 地址(例如使用
ip addr show docker0
或ifconfig docker0
查找 Docker bridge 网卡的 IP)。 - 将
targets
设置为['您的宿主机IP:9100']
。
或者,更推荐的方式(特别是对于 Linux):
运行 Node Exporter 时使用 network_mode: host
。这将使 Node Exporter 直接使用宿主机的网络栈,监听在宿主机的 9100 端口。
bash
docker run \
-d \
--name node_exporter \
--network host \ # <-- 使用 host 网络模式
-v "/proc:/host/proc:ro" \
-v "/sys:/host/sys:ro" \
-v "/:/rootfs:ro" \
quay.io/prometheus/node-exporter:latest \
--path.procfs=/host/proc \
--path.sysfs=/host/sys \
--collector.filesystem.mounted-filesystem-types="ext[34]|xfs|zfs" \
--collector.textfile.directory /etc/node-exporter/textfile.d
注意:--network host
模式下 -p
端口映射不再有效,容器直接使用宿主机的端口。
如果 Node Exporter 使用 network_mode: host
运行,并且 Prometheus 容器 不是 使用 network_mode: host
,那么 Prometheus 容器仍然需要通过宿主机 IP 访问 Node Exporter。如果 Prometheus 容器 也 使用 network_mode: host
运行,那么它们都在宿主机的网络空间,可以通过 localhost:9100
直接访问。
假设 Node Exporter 使用 network_mode: host
运行,并且 Prometheus 使用标准的端口映射 -p 9090:9090
(默认 bridge 网络),则修改后的 prometheus.yml
如下:
“`yaml
… (前面的 global, alerting, rule_files 不变)
scrape_configs:
– job_name: ‘prometheus’
static_configs:
– targets: [‘localhost:9090’]
- job_name: ‘node_exporter’
static_configs:
# Prometheus 容器需要访问宿主机的 9100 端口
# 在 Linux 默认 bridge 网络下,需要宿主机 IP
# 或者,如果 Node Exporter 使用 network_mode: host,且 Prometheus 也使用 network_mode: host,则可以是 localhost:9100
# 在 Docker Desktop (Win/Mac) 下,可以使用 host.docker.internal:9100- targets: [‘宿主机IP_或_host.docker.internal:9100’] # <—- 请替换
“`
- targets: [‘宿主机IP_或_host.docker.internal:9100’] # <—- 请替换
修改完 prometheus.yml
后,记得重启 Prometheus 容器(或发送 SIGHUP 信号)来加载新配置:
bash
docker restart prometheus
访问 Prometheus Web UI (http://localhost:9090
),进入 “Status” -> “Targets” 页面,您应该能看到 node_exporter
job,并且状态为 UP
。这表示 Prometheus 已经成功连接并开始抓取 Node Exporter 的指标了。
可视化数据:与 Grafana 集成
Prometheus 提供了基本的 Web UI 用于查询和查看图表,但功能相对简单。Grafana 是一个流行的开源数据可视化和仪表盘工具,与 Prometheus 集成得非常好,提供了更丰富、更灵活的数据展示能力。
我们将在 Docker 中运行 Grafana,并将其配置为使用 Prometheus 作为数据源。
1. 在 Docker 中运行 Grafana
Grafana 也提供官方 Docker 镜像。我们也需要为 Grafana 的数据(仪表盘、数据源配置等)进行持久化。
bash
docker run \
-d \
--name grafana \
-p 3000:3000 \
-v grafana_data:/var/lib/grafana \
grafana/grafana:latest
-p 3000:3000
: Grafana 默认监听 3000 端口。-v grafana_data:/var/lib/grafana
: 创建一个名为grafana_data
的具名卷,并挂载到容器内部/var/lib/grafana
,用于存储 Grafana 的数据库、插件等数据。grafana/grafana:latest
: Grafana 官方镜像。
创建具名卷(如果不存在):
bash
docker volume create grafana_data
运行成功后,您可以通过浏览器访问 http://localhost:3000
来访问 Grafana Web UI。默认用户名和密码都是 admin
,首次登录会要求修改密码。
2. 配置 Grafana 连接 Prometheus 数据源
登录 Grafana 后,按照以下步骤添加 Prometheus 作为数据源:
- 点击左侧菜单栏的齿轮图标(Configuration)。
- 选择 “Data sources”。
- 点击 “Add data source”。
- 在列表中找到并选择 “Prometheus”。
在 Prometheus Data Source 配置页面:
- Name: 给这个数据源起一个名称,例如
Prometheus
。 -
URL: 这是最关键的部分,需要填写 Grafana 容器如何访问 Prometheus 容器的地址。
- 如果 Prometheus 使用端口映射
-p 9090:9090
并且您在 Linux 主机上,可能需要填写http://您的宿主机IP:9090
。 - 如果在 Docker Desktop (Win/Mac) 上,可以使用
http://host.docker.internal:9090
。 - 推荐方式(使用 Docker Compose 或自定义网络): 如果 Grafana 和 Prometheus 在同一个 Docker 网络中,并且 Prometheus 容器/服务名称是
prometheus
,则直接填写http://prometheus:9090
。我们将在下一节介绍 Docker Compose。
- 如果 Prometheus 使用端口映射
-
其他选项(Access, Auth, HTTP Headers 等)通常保持默认即可。
点击 “Save & Test”。如果配置正确,应该会显示 “Data source is working” 或类似的成功消息。
3. 导入仪表盘
Grafana 的强大之处在于其丰富的社区仪表盘。您可以导入预先设计好的仪表盘来快速可视化常见的监控指标。
例如,要监控 Node Exporter 收集的主机指标,可以导入社区提供的 Node Exporter Full 仪表盘。
- 访问 Grafana 官网的 Dashboards 页面 (https://grafana.com/grafana/dashboards/)。
- 搜索 “Node Exporter”。
- 找到一个合适的仪表盘(例如 ID 为 1860 的 “Node Exporter Full”)。复制其 ID。
- 回到 Grafana UI,点击左侧菜单栏的加号图标(Create)。
- 选择 “Import”。
- 在 “Import via grafana.com” 输入框中粘贴仪表盘 ID (1860),然后点击 “Load”。
- 在导入页面,选择之前配置的 “Prometheus” 数据源,然后点击 “Import”。
现在,您应该能看到一个展示主机 CPU、内存、磁盘、网络等详细指标的仪表盘了。您可以尝试使用 PromQL 在 Grafana 中构建自己的查询和图表。
使用 Docker Compose 管理监控栈
当监控系统变得复杂,包含 Prometheus, Grafana, Alertmanager, 多个 Exporters 等多个组件时,手动管理每个容器会变得繁琐。Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具,它使用一个 YAML 文件来配置应用的服务、网络和卷,然后通过一个命令即可创建和启动所有服务。
使用 Docker Compose 管理监控栈是推荐的生产环境实践。
1. 安装 Docker Compose
如果您使用的是 Docker Desktop for Windows 或 macOS,Docker Compose 已经内置。对于 Linux 用户,可能需要单独安装。请参考官方文档:https://docs.docker.com/compose/install/
2. 创建 docker-compose.yml
文件
在您的项目目录下(例如 ~/monitoring-stack
)创建一个名为 docker-compose.yml
的文件。
bash
mkdir ~/monitoring-stack
cd ~/monitoring-stack
touch docker-compose.yml
编辑 docker-compose.yml
文件,添加 Prometheus 和 Grafana 服务以及必要的卷和网络配置:
“`yaml
version: ‘3.8’ # 指定 Docker Compose 文件格式版本
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
– “9090:9090” # 将容器的9090端口映射到宿主机的9090端口
volumes:
– ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml # 挂载配置文件
– prometheus_data:/prometheus # 挂载数据卷
command: # 容器启动时执行的命令
– ‘–config.file=/etc/prometheus/prometheus.yml’
– ‘–storage.tsdb.path=/prometheus’
– ‘–web.console.libraries=/usr/share/prometheus/console_libraries’
– ‘–web.console.html=/usr/share/prometheus/console_html’
# – ‘–web.enable-lifecycle’ # 如果需要热加载配置,取消注释
restart: unless-stopped # 容器退出时自动重启,除非手动停止
networks:
– monitor-net # 将prometheus连接到自定义网络
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
– “3000:3000” # 将容器的3000端口映射到宿主机的3000端口
volumes:
– grafana_data:/var/lib/grafana # 挂载数据卷
# – ./grafana/provisioning/:/etc/grafana/provisioning/ # 可选:挂载配置目录
restart: unless-stopped
networks:
– monitor-net # 将grafana连接到自定义网络
node_exporter: # 添加 Node Exporter 服务
image: quay.io/prometheus/node-exporter:latest
container_name: node_exporter
# 注意:为了让 Node Exporter 访问宿主机指标,推荐使用 host 网络模式
network_mode: host # 使用宿主机网络
pid: host # 允许访问宿主机的进程ID空间,获取进程指标
volumes:
– /proc:/host/proc:ro
– /sys:/host/sys:ro
– /:/rootfs:ro
command:
– ‘–path.procfs=/host/proc’
– ‘–path.sysfs=/host/sys’
– ‘–collector.filesystem.mounted-filesystem-types=ext[34]|xfs|zfs’
– ‘–collector.textfile.directory=/etc/node-exporter/textfile.d’ # Textfile collector 目录
restart: unless-stopped
# Node Exporter 使用 host 网络,不需要连接到 monitor-net
# 如果需要通过容器名称访问,则不能使用 host 网络,需要复杂的端口映射或自定义网络配置
volumes: # 定义具名卷
prometheus_data:
grafana_data:
networks: # 定义自定义网络
monitor-net:
driver: bridge # 使用 bridge 驱动
“`
配置说明:
version
: 指定 Compose 文件版本。services
: 定义组成应用的服务。prometheus
,grafana
,node_exporter
: 每个服务对应一个容器。image
: 指定使用的 Docker 镜像。container_name
: 指定容器名称。ports
: 端口映射。volumes
: 卷挂载。这里使用了绑定挂载./prometheus/prometheus.yml
(宿主机当前目录下的prometheus/prometheus.yml
) 和具名卷prometheus_data
。command
: 容器启动时执行的命令,覆盖镜像默认的启动命令。restart: unless-stopped
: 容器退出时(非手动停止)自动重启。networks
: 将服务连接到指定的网络。
volumes
: 定义 Compose 管理的具名卷。networks
: 定义 Compose 管理的网络。这里创建了一个名为monitor-net
的 bridge 网络。
3. 更新 Prometheus 配置文件 (prometheus.yml
)
在 ~/monitoring-stack/prometheus
目录下创建或复制您的 prometheus.yml
文件。
修改 prometheus.yml
中的 scrape_configs
,特别是 node_exporter
的 target 地址。由于 Prometheus 和 Grafana 在同一个 monitor-net
网络中,并且 Node Exporter 使用 network_mode: host
,Prometheus 需要通过宿主机的 IP 或 host.docker.internal
来访问 Node Exporter 监听的 9100 端口。
“`yaml
… (global 等不变)
scrape_configs:
– job_name: ‘prometheus’
# 如果 prometheus 服务也使用 host 网络,这里可以是 ‘localhost:9090’
# 如果 prometheus 使用默认网络并映射端口,这里是它自己容器内部的地址
static_configs:
– targets: [‘localhost:9090’] # Prometheus 容器内部访问自身
- job_name: ‘node_exporter’
static_configs:
# Node Exporter 使用 host 网络,Prometheus 容器需要访问宿主机 IP 的 9100 端口
# 在 Docker Desktop (Win/Mac) 可以用 host.docker.internal
# 在 Linux 上需要宿主机 IP- targets: [‘宿主机IP_或_host.docker.internal:9100’] # <—- 请替换
“`
- targets: [‘宿主机IP_或_host.docker.internal:9100’] # <—- 请替换
更灵活的 Docker Compose 网络配置:
如果您不希望 Node Exporter 使用 network_mode: host
(例如因为它不适用于所有操作系统或更喜欢容器网络的隔离性),则需要将 Node Exporter 也加入 monitor-net
网络,并在其 docker-compose.yml
中移除 network_mode: host
和 pid: host
(或进行更复杂的配置来访问宿主机文件系统)。
在这种情况下,Node Exporter 的 docker-compose.yml
部分会类似这样:
yaml
node_exporter:
image: quay.io/prometheus/node-exporter:latest
container_name: node_exporter
ports:
- "9100:9100" # 如果不使用 host 网络,需要映射端口
# 注意:如果不用 host 网络,Node Exporter 容器内部访问宿主机文件系统需要复杂的配置,
# 或者考虑使用特定为容器环境设计的 Exporter,如 cAdvisor
# 如果只是监控容器内部或不关心宿主机底层指标,可以不用挂载那些卷
# 如果仍想监控宿主机且不用 host 网络,可能需要在容器内部配置特权模式或额外的 capabilities,比较复杂。
# 鉴于 Node Exporter 通常就是为了监控宿主机,network_mode: host 是最常见和简单的方案。
restart: unless-stopped
networks:
- monitor-net # Node Exporter 也加入这个网络
如果 Node Exporter 加入 monitor-net
,并且其服务名称在 docker-compose.yml
中是 node_exporter
,则 Prometheus 的 targets
可以写成:
yaml
- job_name: 'node_exporter'
static_configs:
- targets: ['node_exporter:9100'] # 通过服务名称访问 Node Exporter
出于简化和监控宿主机指标的目的,本文后续示例将沿用 Node Exporter 使用 network_mode: host
的方式。
4. 启动监控栈
在包含 docker-compose.yml
文件的目录下,运行以下命令:
bash
docker-compose up -d
up
: 创建并启动docker-compose.yml
文件中定义的所有服务。-d
: 在后台运行容器。
Docker Compose 会创建 monitor-net
网络,prometheus_data
和 grafana_data
卷(如果它们不存在),然后启动 Prometheus, Grafana 和 Node Exporter 容器,并将它们连接到指定的网络(Node Exporter 除外,因为它使用了 host 网络)。
您可以通过 docker-compose ps
命令查看所有服务的运行状态。
5. 停止和移除监控栈
要停止所有服务(不删除数据和配置):
bash
docker-compose stop
要停止并移除所有容器、网络(不删除卷):
bash
docker-compose down
要停止并移除所有容器、网络和卷:
bash
docker-compose down --volumes
使用 Docker Compose 的好处:
- 一体化管理: 所有组件的定义都在一个文件里。
- 简化命令: 只需几个
docker-compose
命令就能管理整个应用栈。 - 网络和卷管理: Compose 自动处理网络和卷的创建和连接。
- 服务发现: 在同一个 Compose 网络中的服务可以通过服务名称相互访问(例如 Grafana 访问
http://prometheus:9090
)。
监控 Docker 容器(使用 cAdvisor – 简要提及)
除了监控主机,Prometheus 也可以监控 Docker 容器本身的资源使用情况。cAdvisor (Container Advisor) 是 Google 开发的一个容器监控工具,它可以自动发现同一台机器上运行的所有容器,并收集它们的 CPU、内存、网络、文件系统等指标。cAdvisor 也可以作为 Prometheus 的 Exporter 使用。
在 Docker 中运行 cAdvisor:
bash
docker run \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:rw \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--volume=/dev/disk/:/dev/disk:ro \
--publish=8080:8080 \
--detach=true \
--name=cadvisor \
--restart=unless-stopped \
google/cadvisor:latest
然后,您可以在 prometheus.yml
中添加一个 scrape 配置来抓取 cAdvisor 容器的 8080 端口(如果 cAdvisor 运行在宿主机网络或端口映射到宿主机)。
yaml
- job_name: 'cadvisor'
static_configs:
- targets: ['宿主机IP_或_host.docker.internal:8080'] # <---- cAdvisor地址
将 cAdvisor 添加到 docker-compose.yml
并将其与 Prometheus 放在同一个网络中会更方便,可以通过服务名称访问:
yaml
cadvisor:
image: google/cadvisor:latest
container_name: cadvisor
ports:
- "8080:8080" # 端口映射到宿主机
volumes: # cAdvisor 需要访问宿主机特定目录
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
# - /dev/disk/:/dev/disk:ro # 某些指标可能需要
restart: unless-stopped
networks:
- monitor-net # 加入监控网络
# 额外的特权或capabilities可能根据需要添加
privileged: true # 或者 cap_add: - SYS_ADMIN
相应的 Prometheus scrape_config
(如果 cAdvisor 在 monitor-net
中且服务名称为 cadvisor
):
yaml
- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080'] # 通过服务名称访问 cAdvisor
告警管理(使用 Alertmanager – 简要提及)
Prometheus 负责收集和评估规则,但发送告警通知的任务则由 Alertmanager 负责。Alertmanager 接收来自 Prometheus 的告警,进行分组、去重,然后路由到配置的接收方(如邮件、Slack、钉钉等)。
要在 Docker 中运行 Alertmanager,您也需要为其配置持久化存储和配置文件。
bash
docker run \
-d \
--name alertmanager \
-p 9093:9093 \
-v ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml \
-v alertmanager_data:/data \
prom/alertmanager:latest \
--config.file=/etc/alertmanager/alertmanager.yml \
--storage.path=/data
创建 Alertmanager 的配置文件 alertmanager.yml
和具名卷 alertmanager_data
是必要的。
然后在 Prometheus 的 prometheus.yml
中配置与 Alertmanager 的连接(通常在其 alerting
部分)。
yaml
alerting:
alertmanagers:
- static_configs:
# 如果 Alertmanager 在 monitor-net 中且服务名称是 alertmanager
- targets: ['alertmanager:9093']
# 如果 Alertmanager 端口 9093 映射到宿主机,则需要宿主机 IP 或 host.docker.internal
# - targets: ['宿主机IP_或_host.docker.internal:9093']
在 docker-compose.yml
中添加 Alertmanager 服务:
“`yaml
alertmanager:
image: prom/alertmanager:latest
container_name: alertmanager
ports:
– “9093:9093” # Alertmanager 默认端口
volumes:
– ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml
– alertmanager_data:/data
command:
– ‘–config.file=/etc/alertmanager/alertmanager.yml’
– ‘–storage.path=/data’
restart: unless-stopped
networks:
– monitor-net # 加入监控网络
volumes:
# … 其他卷
alertmanager_data:
“`
关于 Alertmanager 本身的详细配置(如接收器、路由规则)超出了本文范围,但上述步骤展示了如何在 Docker 环境下将其与 Prometheus 集成。
常见问题与故障排除
在 Docker 环境下配置 Prometheus 时,可能会遇到一些问题:
- 端口冲突: 确保 Prometheus (9090), Grafana (3000), Node Exporter (9100), cAdvisor (8080), Alertmanager (9093) 等端口没有被宿主机上其他进程占用。
- 配置文件路径或权限问题: 检查
-v
参数中宿主机路径是否正确。确保 Prometheus 容器内的用户对挂载的配置文件和数据目录有读写权限。默认情况下,Prometheus 容器以非 root 用户运行,可能需要调整宿主机文件或目录的权限(例如chmod -R 777 ~/prometheus
或更精细的控制)。 - 抓取目标无法访问:
- 检查 Prometheus Web UI 的 “Status” -> “Targets” 页面,查看具体错误信息。
- 检查目标 Exporter 是否正在运行,并且其端口是否正确暴露。
- 检查 Prometheus 容器与目标 Exporter 容器之间的网络连通性。如果使用 Docker Compose 或自定义网络,确保它们在同一个网络中。如果使用宿主机网络,确保防火墙允许通信。
targets
配置中的 IP 或主机名是否正确。
- 配置加载失败: 检查
prometheus.yml
文件是否存在语法错误(YAML 格式要求严格)。可以使用在线 YAML 校验工具或promtool check config prometheus.yml
命令(需要在安装了 prometheus/promtool 的环境中执行)进行检查。查看 Prometheus 容器的日志 (docker logs prometheus
) 获取详细错误信息。 - 数据卷问题: 检查具名卷是否正确创建和挂载。如果遇到数据持久化问题,可以尝试删除并重新创建具名卷(注意备份数据!)。
总结
本文详细介绍了如何在 Docker 环境下安装和配置 Prometheus,并涵盖了与其生态系统中重要组件(Node Exporter, Grafana, Alertmanager)的集成方法。
从最基本的容器运行,到使用 Docker Volume 进行数据和配置的持久化,再到利用 Docker Compose 编排整个监控栈,这些步骤展示了 Docker 如何简化复杂的监控系统部署。通过将 Prometheus 及其依赖项容器化,我们获得了环境隔离、易于管理、可移植和可复现的优势。
在 Docker 中运行 Prometheus 仅仅是构建强大监控体系的第一步。在此基础上,您可以进一步探索:
- 更多的 Exporter: 监控数据库、消息队列、Web 服务器等各种服务。
- 服务发现 (Service Discovery): 利用 Docker、Kubernetes、Consul 等平台的 API 自动发现和配置抓取目标,无需手动修改
prometheus.yml
。 - 告警规则编写: 定义自己的 PromQL 规则来检测异常情况并触发告警。
- 高级 PromQL: 学习更复杂的查询技巧来深入分析指标数据。
- 长期存储: 考虑使用 Thanos 或 Cortex 等方案处理海量历史数据和分布式部署。
通过将 Prometheus 与 Docker 结合,您可以更高效、更可靠地构建和维护您的监控基础设施,为保障系统的稳定运行提供坚实的基础。
希望本文能帮助您顺利在 Docker 中搭建起自己的 Prometheus 监控系统!