Prometheus 在 Nginx 反向代理下的路由与路径配置
背景
公司小组一个端到端的容器化测试环境,位于不同的子路径下,通过 Nginx 代理:
- 比如用户 A 在
/a/
下:/a/prometheus/
- 比如用户 B 在
/b/
下:/b/prometheus/
想要达到的效果除上述不同子路径的区别下,需要在容器内部没有这个区分:即容器内可直接访问 prometheus:9090
请求 Prometheus。
TLDR: 如果你也有这样的需求,太长不想看可直接跳到最后的总结。
Prometheus 的路径和路由配置
从 Prometheus 的命令行参数中可以看到其提供了以下两个选项来控制路径与路由配置:
-
--web.external-url=<URL>
The URL under which Prometheus is externally reachable (for example, if Prometheus is served via a reverse proxy). Used for generating relative and absolute links back to Prometheus itself. If the URL has a path portion, it will be used to prefix all HTTP endpoints served by Prometheus. If omitted, relevant URL components will be derived automatically.
这是 Prometheus 外部可达的地址(URL)(经反向代理后)。
用于(在页面上或请求中)生成相对或绝对链接。
-
--web.route-prefix=<path>
Prefix for the internal routes of web endpoints. Defaults to path of --web.external-url.
Prometheus 内部 Web 请求的路由前缀。
默认为
--web.external-url
中的路径。
直接访问测试
为了在容器内可直达 Prometheus 的 API。所以 --web.route-prefix
应该配置为 /
。
而对于 --web.external-url
,由于其控制的是外部可访问的路径,以及页面中的相对链接生成。
所以这个地址应该配置成文章开始提到的路径(以用户 A 为例):/a/prometheus/
。
下面来实测看看:
1
|
|
注:为方便说明,下面以 nginx
和 prometheus
分别代表这两个服务。
API 可访问:
1 2 |
|
访问首页时被重定向到带前缀的路径下了:
1 2 3 4 5 6 7 8 |
|
但是如果尝试访问这个重定向后的地址,会报错找不到:
1 2 |
|
是不是挺奇怪的?如果我直接请求不带前缀的路径,却能找到:
1 2 |
|
所以应了 --web.external-url=<URL>
说明中“更深层次”的含义:
这个选项是用于控制反射代理前的路径,而 Prometheus 本身不需要这个路径,你应该在 nginx 中重写路径去掉。
经 nginx 代理测试
Nginx 的配置:
1 2 3 |
|
尝试访问一下,意料之中不行,因为还没有重写路径:
1 2 |
|
尝试重写一下路径:
1 2 3 4 |
|
上面这么 rewrite
规则大致含义:将请求 /a/prometheus/xxx
重写成 /xxx
后再传递给被代理的服务器。
于是,Prometheus 接收到了不带前缀的请求。并且,发现可以了:
1 2 3 4 5 |
|
经查询 nginx 的 proxy_pass
文档发现:
- 如果
proxy_pass
后不带 URL,则会直接把 nginx 接收的到原始 URL 原封不动地传递给被代理的服务器; - 如果
proxy_pass
后带有 URL,则会把location
中的前缀去掉后追加到这个 URL 后再代理过去;
这样一来,上面的 nginx 配置可以再简化成下面这样:
1 2 3 |
|
注意最后有一个 /
。
总结
-
Prometheus 的配置:
--web.external-url=/你的/前缀/
--web.route-prefix=/
-
Nginx 的配置:
1 2 3 4
location /你的/前缀/ { # 注意后面的 / 。 proxy_pass http://proemtheus:9090/; }
另外,PushGateway 和 Prometheus 有完全类似的配置。
希望可以帮到你。