ezra-sullivan
发布于 2025-06-19 / 0 阅读
0
0

01 - Prometheus 简介与常规部署

更新时间:2025 年 6 月

版本:Prometheus 3.4.x

官网:Prometheus

官方文档:Overview | 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_counthttp_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 实例聚合数据,支持分层监控架构。

架构

01-architecture

Prometheus 从已配置的作业中抓取指标,无论是直接还是通过中间推送网关为短期作业。它将所有抓取的样本本地存储,并在此数据上运行规则,以从现有数据中聚合和记录新的时间序列或生成警报。可以使用 Grafana 或其他 API 消费者来可视化收集到的数据

注意事项

  • Prometheus 在采集和存储数据时,一律使用 UTC 时间无论宿主机是东八区还是其他时区。这不会影响数据采集和准确性
  • Prometheus Web UI 显示时间是 UTC,但可以设置显示本地时间

安装主机准备

主机准备

主机名操作系统架构IP安装软件
prometheus-01.monitor.localAlmaLinux 9.6x86_64192.168.111.197Prometheus 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}

配置

配置程序

参考:Configuration | Prometheus

默认配置,未修改

$ 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)。原因:iptablesPREROUTING 链的 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

参考:Management API | Prometheus

健康检查

GET /-/healthy
HEAD /-/healthy

此端点始终返回 200,并应用于检查 Prometheus 的健康状态

就绪检查

GET /-/ready
HEAD /-/ready

当 Prometheus 准备服务流量(即响应查询)时,此端点返回 200

重新加载

POST /-/reload

此端点触发 Prometheus 配置文件的重新加载。默认情况下被禁用,可以通过 --web.enable-lifecycle 标志启用。或者,可以通过向 Prometheus 进程发送 SIGHUP 来触发配置重新加载


评论