Prometheus接入Pushgateway实战:二进制与Docker部署、指标推送及远程上报

前言

Prometheus 默认采用 Pull 模型:它按采集周期访问目标的 /metrics 端点。这对 Web 服务、数据库等长期运行的进程非常合适,但在批处理监控中会碰到时间差。备份脚本执行完就退出,CI/CD 作业可能只运行几分钟;假如进程在两次抓取之间启动又结束,Prometheus 就未必能采到这次任务的执行结果。

Pushgateway 提供了一个中间指标入口。批量任务通过 HTTP 将成功状态、执行耗时、处理记录数等指标推送过去,Pushgateway 按分组键保存这些指标,Prometheus 再定期从它的 /metrics 端点拉取。需要注意,这并不是把 Prometheus 改成 Push 系统:Pushgateway 既不是日志库,也不会替你判断任务是不是按时执行,更不会自动清理已经停止的任务分组。实际应用时,要一并设计指标分组、过期判断和访问权限。

本篇沿用原始实验路线,在 Linux 虚拟机上分别演示二进制安装和 Docker 安装,配置 Prometheus 抓取目标,利用 curl、Shell 和 Python 完成不同任务的指标上报,再借助 cpolar 配置可从外部访问的地址。部署步骤、原有命令及截图均保留,并对版本记录、指标持久化、返回码判断和远程写入安全作必要说明,便于按图复现,也能知道哪些地方需要进一步完善后才能用于生产环境。

1. 为什么短任务需要 Pushgateway:环境与工作方式

Prometheus 通过周期性抓取获取监控数据,前提是采集时目标仍然能够提供指标。对于长期运行的服务,这种方式直观;但备份、流水线和临时数据处理作业通常执行完成就退出,下一次抓取未必来得及。Pushgateway 允许这些任务先把指标推送给一个持续运行的中间组件,然后由 Prometheus 照常采集它。这里的"离线任务"指不常驻、短生命周期的作业,并不是指任务在完全没有网络连接时也能实时上报。

本篇按原文的虚拟机环境演示,保留原始版本记录:

  • 虚拟机:Oracle VirtualBox 5.1.20 r114628(Qt 5.6.2)。
  • 系统:原文记录为 entOS Linux release 7.9.2009 (Core),应是 CentOS 7.9.2009 的笔误。
  • Docker:26.1.4。
  • Prometheus:v3.5.0。
  • Pushgateway:环境清单写的是 1.0.0,但下方下载与解压命令使用的是 1.11.2;复现时以实际下载和运行的版本为准。

演示开始前需有可运行的 Prometheus。若尚未安装,可先参考原文提及的《监控不再局域网!Cpolar 让 Prometheus 走出内网限制!》完成基础环境。Pushgateway 适用于特定批处理任务,并不建议直接拿来替代一般服务的常规采集。

2. 安装 Pushgateway:二进制与 Docker 两种路线

两种安装方式任选其一即可。若都在同一台机器上启动,默认都会占用 9091 端口,应避免端口冲突。这里先保留原文的 systemd 部署方式,再介绍容器版本。

2.1 二进制安装及 systemd 托管

首先到项目发布页面选择对应平台的 Linux 二进制包,原文采用 pushgateway-1.11.2.linux-amd64.tar.gz。下载后将压缩包上传至 /app 目录。

上传完成:

在 /app 下执行解压命令:

shell 复制代码
tar -zxvf pushgateway-1.11.2.linux-amd64.tar.gz

随后按原文将解压出的目录更名为 pushgateway,并删除已经用完的安装包。请确认压缩包已成功解压,再执行删除操作。

shell 复制代码
mv pushgateway-1.11.2.linux-amd64 pushgateway
rm -rf pushgateway-1.11.2.linux-amd64.tar.gz

要让 Pushgateway 随系统启动,可以创建 systemd 服务文件:

shell 复制代码
sudo vim /etc/systemd/system/pushgateway.service

写入以下服务配置,保持原文参数不变:

shell 复制代码
[Unit]
Description=Pushgateway for Prometheus
Documentation=https://github.com/prometheus/pushgateway
After=network-online.target

