更新时间:2025 年 6 月
版本:Prometheus 3.4.x
官网:Prometheus
组件下载地址:Download | Prometheus
官方提供的 Ansible Role:prometheus-community/ansible: Ansible Collection for Prometheus
简介
Prometheus 是一个开源的系统监控和警报工具包
Prometheus 以时间序列(time series)数据的形式收集和存储指标(metrics)
- 时间序列数据:每个指标数据都会带有一个时间戳(timestamp),表示该数据的采集时间
- 标签(labels):除了指标值本身,每个数据点还可以附带可选的键值对(key-value pairs),这些标签用于区分相同类型的指标。例如,针对不同的主机、容器或服务的同一个 CPU 使用率指标,可以用
instance="host1"
或instance="host2"
来区分
功能
多维数据模型
- 时间序列数据 + 标签(Labels)实现灵活分类、过滤与聚合
数据采集
- 主动拉取(Pull)为主,支持 Pushgateway 推送短周期任务数据
- 集成 Exporters 监控第三方服务(如数据库、服务器)
PromQL 查询语言
- 实时分析指标,支持聚合、预测、多维度计算(如故障率、分位数)
告警与通知
- 基于 PromQL 定义规则,Alertmanager 处理告警去重、路由至邮件/Slack 等
存储与可视化
- 本地高效存储,兼容远程存储(如 Thanos)
- 原生 UI + Grafana 深度集成,灵活构建仪表盘
动态服务发现
- 自动发现 Kubernetes、Consul 等环境中的监控目标
高可用扩展
- 支持联邦集群(Federation)分片聚合,适应云原生架构
核心优势:专为云原生设计,灵活、多维、实时,适合微服务/容器监控
指标
指标(Metric)是用于描述系统或应用程序特定特征的度量标准,通常以时间序列的形式存储和表示。每个指标由指标名称(metric name)和一组键值对标签(label)组成,用于标识和区分不同的度量对象
指标类型
Prometheus 定义了四种核心指标类型,用于不同监控场景:
类型 | 用途 | 示例 |
---|---|---|
Counter | 累计递增的数值(如请求总数、错误次数) | http_requests_total{status="200"} |
Gauge | 瞬时值,可增可减(如CPU使用率、内存占用) | node_memory_free_bytes |
Histogram | 采样观测值分布(如请求延迟、响应大小),自动计算分位数(_bucket 、_sum 、_count ) | http_request_duration_seconds_bucket{le="0.1"} |
Summary | 类似直方图,但客户端计算分位数(如耗时百分比) | rpc_duration_seconds{quantile="0.99"} |
指标结构
每个指标由以下部分组成:
- 指标名称(Metric Name):描述监控的内容(如
http_requests_total
) - 标签(Labels):键值对,用于多维度分类(如
method="GET"
,path="/api"
) - 时间戳(Timestamp):数据点的时间。
- 值(Value):数值类型的监控数据
示例:
http_requests_total{method="GET", status="200", instance="10.0.0.1:8080"} 12345
标签(Labels)的作用
- 多维度切分:通过标签区分同一指标的不同维度(如按服务、状态码、实例分类)
- 查询灵活性:支持 PromQL 按标签过滤、聚合(如
sum(rate(http_requests_total{status=~"5xx"}[5m]))
) - 避免高基数:标签值需有限(如避免将用户ID作为标签),否则可能导致存储压力
指标的暴露方式
- HTTP Endpoint:应用程序通过
/metrics
端点暴露指标,供 Prometheus 主动拉取(Pull) - 客户端库:集成官方库(如 Go、Java、Python)或第三方库生成指标
- Exporters:通过 Exporter 转换第三方系统指标(如
node_exporter
采集服务器指标)
组件
Prometheus Server
- 核心服务,负责定时拉取(Scrape)指标、存储数据(TSDB)、执行 PromQL 查询。
Client Libraries
- 集成到应用中的代码库(如 Go/Python),暴露自定义指标供 Server 抓取。
Exporters
- 将第三方系统数据转为 Prometheus 格式(如 Node Exporter 监控服务器,MySQL Exporter 监控数据库)。
Pushgateway
- 临时存储短生命周期任务(如定时脚本)推送的指标,供 Server 拉取。
Alertmanager
- 接收告警,进行去重、分组、静默,并路由到邮件/Slack 等通知渠道。
其他支持的工具
-
Service Discovery:动态识别监控目标(支持 Kubernetes、Consul、AWS 等),自动适应服务扩缩容。
-
联邦集群(Federation):跨多个 Prometheus 实例聚合数据,支持分层监控架构。
架构

