使用现有 Prometheus
Docker Compose 快速入门会部署一个内置 Prometheus。如果你已经在运行 Prometheus,可以用外部部署替换内置实例。迁移后,控制台的 Monitoring 页面将查询外部 Prometheus。
网关指标如何到达 Prometheus
API7 网关指标可以通过两条独立路径到达 Prometheus。
| 路径 | 数据流 | 用途 |
|---|---|---|
| 远程写入 | 数据面 → DP Manager → Prometheus(/api/v1/write) | 控制台的 Monitoring 页面,其查询会发送到此 Prometheus。 |
| 抓取 | Prometheus → 数据面 :9091(参见监控指标) | 确认网关端点不会重复暴露指标族后,用于你自己的 Grafana 仪表板或告警系统。 |
内置 Prometheus 接收控制 台所需的远程写入数据。当指标端点不会重复暴露指标族时,两条路径使用相同的指标名称和标签。只有抓取得到的序列会额外携带 Prometheus 添加的 job 和 instance 标签。控制台查询使用 sum(...) by (...) 聚合,并且不按 job 筛选,因此 Monitoring 页面可以查询通过任一路径传入的指标。
如果同一个 Prometheus 既抓取数据面,又接收远程写入,同一网关指标可能通过两条路径到达。控制台随后会重复计算请求和带宽序列。每个 Prometheus 实例只保留一条路径。
前置条件
迁移前,请确保外部实例和控制面配置文件均可用。
- 一个控制面容器可以访问的外部 Prometheus 实例。
- 包含
docker-compose.yaml、dashboard_conf/conf.yaml和dp_manager_conf/conf.yaml的控制面部署目录。在某些版本中,服务名称可能是api7-ee-dashboard和api7-ee-dp-manager。
选择迁移路径
对于当前公开发布版本,请使用远程写入。只有后续已修复版本,或 API7 支持团队确认包含修复的构建,才能使用直接抓取。
此版本的数据面端点会重复暴露 apisix_nginx_metric_errors_total,Prometheus 会拒绝整个抓取。目前尚未发布修复版本。
比较两条路径所需的变更:
| 考量项 | 远程写入 | 直接抓取 |
|---|---|---|
| 可用性 | 当前公开发布版本可用 | 当前公开发布版本不可用;需要后续已修复版本或 API7 支持团队确认的构建 |
| 适用场景 | 外部 Prometheus 可以接收 DP Manager 的远程写入,包括此前已抓取数据面的情况 | 外部 Prometheus 已经抓取经验证不会重复暴露指标族的网关端点 |
| 外部 Prometheus 变更 | 添加 --web.enable-remote-write-receiver;控制面向其写入指标 | 无;抓取配置保持不变 |
| 所需权限 | 控制台需要读取权限;DP Manager 需要写入权限 | 读取权限 |
| 现有 Grafana 和告警 | 远程写入的序列不包含 job 和 instance;需要更新按这些标签筛选的查询 | 无需更改查询 |
完成其中一条路径的配置后,再继续完成通用的身份认证、移除、重启、验证和回滚步骤。
备份当前配置
创建一个可用于恢复原始 Prometheus 配置和 Docker Compose 服务的备份。
cd <control-plane-directory>
BAK="/var/tmp/api7-prom-backup-$(date +%F)"
mkdir -p "$BAK"
cp -a docker-compose.yaml dashboard_conf dp_manager_conf "$BAK"/
配置远程写入
DP Manager 将网关指标发送到外部 Prometheus,控制台则查询同一实例。
启用远程写入接收端
--web.enable-remote-write-receiver 是 Prometheus 启动参数,而不是 prometheus.yml 设置。添加该参数后,重启或重新创建 Prometheus 以使变更生 效:
- systemd:将
--web.enable-remote-write-receiver添加到ExecStart,再运行systemctl daemon-reload && systemctl restart prometheus。 - Docker / Docker Compose:将
--web.enable-remote-write-receiver添加到容器的command,再重新创建容器。 - Kubernetes:将该参数添加到 Prometheus 容器的
args,再滚动更新 Pod。
确认接收端已启用:
curl -s -o /dev/null -w '%{http_code}\n' -X POST "http://<external-prometheus>:9090/api/v1/write"
# 400 = 已启用(无效请求体,符合预期) 404 = 仍未启用
如果端点需要身份认证,请添加匹配的认证方式(例如为 Basic 身份认证添加 -u <user>:<password>),并使用 https:// URL。401 或 403 响应表示身份认证失败,而不是接收端未启用。
让控制台和 DP Manager 使用外部 Prometheus
在两个配置文件中将 addr 设置为外部 Prometheus。保持 telemetry.enable: true,使 DP Manager 继续上报指标。
prometheus:
addr: "http://<external-prometheus>:9090" # 必须能从控制台容器内访问
query_path_prefix: ""
whitelist:
- "/api/v1/query_range"
- "/api/v1/query"
# 保持其余配置不变
telemetry:
enable: true # 为远程写入保持启用
prometheus:
addr: "http://<external-prometheus>:9090"
remote_write_path: "/api/v1/write"
使用远程写入时,可以跳过直接抓取部分并继续配置身份认证。
在已验证的修复版本中保留直接抓取
只有后续修复了重复暴露问题的版本,或 API7 支持团队确认包含修复的构建,才能使用直接抓取。
继续操作前,请配置数据面指标监听器,使其绑定到 Prometheus 可访问的地址。监听器默认绑定到 127.0.0.1;仅发布或暴露 9091 端口不会改变该绑定地址。有关监听器配置,请参阅监控指标。
确认外部 Prometheus 中已有网关指标
通过路由发送几个请求,然后检查外部 Prometheus 是否已经摄取相应的网关指标。以下只读请求应返回大于 0 的结果:
curl -sG --data-urlencode 'query=count(apisix_http_status)' \
"http://<external-prometheus>:9090/api/v1/query"
结果为空也可能表示尚无流量到达网关,或尚未将 prometheus 插件启用为全局规则。如果产生流量后计数仍为 0,请先修复抓取任务或启用插件。
如果外部 Prometheus 启用了身份认证,请为此 curl 添加凭据(例如 -u <user>:<password>),并使用 https:// URL。401 或 403 响应表示身份认证失败,而不是缺少指标。
让控制台使用外部 Prometheus 并停止远程写入
编辑 dashboard_conf/conf.yaml。将 addr 改为外部 Prometheus,并禁用遥测,使控制面停止写入会与抓取结果重复的指标。
prometheus:
addr: "http://<external-prometheus>:9090" # 必须能从控制台容器内访问
query_path_prefix: ""
whitelist:
- "/api/v1/query_range"
- "/api/v1/query"
# 保持其余配置不变
telemetry:
enable: false
如果 telemetry.enable 仍为 true,控制面会继续远程写入与抓取序列冲突的指标,控制台会将它们重复计算。
此 telemetry 配置块是控制面 dashboard_conf/conf.yaml 中的顶层键,而不是优化遥测数据传输中介绍的数据面 api7ee.telemetry 退出选项。禁用它会让 DP Manager 停止向 Prometheus 远程写入。重新创建控制面容器后更改即会生效,数据面会继续处理流量。
使用直接抓取时,无需更改 dp_manager_conf/conf.yaml。禁用遥测后,DP Manager 会停止连接 Prometheus,因此不再使用其中的 addr 值。
配置身份认证
如果外部 Prometheus 不要求身份认证,请继续移除内置 Prometheus。否则,请配置该实例所使用的认证方式。
Basic 身份认证
添加嵌套的 basic_auth 配置块。控制面会忽略直接在 prometheus 下设置的 username 和 password。
请通过 HTTPS 或可信网络发送 Basic 凭据,因为使用纯 http:// 会以明文传输凭据。请将 addr 指向 https:// 端点,或通过同机反向代理终止 TLS。
prometheus:
addr: "https://<external-prometheus>:9090" # 使用 https,避免凭据以明文发送
basic_auth:
username: "api7-readonly"
password: "<password>"
使用远程写入时,请在 dp_manager_conf/conf.yaml 中添加相同的 basic_auth 配置块。DP Manager 凭据需要拥有 /api/v1/write 的写入权限。
双向 TLS
控制面原生支持通过 tls 配置块配置客户端证书,无需代理。将 addr 指向 https:// 端点,并引用客户端密钥对和 CA:
prometheus:
addr: "https://<external-prometheus>:9090"
tls:
enable_client_cert: true
cert_file: /path/to/client.crt
key_file: /path/to/client.key
ca_file: /path/to/ca.crt
使用远程写入时,请在 dp_manager_conf/conf.yaml 中添加相同的 tls 配置块,并将证书文件挂载到控制面容器中。
其他身份认证方案
对于 Bearer Token 或控制面不原生支持的其他认证方式,请在 Prometheus 前部署反向代理来注入凭据。将 addr 指向该代理;如果代理在某个路径前缀下提供 API,请设置 query_path_prefix。
使用远程写入时,同一前缀也适用于写入请求。请将 dp_manager_conf/conf.yaml 中的 remote_write_path 设置为包含该前缀的路径(例如 /prom-proxy/api/v1/write),或让代理保留 /api/v1/write。
使用远程写入时,控制台和 DP Manager 从不同文件读取凭据,因此可以使用不同账户。Prometheus 原生授权会向每个有效账户授予相同的读取和写入权限,因此使用不同账户可改善凭据管理,但无法让控制台账户变为只读。
要强制实施端点级权限,请在 Prometheus 前部署反向代理。只允许控制台账户访问 /api/v1/query 和 /api/v1/query_range,并允许 DP Manager 账户访问 /api/v1/write。阻止写入端点会导致远程写入失败。
移除内置 Prometheus
配置一条指标路径和所需的身份认证后,从 Docker Compose 中移除内置实例。
从 docker-compose.yaml 中删除 prometheus 服务配置块,以及引用该服务的 depends_on 条目。3.9.x 参考 Compose 文件没有为 Prometheus 声明持久化数据卷;如果你的部署自行添加了命名卷或绑定挂载,请先记录其挂载关系并按需导出历史数据,在确认不需要回滚前不要删除实际存储。
services:
# 删除整个 prometheus 服务配置块
# prometheus:
# image: api7/prometheus:...
dashboard:
depends_on:
postgresql: {condition: service_healthy}
# 删除下一行
# prometheus: {condition: service_healthy}
如果保留 depends_on 条目,堆栈会因 service "dashboard" depends on undefined service "prometheus": invalid compose project 而无法启动。重启前运行 docker compose config >/dev/null 即可发现此问题。
重启控制面
本节以及验证和回滚部分中的 docker compose 命令使用服务名称 dashboard 和 dp-manager。如果 Compose 文件中的名称是 api7-ee-dashboard 和 api7-ee-dp-manager,请在所有命令中替换为对应名称。
docker compose config >/dev/null && echo "compose OK"
# 重新创建控制面组件
docker compose up -d --force-recreate dashboard dp-manager
# 按名称移除现已成为孤立容器的内置 Prometheus。
# 该服务已从 Compose 文件中删除,因此 `docker compose rm prometheus`
# 会报告 "no such service"。请改为直接删除容器:
docker rm -f <compose-project>-prometheus-1
docker compose logs --tail=100 dp-manager | grep -i prometheus
DP Manager 日志中不应出现 failed to write prometheus metrics。此流程不会重启数据面,因此数据面会继续处理流量。
--remove-orphansdocker compose up -d --remove-orphans 会删除 Compose 项目中所有不再在文件中定义的容器。如果数据面或其他容器运行在同一项目中,却没有相应的服务条目,该命令也会将其删除。按名称删除 Prometheus 可以把操作限制在目标容器上。