[Service]
Type=simple
User=prometheus
Group=prometheus
ExecStart=/app/pushgateway/pushgateway \
  --web.listen-address=:9091 \
  --web.enable-admin-api \
  --log.level=info
WorkingDirectory=/app/pushgateway
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=pushgateway

[Install]
WantedBy=multi-user.target

其中 ExecStart 指向 /app/pushgateway/pushgateway,监听端口是 9091;Restart=on-failure 用于异常退出后重启。服务指定了 User=prometheus 和 Group=prometheus,因此需要事先确认该账号及用户组存在,并能访问运行目录。配置中的 --web.enable-admin-api 还会开启全量清空指标的管理接口:仅演示时也应限制谁可以访问该端口,实际部署如不需要这个接口就不要启用。

然后设置目录归属和程序执行权限:

shell 复制代码
sudo chown -R prometheus:prometheus /app/pushgateway
sudo chmod +x /app/pushgateway/pushgateway

重载服务配置,启动并设置开机自启,最后检查状态:

shell 复制代码
# 重载配置
sudo systemctl daemon-reexec
sudo systemctl daemon-reload

# 启动并设置开机自启
sudo systemctl start pushgateway
sudo systemctl enable pushgateway

# 查看状态
sudo systemctl status pushgateway

服务启动不等于链路全部可用。继续检查进程、访问本机指标端点,并跟踪日志:

shell 复制代码
# 检查进程
ps aux | grep pushgateway

# 访问指标端点(本地)
curl http://localhost:9091/metrics

# 查看日志
journalctl -u pushgateway -f

如果需要从别的机器访问 9091,原文还给出 CentOS 7 的防火墙放行操作:

shell 复制代码
# CentOS 7 使用 firewalld
sudo firewall-cmd --permanent --add-port=9091/tcp
sudo firewall-cmd --reload

这里的放行应仅针对可信来源;它不是让 Pushgateway 可以直接暴露给所有互联网用户的建议。特别是启用了管理 API 的实例,更需要限制写入和管理权限。

浏览器输入 http://服务器IP:9091,可以打开 Web 页面。此时还没有任务主动上报,所以页面中不会出现自定义任务组。

访问 http://服务器IP:9091/metrics 时仍能看到 go_、process_ 等自身运行指标。这说明服务本身可以提供采集端点,不代表备份或批处理指标已经进来了。

还有一项要单独说明:原文这份 systemd 配置未启用 --persistence.file,因此不能声称已经完成指标磁盘持久化。 Pushgateway 默认不会把推送数据持久保存到磁盘;若需要重启后保留已推送的指标,应按官方文档配置持久化文件并安排相应的文件权限与备份。

2.2 使用 Docker 安装

已经有 Docker 环境的读者,可以直接拉取官方镜像:

shell 复制代码
docker pull prom/pushgateway

随后按照原文运行容器,将宿主机 9091 映射至容器 9091:

shell 复制代码
docker run -d \
  --name=pg \
  -p 9091:9091 \
  prom/pushgateway

完成后,用浏览器访问示例地址:

shell 复制代码
http://ip:9091/

实际使用时要把示例中的 ip 替换为服务器地址。原命令没有配置数据持久化参数或重启策略,不要将它误解为已经具备故障恢复后的指标保留能力。如果选择容器路线,下面 Prometheus 的抓取地址也要按容器和 Prometheus 的真实网络拓扑填写。

3. 让 Prometheus 定期采集 Pushgateway

Pushgateway 接收了任务指标,还需要 Prometheus 把它纳入采集目标。先找到并编辑原文的 Prometheus 配置文件:

shell 复制代码
vi /app/prometheus/prometheus.yml

原文展示的新增目标片段如下:

shell 复制代码
      - targets: ['localhost:9091']
        labels:
          app: "pushgateway"

注意:这只是目标片段,不是一份可以独立运行的完整 prometheus.yml。 应将其放进适当的 scrape_configs / static_configs 结构,并沿用已有配置的缩进。Pushgateway 官方还建议在对应抓取任务中设置 honor_labels: true,以保留被推送指标的 job、instance 等标签,而不是让采集端的标签覆盖原有分组信息。localhost:9091 也仅适用于 Prometheus 与 Pushgateway 共享同一网络命名空间并能从该地址连通的情况;分属不同容器或主机时,需改为可达的实际地址。

