部署指南
生产环境部署策略与最佳实践
本指南涵盖生产环境的部署策略、最佳实践和实际配置。
pg_exporter 本身可以通过以下方式配置:
- 命令行参数(优先级较高)
- 环境变量(优先级较低)
指标采集器通过 YAML 配置文件(目录/文件)进行配置:
/etc/pg_exporter.yml(默认)/etc/pg_exporter/(包含多个文件的目录)
配置文件使用 YAML 格式,由 采集器定义 组成,指定要采集的指标以及如何采集。
命令行参数
所有配置选项都可以通过命令行标志指定:
pg_exporter \
--url="postgres://user:pass@localhost:5432/postgres" \
--config="/etc/pg_exporter/pg_exporter.yml" \
--web.listen-address=":9630" \
--auto-discovery \
--exclude-database="template0,template1" \
--log.level="info"
运行 pg_exporter --help 获取完整的可用标志列表:
Flags:
-h, --[no-]help 显示上下文相关帮助(也可尝试 --help-long 和 --help-man)。
-u, --url=URL postgres 目标 URL
-c, --config=CONFIG 配置目录或文件路径
--[no-]web.systemd-socket 使用 systemd socket 激活监听器代替端口监听器(仅限 Linux)。
--web.listen-address=:9630 ...
暴露指标和 Web 界面的地址。可重复指定多个地址。示例:`:9100` 或 `[::1]:9100` 用于 http,`vsock://:9100` 用于 vsock
--web.config.file="" 可启用 TLS 或认证的配置文件路径。参见:https://github.com/prometheus/exporter-toolkit/blob/master/docs/web-configuration.md
-l, --label="" 常量标签:逗号分隔的 label=value 对列表 ($PG_EXPORTER_LABEL)
-t, --tag="" 标签,逗号分隔的服务器标签列表 ($PG_EXPORTER_TAG)
-C, --[no-]disable-cache 强制不使用缓存 ($PG_EXPORTER_DISABLE_CACHE)
-m, --[no-]disable-intro 禁用采集器级别的内省指标 ($PG_EXPORTER_DISABLE_INTRO)
-a, --[no-]auto-discovery 自动抓取给定服务器的所有数据库 ($PG_EXPORTER_AUTO_DISCOVERY)
-x, --exclude-database="template0,template1,postgres"
启用自动发现时排除的数据库 ($PG_EXPORTER_EXCLUDE_DATABASE)
-i, --include-database="" 启用自动发现时包含的数据库 ($PG_EXPORTER_INCLUDE_DATABASE)
-n, --namespace="" 内置指标的前缀,默认为 (pg|pgbouncer) ($PG_EXPORTER_NAMESPACE)
-f, --[no-]fail-fast 启动时立即失败而不是等待 ($PG_EXPORTER_FAIL_FAST)
-T, --connect-timeout=100 连接超时(毫秒),默认 100 ($PG_EXPORTER_CONNECT_TIMEOUT)
-P, --web.telemetry-path="/metrics"
暴露指标的 URL 路径 ($PG_EXPORTER_TELEMETRY_PATH)
-D, --[no-]dry-run 干运行并打印原始配置
-E, --[no-]explain 解释服务器计划的查询
--log.level="info" 日志级别:debug|info|warn|error]
--log.format="logfmt" 日志格式:logfmt|json
--[no-]version 显示应用程序版本
环境变量
所有命令行参数都有对应的环境变量:
PG_EXPORTER_URL='postgres://:5432/?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'
pg_exporter
部署架构
最简单的部署方式是每个 PostgreSQL 实例配置一个导出器:
┌─────────────┐ ┌──────────────┐ ┌────────────┐
│ Prometheus │────▶│ PG Exporter │────▶│ PostgreSQL │
└─────────────┘ └──────────────┘ └────────────┘
:9630 :5432
多数据库环境
使用自动发现来监控多个数据库(默认启用):
┌─────────────┐ ┌────────────────┐ ┌────────────┐
│ Prometheus │────▶│ PG Exporter │────▶│ PostgreSQL │
└─────────────┘ │ 启用自动发现 │ │ ├─ db1 │
│ │ │ ├─ db2 │
└────────────────┘ │ └─ db3 │
└────────────┘
生产配置
PostgreSQL 用户设置
创建一个具有最小必要权限的专用监控用户:
-- 创建监控角色
CREATE ROLE pg_monitor WITH LOGIN PASSWORD 'strong_password' CONNECTION LIMIT 5;
-- 授予必要权限
GRANT pg_monitor TO pg_monitor; -- PostgreSQL 10+ 内置角色
GRANT CONNECT ON DATABASE postgres TO pg_monitor;
-- 对于特定数据库
GRANT CONNECT ON DATABASE app_db TO pg_monitor;
GRANT USAGE ON SCHEMA public TO pg_monitor;
-- 扩展监控的额外权限
GRANT SELECT ON ALL TABLES IN SCHEMA pg_catalog TO pg_monitor;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA pg_catalog TO pg_monitor;
连接安全
使用 SSL/TLS
# 带 SSL 的连接字符串
PG_EXPORTER_URL='postgres://pg_monitor:password@db.example.com:5432/postgres?sslmode=require&sslcert=/path/to/client.crt&sslkey=/path/to/client.key&sslrootcert=/path/to/ca.crt'
使用 .pgpass 文件
# 创建 .pgpass 文件
echo "db.example.com:5432:*:pg_monitor:password" > ~/.pgpass
chmod 600 ~/.pgpass
# 在 URL 中不使用密码
PG_EXPORTER_URL='postgres://pg_monitor@db.example.com:5432/postgres'
Systemd 服务配置
完整的生产环境 systemd 设置:
[Unit]
Description=Prometheus exporter for PostgreSQL/Pgbouncer server metrics
Documentation=https://github.com/pgsty/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/?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'
服务管理
启动和停止服务
# 启动服务
sudo systemctl start pg_exporter
# 停止服务
sudo systemctl stop pg_exporter
# 重启服务
sudo systemctl restart pg_exporter
# 查看服务状态
sudo systemctl status pg_exporter
# 设置开机自启
sudo systemctl enable pg_exporter
查看日志
# 实时查看日志
journalctl -u pg_exporter -f
# 查看最近的日志
journalctl -u pg_exporter --since "1 hour ago"
# 查看错误日志
journalctl -u pg_exporter -p err
Docker 部署
基本 Docker 运行
docker run -d \
--name pg_exporter \
--restart unless-stopped \
-p 9630:9630 \
-e PG_EXPORTER_URL="postgres://user:pass@host:5432/postgres" \
pgsty/pg_exporter:latest
Docker Compose
version: '3.8'
services:
pg_exporter:
image: pgsty/pg_exporter:latest
container_name: pg_exporter
restart: unless-stopped
ports:
- "9630:9630"
environment:
- PG_EXPORTER_URL=postgres://pg_monitor:password@postgres:5432/postgres
- PG_EXPORTER_AUTO_DISCOVERY=true
- PG_EXPORTER_EXCLUDE_DATABASE=template0,template1
volumes:
- ./pg_exporter.yml:/etc/pg_exporter.yml:ro
depends_on:
- postgres
Kubernetes 部署
Deployment 示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: pg-exporter
labels:
app: pg-exporter
spec:
replicas: 1
selector:
matchLabels:
app: pg-exporter
template:
metadata:
labels:
app: pg-exporter
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9630"
spec:
containers:
- name: pg-exporter
image: pgsty/pg_exporter:latest
ports:
- containerPort: 9630
env:
- name: PG_EXPORTER_URL
valueFrom:
secretKeyRef:
name: pg-credentials
key: connection-url
- name: PG_EXPORTER_AUTO_DISCOVERY
value: "true"
livenessProbe:
httpGet:
path: /liveness
port: 9630
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /readiness
port: 9630
initialDelaySeconds: 5
periodSeconds: 5
resources:
limits:
cpu: 200m
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi
Service 示例
apiVersion: v1
kind: Service
metadata:
name: pg-exporter
labels:
app: pg-exporter
spec:
ports:
- port: 9630
targetPort: 9630
name: metrics
selector:
app: pg-exporter
Prometheus 配置
静态配置
scrape_configs:
- job_name: 'postgresql'
static_configs:
- targets:
- 'pg-exporter-1:9630'
- 'pg-exporter-2:9630'
- 'pg-exporter-3:9630'
服务发现
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_ip]
target_label: __address__
replacement: ${1}:9630
监控与告警
推荐的告警规则
groups:
- name: pg_exporter
rules:
# 导出器宕机告警
- alert: PgExporterDown
expr: up{job="postgresql"} == 0
for: 5m
labels:
severity: critical
annotations:
summary: "PG Exporter 宕机"
description: "{{ $labels.instance }} 的 PG Exporter 已宕机超过 5 分钟"
# 数据库连接失败告警
- alert: PostgreSQLDown
expr: pg_up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "PostgreSQL 连接失败"
description: "无法连接到 {{ $labels.instance }} 上的 PostgreSQL"
# 抓取时间过长告警
- alert: PgExporterSlowScrape
expr: pg_exporter_last_scrape_duration_seconds > 30
for: 5m
labels:
severity: warning
annotations:
summary: "PG Exporter 抓取缓慢"
description: "{{ $labels.instance }} 的抓取时间超过 30 秒"