生产部署
使用 systemd、Docker 或 Kubernetes 运行 pg_exporter 并接入 Prometheus
先安装软件包 、创建监控角色,再选择下文的 systemd、Docker 或 Kubernetes 部署方式。启动后检查 /metrics,并将 exporter 接入 Prometheus。
命令参考 列出参数、环境变量、默认值与优先级。命令行设置优先于对应的环境变量;日志、动作与 exporter-toolkit Web 参数只提供命令行形式。采集 SQL 与指标定义使用 YAML 配置 。
进程设置
以下前台运行示例通过 .pgpass 提供数据库密码:
pg_exporter \
--url= 'postgres://monitor@localhost:5432/postgres' \
--config= /etc/pg_exporter.yml \
--web.listen-address= :9630 \
--log.level= info
自动发现默认启用。启动时数据库不可用,exporter 仍会启动 HTTP 服务并在后台重试。设置 --fail-fast 后,初次数据库检查失败会使进程退出。
连接 URL 的来源
使用 --url 或 PG_EXPORTER_URL 指定目标,也可通过 PG_EXPORTER_URL_FILE 读取密钥文件。完整优先级规则 见命令参考。URL 未指定 sslmode 时会使用 disable;远程 TLS 连接需显式设置该参数。
使用 URL 文件时,清除 PG_EXPORTER_URL、PGURL,并省略 --url。软件包服务还需删除 /etc/default/pg_exporter 中默认的 PG_EXPORTER_URL 行。
监控用户与凭据
创建监控用户
CREATE ROLE monitor WITH LOGIN PASSWORD 'replace-this-secret' CONNECTION LIMIT 5 ;
GRANT pg_monitor TO monitor ; -- PostgreSQL 10+
主目标连接池最多三个连接,每个额外发现的数据库最多一个。按这个总量及共用角色的 exporter 数量设置 CONNECTION LIMIT。如果角色没有目标库的 CONNECT 权限,需要逐库授权;可选视图与扩展可能需要额外授权,参见安全指南 。
使用 .pgpass 管理密码
把密码从 URL 中拿掉,交给 libpq 的 .pgpass 机制:
# 以运行 exporter 的操作系统用户身份创建
umask 077
printf '%s\n' 'localhost:5432:*:monitor:replace-this-secret' > ~/.pgpass
chmod 600 ~/.pgpass
# URL 中不再携带密码
export PG_EXPORTER_URL = 'postgres://monitor@localhost:5432/postgres'
软件包服务使用 prometheus 用户。先用 getent passwd prometheus 检查主目录,再把 .pgpass 安装到该目录。软件包新建账号的主目录为 /var/lib/prometheus,目录与文件的安装命令见安全指南 。
数据库连接 TLS
export PG_EXPORTER_URL = 'postgres://[email protected] :5432/postgres?sslmode=verify-full&sslrootcert=/etc/pg_exporter/ca.crt'
HTTP 端口侧的保护
/metrics 之外,/reload、/explain、/stat 属于管理端点:能访问该端口的任何人都可以读取配置与运行态信息、触发重载。如果 exporter 暴露在共享网络中,请通过 --web.config.file(exporter-toolkit web 配置 )启用 TLS/Basic Auth,或在防火墙/反向代理层限制来源。
Systemd 部署(RPM/DEB 包)
软件包将二进制安装到 /usr/bin/pg_exporter,采集器安装到 /etc/pg_exporter.yml,运行设置放在 /etc/default/pg_exporter。RPM 的服务单元位于 /usr/lib/systemd/system/pg_exporter.service,DEB 位于 /lib/systemd/system/pg_exporter.service:
# /usr/lib/systemd/system/pg_exporter.service
[Unit]
Description = Prometheus exporter for PostgreSQL/Pgbouncer server metrics
Documentation = https://pigsty.io/docs/pg_exporter
After = network.target
[Service]
EnvironmentFile = -/etc/default/pg_exporter
User = prometheus
ExecStart = /usr/bin/pg_exporter $PG_EXPORTER_OPTS
Restart = on-failure
[Install]
WantedBy = multi-user.target
环境文件 /etc/default/pg_exporter(包默认值):
PG_EXPORTER_URL = 'postgres://:5432/postgres?sslmode=disable'
PG_EXPORTER_CONFIG = /etc/pg_exporter.yml
PG_EXPORTER_LABEL = ""
PG_EXPORTER_TAG = ""
PG_EXPORTER_DISABLE_CACHE = false
PG_EXPORTER_AUTO_DISCOVERY = true
PG_EXPORTER_EXCLUDE_DATABASE = "template0,template1,postgres"
PG_EXPORTER_INCLUDE_DATABASE = ""
PG_EXPORTER_NAMESPACE = "pg"
PG_EXPORTER_FAIL_FAST = false
PG_EXPORTER_CONNECT_TIMEOUT = 100
PG_EXPORTER_TELEMETRY_PATH = "/metrics"
PG_EXPORTER_OPTS = '--log.level=info'
将默认 URL 改为实际监控用户与目标。有环境变量别名的设置(如 PG_EXPORTER_DISABLE_INTRO)可直接追加;只有命令行形式的参数放入 PG_EXPORTER_OPTS。软件包将环境文件和采集配置标记为配置文件,升级时保留本地修改。
启动并验证服务:
sudo systemctl enable --now pg_exporter
sudo systemctl status pg_exporter --no-pager
curl -fsS http://127.0.0.1:9630/metrics
sudo journalctl -u pg_exporter -n 50 --no-pager
确认指标中有 pg_up 1。持续查看日志可运行 sudo journalctl -u pg_exporter -f。
修改 /etc/default/pg_exporter 后执行 sudo systemctl restart pg_exporter。只修改采集器 YAML 时,可直接重载:
curl -fsS -X POST http://127.0.0.1:9630/reload
Docker 部署
将实际数据库连接 URL 写入 pg_exporter.url。此例要求数据库证书与 db.example.com 匹配,并准备 CA 文件 ca.crt:
postgres://monitor:[email protected] :5432/postgres?sslmode=verify-full&sslrootcert=/run/secrets/pg-ca.crt
限制 URL 文件权限,再将它与 CA 挂载到容器:
chmod 600 pg_exporter.url
docker run -d \
--name pg_exporter \
--restart unless-stopped \
-p 9630:9630 \
-v " $PWD /pg_exporter.url:/run/secrets/pg_exporter_url:ro" \
-v " $PWD /ca.crt:/run/secrets/pg-ca.crt:ro" \
-e PG_EXPORTER_URL_FILE = /run/secrets/pg_exporter_url \
pgsty/pg_exporter:1.5.0
Docker Compose:
services :
pg_exporter :
image : pgsty/pg_exporter:1.5.0
restart : unless-stopped
ports :
- "9630:9630"
environment :
PG_EXPORTER_URL_FILE : /run/secrets/pg_exporter_url
volumes :
- ./pg_exporter.url:/run/secrets/pg_exporter_url:ro
- ./ca.crt:/run/secrets/pg-ca.crt:ro
镜像已内置默认采集配置。需要替换时,将自定义文件只读挂载到 /etc/pg_exporter.yml。镜像基于 scratch,没有 Shell 和 CA 证书包,因此上面的 TLS 示例需要挂载 CA。
检查容器:
docker logs pg_exporter
curl -fsS http://127.0.0.1:9630/metrics
将 9630 端口发布到 Prometheus 可达的地址,并限制网络来源。如果 Prometheus 就在 Docker 宿主机上,使用 -p 127.0.0.1:9630:9630。
Kubernetes 部署
在 exporter 所在命名空间中,用上述 URL 与 CA 文件创建 Secret:
kubectl create secret generic pg-exporter-connection \
--from-file= connection-url= ./pg_exporter.url \
--from-file= pg-ca.crt= ./ca.crt
将下面的清单保存为 pg-exporter.yaml:
apiVersion : apps/v1
kind : Deployment
metadata :
name : pg-exporter
spec :
replicas : 1
selector :
matchLabels : { app : pg-exporter }
template :
metadata :
labels : { app : pg-exporter }
spec :
containers :
- name : pg-exporter
image : pgsty/pg_exporter:1.5.0
ports :
- { name : metrics, containerPort : 9630 }
env :
- name : PG_EXPORTER_URL_FILE
value : /run/secrets/connection-url
volumeMounts :
- name : connection
mountPath : /run/secrets
readOnly : true
livenessProbe :
httpGet : { path : /version, port : metrics }
initialDelaySeconds : 10
periodSeconds : 10
readinessProbe :
httpGet : { path : /version, port : metrics }
periodSeconds : 5
resources :
requests : { cpu : 100m, memory : 128Mi }
limits : { cpu : 200m, memory : 256Mi }
volumes :
- name : connection
secret :
secretName : pg-exporter-connection
---
apiVersion : v1
kind : Service
metadata :
name : pg-exporter
spec :
ports :
- { port : 9630, targetPort : metrics, name : metrics }
selector : { app : pg-exporter }
两个探针都用 /version 检查 exporter 是否能响应 HTTP。/liveness、/readiness 实际上是 /up 的别名,反映数据库健康状态。将它们用于此处,会在数据库故障时重启 exporter 或移除 Service 端点,反而失去故障期间需要的指标。
应用清单并检查部署结果:
kubectl apply -f pg-exporter.yaml
kubectl rollout status deployment/pg-exporter
kubectl logs deployment/pg-exporter
kubectl port-forward service/pg-exporter 9630:9630
保持端口转发运行,在另一个终端检查 /metrics。按实际采集负载调整资源请求与上限;若启用 HTTP 认证,探针也需要相应凭据。
自动发现
自动发现会将同一 PostgreSQL 实例中的数据库加入监控。可用包含名单限定范围:
pg_exporter --auto-discovery \
--exclude-database= "template0,template1,postgres" \
--include-database= "app,analytics"
URL 指定的数据库始终会被监控。包含/排除名单只作用于额外数据库;同一个名称同时出现在两份名单时,排除优先。包含名单为空时,允许所有其他符合条件的数据库。
集群级采集器(tags: [cluster])只在主连接上执行一次。
数据库级采集器也在发现的数据库上执行。内置采集器用 datname 标签区分结果;自定义 SQL 需自行返回声明的标签列。
每次抓取检查数据库的新增或删除。
--no-auto-discovery 将采集范围限定在 URL 指定的数据库。
监控 PgBouncer
将 URL 的数据库名设为 pgbouncer 即可切换到 PgBouncer 模式(以此触发自动检测):
PG_EXPORTER_URL = 'postgres://stats_user@localhost:6432/pgbouncer' \
pg_exporter --namespace= pgbouncer --web.listen-address= :9631
在 PgBouncer 中配置该账号的认证,并将其加入 stats_users,密码存入 .pgpass。此模式运行 PgBouncer 的 SHOW 采集器。分别为 PostgreSQL 与 PgBouncer 启动 exporter,使用不同端口。
未指定命名空间时,自监控指标默认使用 pgbouncer 前缀。软件包环境文件设置了 PG_EXPORTER_NAMESPACE=pg,部署 PgBouncer 服务时应改为 pgbouncer。该设置只影响内置自监控指标,不改变 YAML 定义的指标名。
Prometheus 抓取与告警
抓取配置
scrape_configs :
- job_name : 'postgresql'
scrape_interval : 15s
scrape_timeout : 10s
static_configs :
- targets : [ 'pg-1:9630' , 'pg-2:9630' , 'pg-3:9630' ]
Kubernetes 服务发现:
scrape_configs :
- job_name : 'postgresql'
kubernetes_sd_configs :
- role : pod
relabel_configs :
- source_labels : [ __meta_kubernetes_pod_label_app]
regex : pg-exporter
action : keep
- source_labels : [ __meta_kubernetes_pod_container_port_name]
regex : metrics
action : keep
可先使用 15 秒抓取间隔与 10 秒超时。采集结果在 ttl 到期前可以复用,内置采集器常用 10 秒 TTL。缩短间隔或增加监控库之前,先测量完整抓取的耗时。
告警规则
以下示例使用默认的 pg 自监控指标命名空间:
groups :
- name : pg_exporter
rules :
# 导出器进程失联
- alert : PgExporterDown
expr : up{job="postgresql"} == 0
for : 1m
labels : { severity : critical }
annotations :
summary : "pg_exporter 宕机 ({{ $labels.instance }})"
# 主目标连接或 fatal 采集器失败
- alert : PostgreSQLDown
expr : pg_up{job="postgresql"} == 0
for : 1m
labels : { severity : critical }
annotations :
summary : "PostgreSQL 抓取失败 ({{ $labels.instance }})"
# 整体抓取耗时异常(单位:秒)
- alert : PgExporterSlowScrape
expr : pg_exporter_scrape_duration{job="postgresql"} > 8
for : 5m
labels : { severity : warning }
annotations :
summary : "pg_exporter 抓取缓慢 ({{ $labels.instance }})"
基于角色的流量路由
/primary、/replica、/read 等健康检查端点可以直接充当 HAProxy 等负载均衡器的健康检查探针,实现主从读写分离。端点语义与完整的 HAProxy 配置示例见 API 参考 。