改完后按照原文重启 Prometheus 并查看状态:

shell 复制代码
systemctl restart prometheus
systemctl status prometheus

再打开 http://服务器IP:9090,在目标列表中确认 Pushgateway 对应的采集目标正常;也可以查询 Pushgateway 自身指标检查连通性。

要区分两个验证层次:目标显示正常表示 Prometheus 成功抓到了 Pushgateway;是否存在任务指标,还得等后续真的推送数据并查询对应名称。

4. 把自定义指标推送到 Pushgateway

Pushgateway 的写入地址以 /metrics/job/任务名 开始,后面可按分组需要继续追加 instance 等标签。URL 中这组标签构成分组键,同一任务不同分组的数据可以分开管理。下面先用一条简单数值完成端到端测试,再演示更复杂的数据与删除操作。

4.1 发送第一条测试指标

使用原文的 echo 和 curl 命令,将 test_metric 提交到 test_job 分组:

shell 复制代码
echo "test_metric 123456" | curl --data-binary @- http://192.168.42.140:9091/metrics/job/test_job

返回 Pushgateway 页面后,就能查看新增的任务分组。Pushgateway 还会为每个已推送分组暴露 push_time_seconds、push_failure_time_seconds 等指标,用于观察最近成功或失败的推送时间。

随后在 Prometheus 的表达式查询页面查找 test_metric,确认抓取后能读到样本。

4.2 上报带标签的多条指标

下面这段原始示例将两条不同类型的指标写入 some_job / some_instance 分组:

shell 复制代码
cat <<EOF | curl --data-binary @- http://192.168.42.140:9091/metrics/job/some_job/instance/some_instance
# TYPE some_metric counter
some_metric{label="val1"} 42
# TYPE another_metric gauge
# HELP another_metric Just an example.
another_metric 2398.283
EOF

# TYPE 和 # HELP 用于描述指标类型、含义;instance 是分组标签的一部分。推送前应确保同名指标的类型与标签结构不冲突。原文使用 curl --data-binary,其 HTTP POST 会在对应分组内按指标名称更新数据;如果需要整体替换某个分组的数据,则应按官方 API 语义选择 PUT。

4.3 清理不再需要的分组

临时任务结束后,Pushgateway 不会自动忘记以前收到的指标。如果组被废弃、实例改名,或不再希望 Prometheus 继续读取旧结果,就需要有明确的清理规则。

删除指定 job、instance 组合的全部指标:

复制代码
curl -X DELETE http://192.168.42.140:9091/metrics/job/some_job/instance/some_instance

仅删除 some_job 这个分组:

复制代码
curl -X DELETE http://192.168.42.140:9091/metrics/job/some_job

请特别注意:第二条命令针对的是只有 job=some_job 的那个分组,不会连带清除带 instance=some_instance 的另一个分组。DELETE 只对 URL 指定的完整分组键生效,不能当作模糊匹配的批量清理。

5. 两个批处理场景:Shell 备份与 Python 数据任务

测试指标能进来之后,再把相同方式嵌入短任务。这里保留原文的两段脚本及截图,便于照着复现;它们都是模拟演示,不能把示例中写死的成功状态和记录数当成真实业务结果。

5.1 Shell:汇报备份耗时和结果

示例先记录开始时间,使用 sleep 3 模拟备份过程,然后上报耗时和成功状态。原始脚本如下:

shell 复制代码
#!/bin/bash

JOB_NAME="daily_backup"
INSTANCE="server01"
PUSHGATEWAY_URL="http://localhost:9091"

start_time=$(date +%s)

# 模拟备份操作
echo "Starting backup..."
sleep 3
backup_success=1  # 1 表示成功,0 表示失败(实际可由命令返回值决定)

end_time=$(date +%s)
duration=$((end_time - start_time))

# 构建指标
cat <<EOF | curl --data-binary @- http://localhost:9091/metrics/job/$JOB_NAME/instance/$INSTANCE
# HELP backup_duration_seconds Duration of the backup job in seconds
# TYPE backup_duration_seconds gauge
backup_duration_seconds $duration

