跳到主要内容
版本:3.9.x

使用现有 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 实例只保留一条路径。

前置条件​

迁移前,请确保外部实例和控制面配置文件均可用。

  • 一个控制面容器可以访问的外部 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 继续上报指标。

dashboard_conf/conf.yaml
prometheus:
addr: "http://<external-prometheus>:9090" # 必须能从控制台容器内访问
query_path_prefix: ""
whitelist:
- "/api/v1/query_range"
- "/api/v1/query"
# 保持其余配置不变

telemetry:
enable: true # 为远程写入保持启用
dp_manager_conf/conf.yaml
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,并禁用遥测,使控制面停止写入会与抓取结果重复的指标。

dashboard_conf/conf.yaml
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。

dashboard_conf/conf.yaml
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:

dashboard_conf/conf.yaml
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 声明持久化数据卷;如果你的部署自行添加了命名卷或绑定挂载,请先记录其挂载关系并按需导出历史数据,在确认不需要回滚前不要删除实际存储。

docker-compose.yaml
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-orphans

docker compose up -d --remove-orphans 会删除 Compose 项目中所有不再在文件中定义的容器。如果数据面或其他容器运行在同一项目中,却没有相应的服务条目,该命令也会将其删除。按名称删除 Prometheus 可以把操作限制在目标容器上。

移除现有抓取任务​

如果你在已验证的修复版本中保留了直接抓取,请跳过本节。否则,请等待重启后的控制面开始远程写入指标,然后移除现有的数据面抓取任务。重新加载 Prometheus:向进程发送 SIGHUP;如果 Prometheus 使用 --web.enable-lifecycle 运行,则向 /-/reload 发送 POST 请求。

远程写入的序列不包含抓取时添加的 job 和 instance 标签。请更新所有按这些标签筛选的 Grafana 面板或告警规则。

验证​

发送一些流量,然后等待五分钟再检查。最后一个样本到达后,Prometheus 最多还会返回对应序列五分钟,因此在此之前,已禁用路径产生的陈旧序列仍可能出现。

  • 没有重复序列:apisix_http_status{code="200"} 按路由、服务和实例各返回一条序列,这符合预期。两条路径同时启用时,同一组标签会到达两次,只能通过抓取添加的 job 和 instance 标签区分。以下查询会忽略这两个标签进行分组;只启用一条路径时不会返回结果:

    curl -sG --data-urlencode \
    'query=count without (job, instance) (apisix_http_status{code="200"}) > 1' \
    "http://<external-prometheus>:9090/api/v1/query"
  • 值与数据面一致:如果此外部 Prometheus 只接收一个数据面的指标,请将其中的 sum(apisix_http_status{code="200"}) 与该数据面端点中相同指标的总和比较(curl "http://127.0.0.1:9091/apisix/prometheus/metrics"),两者应一致。如果它汇聚多个数据面,请先使用 gateway_group_id 和 instance_id 将外部查询限定到同一数据面;不要将未限定范围的总和与单个数据面端点比较。

  • 控制台 Monitoring 页面:打开 30 分钟的时间范围,确认每个面板都有数据。

  • 使用远程写入的 DP Manager 日志中没有写入错误:docker compose logs --tail=200 dp-manager | grep -c 'failed to write prometheus' 返回 0。

回滚​

恢复备份并重新启动内置 Prometheus。数据面无需重启。

cd <control-plane-directory>
cp -a /var/tmp/api7-prom-backup-<date>/* .
docker compose up -d prometheus
docker compose up -d --force-recreate dashboard dp-manager

3.9.x 参考 Compose 文件没有为内置 Prometheus 定义持久化数据卷,因此上述回滚会启动一个没有旧历史数据的新 Prometheus。若部署使用了自定义命名卷或绑定挂载,请在启动前恢复并重新挂载同一存储。内置 Prometheus 不会补收停机期间产生的指标。

如果你使用直接抓取,外部 Prometheus 无需更改。如果你使用远程写入:

  1. 重新添加此前移除的抓取任务。
  2. 当不再有任何发送端需要远程写入接收端时,移除 --web.enable-remote-write-receiver。请采用启用远程写入接收端中启用该参数时使用的相同方式应用更改。

使用 Docker Compose 时,应重新创建 Prometheus 容器,因为普通的 restart 会复用旧命令。使用 systemd 时,应编辑 ExecStart 并重启服务。

接收端参数不会添加身份认证。如果保留接收端,请通过身份认证和网络控制保护 /api/v1/write。

注意事项​

  • 历史数据不会迁移。 3.9.x 参考 Compose 文件不会把内置 Prometheus 数据保存在命名卷中;移除或重新创建容器前,如需保留历史数据,请先将其导出(promtool tsdb dump)。如果部署自行配置了持久化存储,请保留并记录其挂载关系,以便回滚时重新挂载。
  • 使用直接抓取时,新增数据面需要抓取目标。 请将每个新增数据面添加到 Prometheus scrape_configs,否则 Prometheus 中不会包含该实例。远程写入使用现有的数据面到 DP Manager 通道,无需为每个实例添加抓取目标。
  • adc sync 可能停止大多数流量指标。 HTTP 流量指标和大多数 AI 指标族依赖默认的 prometheus 全局规则。如果 ADC 配置省略 global_rules.prometheus,同步会删除该规则。未直接启用该插件的路由上,这些指标族将停止更新;节点指标和 apisix_llm_active_connections 仍可能存在。有关启用此插件的说明,请参阅监控指标。
  • 控制面自身指标是可选的。 内置 Prometheus 还会抓取控制面自身的指标(api7_dashboard_*、etcd_*)。控制台不使用这些指标;仅当需要使用它们排查问题时,才为控制面的 7081 端口添加抓取目标。

其他资源​