Prometheus 从已配置的作业中抓取指标,无论是直接还是通过中间推送网关为短期作业。它将所有抓取的样本本地存储,并在此数据上运行规则,以从现有数据中聚合和记录新的时间序列或生成警报。可以使用 Grafana 或其他 API 消费者来可视化收集到的数据
注意事项
- Prometheus 在采集和存储数据时,一律使用 UTC 时间,无论宿主机是东八区还是其他时区。这不会影响数据采集和准确性
- Prometheus Web UI 显示时间是 UTC,但可以设置显示本地时间
安装主机准备
主机准备
主机名 | 操作系统 | 架构 | IP | 安装软件 |
---|---|---|---|---|
prometheus-01.monitor.local | AlmaLinux 9.6 | x86_64 | 192.168.111.197 | Prometheus 3.x |
时间设置
设置时区
timedatectl set-timezone Asia/Shanghai
设置主机名
hostnamectl set-hostname prometheus-01.monitor.local
防火墙及 SELinux
安装后配置
内核模块设置(Docker 需要)
加载 br_netfilter
模块
modprobe br_netfilter
echo 'br_netfilter' > /etc/modules-load.d/br_netfilter.conf
系统参数
资源限制
PAM 模块
PAM 模块 pam_limits 对用户会话中可以获得的系统资源设置了限制,可以使用 ulimit 命令进行修改,或者直接将修改的值写入配置文件 /etc/security/limits.conf
和 /etc/security/limits.d/*.conf
# 备份原有的设置
find /etc/security/limits.d -type f -name *.conf -exec mv {} {}.bak.`date +"%Y%m%d"` \;
# 设置限制
cat > /etc/security/limits.d/sys.conf <<EOF
* - core unlimited
* - nproc unlimited
* - nofile 1048576
* - memlock unlimited
* - msgqueue unlimited
* - stack unlimited
EOF
systemd
systemd 有独立于 PAM 的资源限制(setrlimit
),若服务通过 systemd 启动也需要设置
###### 修改用户级默认配置 ######
# 备份原有的文件或创建目录
[ -f /etc/systemd/user.conf.d/ ] && find /etc/systemd/user.conf.d/ -type f -name *.conf -exec mv {} {}.bak.`date +"%Y%m%d"` \; || mkdir -p /etc/systemd/user.conf.d
# 修改配置
cat > /etc/systemd/user.conf.d/sys.conf << EOF
[Manager]
DefaultLimitCORE=infinity
DefaultLimitNPROC=infinity
DefaultLimitNOFILE=1048576
DefaultLimitMEMLOCK=infinity
DefaultLimitMSGQUEUE=infinity
EOF
###### 修改系统级默认配置 ######
# 备份原有的配置
cp /etc/systemd/system.conf /etc/systemd/system.conf.bak`date +"%Y%m%d"`
# 修改配置
grep -q '^#* *DefaultLimitCORE.*' /etc/systemd/system.conf && sed -ri 's@^#* *(DefaultLimitCORE).*@\1=infinity@' /etc/systemd/system.conf || echo "DefaultLimitCORE=infinity" >> /etc/systemd/system.conf
grep -q '^#* *DefaultLimitNPROC.*' /etc/systemd/system.conf && sed -ri 's@^#* *(DefaultLimitNPROC).*@\1=infinity@' /etc/systemd/system.conf || echo "DefaultLimitNPROC=infinity" >> /etc/systemd/system.conf
grep -q '^#* *DefaultLimitNOFILE.*' /etc/systemd/system.conf && sed -ri 's@^#* *(DefaultLimitNOFILE).*@\1=1048576@' /etc/systemd/system.conf || echo "DefaultLimitNOFILE=1048576" >> /etc/systemd/system.conf
grep -q '^#* *DefaultLimitMEMLOCK.*' /etc/systemd/system.conf && sed -ri 's@^#* *(DefaultLimitMEMLOCK).*@\1=infinity@' /etc/systemd/system.conf || echo "DefaultLimitMEMLOCK=infinity" >> /etc/systemd/system.conf
grep -q '^#* *DefaultLimitMSGQUEUE.*' /etc/systemd/system.conf && sed -ri 's@^#* *(DefaultLimitMSGQUEUE).*@\1=infinity@' /etc/systemd/system.conf || echo "DefaultLimitMSGQUEUE=infinity" >> /etc/systemd/system.conf
# 重启 systemd 生效
systemctl daemon-reexec
内核参数
cat >/etc/sysctl.d/99-sysctl.conf <<EOF
###### MTU 相关设置 ######
# 仅在路径 MTU 不可达时启用 TCP 层 MTU 探测
net.ipv4.tcp_mtu_probing = 1
# 启用 IP 层 MTU 探测 Path MTU Discovery (PMTUD)
net.ipv4.ip_no_pmtu_disc = 0
###### TCP 连接快速释放设置 ######
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
###### TIME_WAIT 过多时设置 ######
net.ipv4.tcp_tw_reuse = 1
#net.ipv4.tcp_tw_recycle = 0
# 限制 TIME_WAIT 最大值,默认 8192
net.ipv4.tcp_max_tw_buckets=5000
###### 端口相关设置 ######
# 设定允许系统主动打开的端口范围,根据需要设置,默认 32768 60999
net.ipv4.ip_local_port_range = 32768 65530
###### 防 SYNC 攻击设置 ######
net.ipv4.tcp_syncookies=1
net.ipv4.tcp_syn_retries=3
net.ipv4.tcp_synack_retries=2
net.ipv4.tcp_max_syn_backlog=8192
# 配置 TCP 重传的最大次数减少到 5 次,超时时间约为 6 秒,方便及时发现节点故障
# net.ipv4.tcp_retries2=5
###### 其他 TCP 设置 ######
# 系统当前因后台进程无法处理的新连接而溢出,则允许系统重置新连接
net.ipv4.tcp_abort_on_overflow=1
####### nf_conntrack 相关设置(k8s、docker 防火墙的 nat) #######
net.netfilter.nf_conntrack_max = 262144
net.nf_conntrack_max = 262144
net.netfilter.nf_conntrack_tcp_timeout_established = 86400
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 3600
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
####### socket 相关设置 ######
net.core.somaxconn = 32768
net.core.netdev_max_backlog = 32768
###### 其他设置 #######
net.ipv4.conf.default.rp_filter=0
net.ipv4.conf.default.accept_source_route=0
net.ipv4.ip_forward = 1
net.ipv4.ip_nonlocal_bind = 1
#
net.ipv4.conf.all.forwarding=1
net.ipv6.conf.all.forwarding=1
###### 内存相关设置 #######
vm.swappiness = 0
vm.max_map_count = 655360
vm.overcommit_memory = 0
# vm.min_free_kbytes = 1048576
###### 文件相关 #######
fs.file-max = 9223372036854775807
fs.nr_open = 1073741816
fs.aio-max-nr = 1048576
####### K8S 相关设置 ######
# 必须先加载 br_netfilter 模块
# 二层的网桥在转发包时也会被 arptables/ip6tables/iptables 的 FORWARD 规则所过滤
net.bridge.bridge-nf-call-arptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
###### 进程相关 #######
# 最大进程 id,默认值为 32768,最大值根据发行版有所不同
kernel.pid_max = 132768
kernel.threads-max = 123342
EOF
sysctl --system
安装
参考 - 1:First steps | Prometheus
参考 - 2:Getting started | Prometheus
参考 - 3:Installation | Prometheus
二进制方式
部署
基础变量设置
PROMETHEUS_VERSION=3.4.1
PROMETHEUS_OS=linux
PROMETHEUS_ARCH=amd64
PROMETHEUS_HOME=/opt/prometheus
PROMETHEUS_CONF=/etc/prometheus
PROMETHEUS_DATA=/data/prometheus
PROMETHEUS_USER=prometheus
PROMETHEUS_USER_GROUP=prometheus
# 创建目录
mkdir -p ${PROMETHEUS_HOME}/bin
mkdir -p ${PROMETHEUS_CONF}/{rules,files_sd}
mkdir -p ${PROMETHEUS_DATA}
# 创建用户和组
groupadd --system ${PROMETHEUS_USER_GROUP}
useradd -s /sbin/nologin --system -g ${PROMETHEUS_USER_GROUP} ${PROMETHEUS_USER}
下载解压
# 下载
curl -x http://192.168.111.1:10811 \
-o /usr/local/src/prometheus-${PROMETHEUS_VERSION}.${PROMETHEUS_OS}-${PROMETHEUS_ARCH}.tar.gz \
-L https://github.com/prometheus/prometheus/releases/download/v${PROMETHEUS_VERSION}/prometheus-${PROMETHEUS_VERSION}.${PROMETHEUS_OS}-${PROMETHEUS_ARCH}.tar.gz
# 解压
tar -xf /usr/local/src/prometheus-${PROMETHEUS_VERSION}.${PROMETHEUS_OS}-${PROMETHEUS_ARCH}.tar.gz \
-C /usr/local/src/
# 复制到对应目录
\cp /usr/local/src/prometheus-${PROMETHEUS_VERSION}.${PROMETHEUS_OS}-${PROMETHEUS_ARCH}/{prometheus,promtool} ${PROMETHEUS_HOME}/bin
\cp /usr/local/src/prometheus-${PROMETHEUS_VERSION}.${PROMETHEUS_OS}-${PROMETHEUS_ARCH}/prometheus.yml ${PROMETHEUS_CONF}
授权
chown -R ${PROMETHEUS_USER}:${PROMETHEUS_USER_GROUP} ${PROMETHEUS_HOME}
chown -R ${PROMETHEUS_USER}:${PROMETHEUS_USER_GROUP} ${PROMETHEUS_CONF}
chown -R ${PROMETHEUS_USER}:${PROMETHEUS_USER_GROUP} ${PROMETHEUS_DATA}
配置
配置程序
默认配置,未修改
$ vim ${PROMETHEUS_CONF}/prometheus.yml
# my global config
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
# scrape_timeout is set to the global default (10s).
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093
# Load rules once and periodically evaluate them according to the global 'evaluation_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"]
配置环境变量
cat > /etc/profile.d/prometheus.sh << EOF
export PROMETHEUS_HOME=${PROMETHEUS_HOME}
export PROMETHEUS_CONF=${PROMETHEUS_CONF}
export PROMETHEUS_DATA=${PROMETHEUS_DATA}
export PROMETHEUS_USER=${PROMETHEUS_USER}
export PROMETHEUS_USER_GROUP=${PROMETHEUS_USER_GROUP}
export PATH=\${PATH}:\${PROMETHEUS_HOME}/bin
EOF
source /etc/profile
配置 systemd 管理
cat > /usr/lib/systemd/system/prometheus.service << EOF
[Unit]
Description=Prometheus Server
Documentation=https://prometheus.io/docs/introduction/overview/
After=network.target
[Service]
User=${PROMETHEUS_USER}
Group=${PROMETHEUS_USER_GROUP}
Type=simple
ExecStart=${PROMETHEUS_HOME}/bin/prometheus \
--config.file=${PROMETHEUS_CONF}/prometheus.yml \
--storage.tsdb.path=${PROMETHEUS_DATA} \
--web.listen-address=0.0.0.0:9090 \
--web.enable-lifecycle \
--log.level=info
Restart=on-failure
RestartSec=5s
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
配置 firewalld 和 SELinux
# 临时禁止 SELinux
setenforce 0
# 永久禁止 SELinux
sed -ri 's/^(SELINUX).*/\1=disabled/g' /etc/selinux/config && sed -ri 's/^SELINUX(.*)/\1=disabled/g' /etc/sysconfig/selinux
firewall-cmd --permanent --zone=public --add-service=prometheus
firewall-cmd --reload
启动
测试启动
sudo -u ${PROMETHEUS_USER} \
${PROMETHEUS_HOME}/bin/prometheus \
--config.file=${PROMETHEUS_CONF}/prometheus.yml \
--storage.tsdb.path=${PROMETHEUS_DATA} \
--web.listen-address=0.0.0.0:9090 \
--web.enable-lifecycle \
--log.level=info
启动并设置开机启动
systemctl enable --now prometheus
测试
浏览器访问:http://192.168.111.197:9090/query
Docker 方式
dockerhub 地址:prom/prometheus - Docker Image
基础变量设置
PROMETHEUS_VERSION=v3.4.1
PROMETHEUS_CONF=/etc/prometheus
PROMETHEUS_DATA=/data/prometheus
# 创建目录
mkdir -p ${PROMETHEUS_CONF}/{rules,files_sd}
mkdir -p ${PROMETHEUS_DATA}
# 注:如果不想用 root 用户启动容器,需要将数据目录权限给到 nobody
chown -R nobody:nobody ${PROMETHEUS_DATA}
# 配置环境变量
cat > /etc/profile.d/prometheus.sh << EOF
export PROMETHEUS_VERSION=${PROMETHEUS_VERSION}
export PROMETHEUS_CONF=${PROMETHEUS_CONF}
export PROMETHEUS_DATA=${PROMETHEUS_DATA}
EOF
source /etc/profile
复制配置文件
docker run -d --name tmp_prometheus prom/prometheus:${PROMETHEUS_VERSION}
# 默认镜像中只有一个配置文件
docker cp tmp_prometheus:/etc/prometheus/prometheus.yml ${PROMETHEUS_CONF}/prometheus.yml
docker rm -f tmp_prometheus
修改配置
vim ${PROMETHEUS_CONF}/prometheus.yml
启动
$ docker run -d --name=prometheus --restart=always \
-p 9090:9090 \
-v ${PROMETHEUS_CONF}:/etc/prometheus \
-v ${PROMETHEUS_DATA}:/prometheus \
--restart=always \
--cpus 0.5 \
--memory 500M \
prom/prometheus:${PROMETHEUS_VERSION} \
--config.file=/etc/prometheus/prometheus.yml \
--storage.tsdb.path=/prometheus \
--web.listen-address=0.0.0.0:9090 \
--web.enable-lifecycle \
--log.level=info
防火墙设置
停止 Docker
systemctl stop docker
重建 iptables 的 DOCKER-USER 链
firewall-cmd --permanent --direct --remove-chain ipv4 filter DOCKER-USER
firewall-cmd --permanent --direct --remove-rules ipv4 filter DOCKER-USER
firewall-cmd --permanent --direct --add-chain ipv4 filter DOCKER-USER
添加 iptables 规则
# 序号越小,优先级越高
# 允许已建立的连接(ESTABLISHED/RELATED),优先级 1
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 1 \
-m conntrack \
--ctstate RELATED,ESTABLISHED -j RETURN \
-m comment --comment 'Allow pre-existing connections (do not break active streams)'
# 允许容器相互访问,优先级 1
# 172.17.0.0/16 为 Docker 容器的 CIDR
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 1 \
-j RETURN \
-s 172.17.0.0/16 \
-m comment --comment 'allow docker-container internal communication'
# 默认拒绝所有其他流量,优先级 999
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 999 \
-j REJECT -m comment --comment 'reject all other traffic to DOCKER-USER'
允许某端口暴露
注:永久配置需要加
--permanent
选项
注:此处的 80 端口应该是容器侧的端口,例如 8080 端口映射到容器 80 端口,此处应该写 80 端口(-p 8080:80)。原因:
iptables
的PREROUTING
链的nat
表在filter
表之前,nat
表已经完成了 DNAT 转换。查看nat
表:iptables -nvL -t nat
# 暴露给指定 IP
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 2 \
-p tcp -m multiport --dports 9090 \
-s 192.168.111.1/32 -j RETURN
# 暴露给指定网段
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 2 \
-p tcp -m multiport --dports 9090 \
-s 172.17.0.0/16 -j RETURN
加载永久配置
firewall-cmd --reload
启动 Docker
systemctl enable --now docker
测试
浏览器访问:http://192.168.111.197:9090/query
附录
FAQ
参考:Prometheus --- FAQ | Prometheus
管理 API
健康检查
GET /-/healthy
HEAD /-/healthy
此端点始终返回 200,并应用于检查 Prometheus 的健康状态
就绪检查
GET /-/ready
HEAD /-/ready
当 Prometheus 准备服务流量(即响应查询)时,此端点返回 200
重新加载
POST /-/reload
此端点触发 Prometheus 配置文件的重新加载。默认情况下被禁用,可以通过 --web.enable-lifecycle
标志启用。或者,可以通过向 Prometheus 进程发送 SIGHUP
来触发配置重新加载