# HELP backup_success Whether the backup succeeded (1) or failed (0)
# TYPE backup_success gauge
backup_success $backup_success
EOF

echo "Metrics pushed to Pushgateway."

执行后,打开 Pushgateway 查看这次上报的分组:

在 Prometheus 中查询时,示例指标表现为:

shell 复制代码
backup_duration_seconds{job="daily_backup", instance="server01"} 3
backup_success{job="daily_backup", instance="server01"} 1

这两个指标分别回答"用了多少秒"和"是否成功"。在真正的备份脚本中,需要根据备份命令实际退出码设置 backup_success,不能固定写 1;同时应检查指标提交是否成功。原始脚本虽然定义了 PUSHGATEWAY_URL 变量,实际请求仍直接写了 localhost:9091,迁移到其他机器时也要同步检查请求目标。

5.2 Python:汇报处理量与执行状态

对于一次性 Python 数据任务,也可以把最后的处理结果转换为 Prometheus 文本格式,通过 HTTP 提交。原文脚本使用 requests,模拟处理 1500 条记录:

shell 复制代码
import requests
import time

def push_metrics(job, instance, records_processed, success):
    metrics = f"""
    # HELP data_records_processed Number of records processed
    # TYPE data_records_processed gauge
    data_records_processed {records_processed}

    # HELP data_job_success Job success status (1 = success, 0 = failure)
    # TYPE data_job_success gauge
    data_job_success {int(success)}
    """
    url = f"http://localhost:9091/metrics/job/{job}/instance/{instance}"
    response = requests.post(url, data=metrics.encode('utf-8'))
    if response.status_code == 202:
        print("Metrics pushed successfully.")
    else:
        print(f"Failed to push metrics: {response.status_code}")

# 模拟任务
start = time.time()
try:
    # 模拟处理 1500 条数据
    records = 1500
    time.sleep(2)
    success = True
except Exception as e:
    records = 0
    success = False

push_metrics(
    job="data_pipeline",
    instance="worker-node-01",
    records_processed=records,
    success=success
)

在准备好 Python 和 requests 依赖后,按原文方式执行文件:

shell 复制代码
python3 1.py

访问 Pushgateway,查看是否收到 data_pipeline 任务数据:

Prometheus 中预期出现的示例指标如下:

shell 复制代码
data_records_processed{job="data_pipeline", instance="worker-node-01"} 1500
data_job_success{job="data_pipeline", instance="worker-node-01"} 1

正式使用时,records 应来自实际处理结果,success 应由真实异常处理或退出状态得出。还要注意,原脚本只把 HTTP 202 判断为"推送成功";按官方 API,正常 POST/PUT 还可能返回 200,因此不能仅靠 status_code == 202 判定。应检查所有合适的成功状态,并为网络异常、超时和失败响应设置处理逻辑。

指标被保留不代表任务仍在运行。对每天一次的任务,最好结合 push_time_seconds 判断最近一次上报是否过期,再配合状态指标判断执行结果。

6. 通过 cpolar 为远程任务建立访问通道

到这里,本地任务已经能够将指标交给 Pushgateway,Prometheus 也能正常采集。如果备份脚本在另一台云服务器、远程 CI/CD 节点或其他网络中执行,而 Pushgateway 只部署在内网,就还需要解决网络连通问题。

cpolar 的作用是将本地运行的 HTTP 服务映射为可从外部访问的地址,不会改变 Pushgateway 的采集与存储方式。需要特别提醒的是:这次对外映射的是可写入指标的服务,不只是一个只读看板。Prometheus 官方指出,能访问 Pushgateway HTTP 端点的用户可以创建、修改和删除指标;因此应只允许可信任务上报,并做好认证、访问限制与监控。

6.1 安装 cpolar

在运行 Pushgateway 的 Linux 主机上执行原文安装命令:

shell 复制代码
sudo curl https://get.cpolar.sh | sh

安装完成后检查服务是否启动:

shell 复制代码
sudo systemctl status cpolar

随后在浏览器访问这台服务器的局域网 IP 加 9200 端口,使用 cpolar 账号登录 Web 管理界面。若是在同一台主机上操作,也可以使用本机地址;不要把示例中的 localhost 直接照搬到别的电脑浏览器中。

7. 创建用于 Pushgateway 的公网隧道

登录 cpolar Web UI,依次进入隧道管理 → 创建隧道。沿用原文截图中的参数:

  • 隧道名称:pushgateway(或另一个不重复的名称)。
  • 协议:http。
  • 本地地址:9091。
  • 域名类型:随机域名。
  • 地区:China Top。

创建后进入状态 → 在线隧道列表,查看系统提供的公网地址。

使用异地网络验证页面是否可达:

这一步验证的是隧道和 Web 服务连通,不应直接视为远程推送全链路已经验证成功。对外部任务,还应在获得授权的前提下用实际 HTTPS 写入地址提交测试指标,再在 Pushgateway 和 Prometheus 中分别确认收到与采集。

由于写入端点没有天然的只读隔离,公网访问应当设置认证或其他访问限制,不宜只依赖随机网址难以猜到。原始二进制服务又开启了管理 API,尤其不要把管理权限直接向不受信任的网络开放。

8. 固定二级子域名:减少远程任务频繁改地址

临时测试可用随机域名;需要多个远程脚本长期上报时,固定地址更容易维护。原文使用 cpolar 的二级子域名保留功能,具体以账号当前可用权益为准。

先登录 cpolar 控制台,进入预留 → 保留二级子域名 ,按原文选择 China Top,自定义名称为 pushgateway(如已被占用则换一个),填写备注并保留。

再返回本地 cpolar 管理界面,打开隧道管理 → 隧道列表,找到对应隧道并点击编辑。

将域名类型切换为二级子域名 ,在 Sub Domain 中填写刚刚保留成功的名称,地区仍保持一致,然后更新。

更新后在在线隧道列表确认地址变化:

最后用固定的 HTTPS 地址再次测试页面可达性,并验证授权后的指标提交是否正常:

固定域名解决的是访问地址变化问题,并不是对服务的安全加固。对生产环境来说,认证、权限限制、任务分组清理和数据保留策略,仍然需要单独落实。

总结

Pushgateway 的价值在于为短生命周期的批量任务保留一次执行结果,补上 Prometheus 定时抓取与任务短暂运行之间的时间差。本文分别完成了二进制与 Docker 部署、Prometheus 采集目标配置、curl 推送与删除,以及 Shell 备份和 Python 数据处理两个示例;最后通过 cpolar 演示跨网络访问和固定地址的配置。

真正落地时,最容易遗漏的不是安装命令,而是指标的生命周期:任务上报后,Pushgateway 不会替你自动判断结果是否过期,也不会在任务退出时清掉历史分组。应根据业务周期观察最近推送时间、检查执行状态,清理无效分组,并按需要启用数据持久化。若允许外部写入,则必须控制访问权限,不能把公网 URL 当作安全措施。

做到这些,监控系统才不只是"看见了一条新指标",而是能持续回答一次备份、一次构建或一次数据处理究竟完成得怎样。

相关推荐
databook1 小时前
手把手带你走一遍:机器学习模型如何用FastAPI和Docker部署
python·docker·fastapi
江湖有缘2 小时前
3款开源日记工具整理合集,可Docker一键部署!
docker·容器·开源
穷人小水滴14 小时前
用容器编译 VirtualBox 虚拟机软件 (ArchLinux, podman)
linux·容器·virtualbox
EatFans14 小时前
Docker 实战部署:从本地镜像到云服务器,一篇走通 FastAPI + Celery + MySQL + Redis + Nginx
docker·fastapi
judezh15 小时前
api 容器一直 unhealthy?我把一个 Agent 运行时的健康检查逐条拆了,查出四个问题
运维·docker
暗不需求15 小时前
Docker 入门:从「光盘与 DVD」到全栈项目容器化实战
docker·容器·面试
探索云原生15 小时前
一个 Deployment 就能跑 vLLM,为什么还需要 KServe?
docker·ai·云原生·kubernetes·go
虎头金猫6 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
分布式存储与RustFS6 天前
MinIO 官方 Docker 镜像被移除:依赖它的项目该怎么办
docker·云原生·devops·对象存储·minio·分布式存储