使用变量将nginx代理到prometheus

6
我有以下的nginx.conf配置文件:
location /monitoring/prometheus/ {
  resolver 172.20.0.10 valid=5s;
  set $prometheusUrl http://prometheus.monitoring.svc.cluster.local:9090/;

  proxy_set_header Accept-Encoding "";
  proxy_pass $prometheusUrl;
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;

  sub_filter_types text/html;
  sub_filter_once off;
  sub_filter '="/' '="/monitoring/prometheus/';
  sub_filter 'var PATH_PREFIX = "";' 'var PATH_PREFIX = "/monitoring/prometheus";';

  rewrite ^/monitoring/prometheus/?$ /monitoring/prometheus/graph redirect;
  rewrite ^/monitoring/prometheus/(.*)$ /$1 break;
}

当我访问 https://myHost/monitoring/prometheus/graph 时,会被重定向到 /graph (https://myHost/graph)。

当我不使用变量并直接将 URL 放置到 proxy_pass 中时,一切都按预期工作。我可以访问 https://myHost/monitoring/prometheus/graph 并查看 Prometheus。
location /monitoring/prometheus/ {
  resolver 172.20.0.10 valid=5s;

  proxy_set_header Accept-Encoding "";
  proxy_pass http://prometheus.monitoring.svc.cluster.local:9090/;
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;

  sub_filter_types text/html;
  sub_filter_once off;
  sub_filter '="/' '="/monitoring/prometheus/';
  sub_filter 'var PATH_PREFIX = "";' 'var PATH_PREFIX = "/monitoring/prometheus";';

  rewrite ^/monitoring/prometheus/?$ /monitoring/prometheus/graph redirect;
  rewrite ^/monitoring/prometheus/(.*)$ /$1 break;
}

有人能向我解释一下为什么使用变量会导致路由行为不同吗?我需要使用变量来强制nginx在每个请求中解析DNS名称。
2个回答

6
我刚刚想到了。 根据文档所述。

When variables are used in proxy_pass:

location /name/ {
    proxy_pass http://127.0.0.1$request_uri;
}

In this case, if URI is specified in the directive, it is passed to the server as is, replacing the original request URI.

问题出在我在变量中指定了请求URI(末尾的/)。

删除这个/后,一切正常运行。

这里是正常工作的配置:

location /monitoring/prometheus/ {
  set $prometheusUrl http://prometheus.monitoring.svc.cluster.local:9090;

  proxy_set_header Accept-Encoding "";
  proxy_pass $prometheusUrl;
  proxy_redirect off;
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;

  sub_filter_types text/html;
  sub_filter_once off;
  sub_filter '="/' '="/monitoring/prometheus/';
  sub_filter 'var PATH_PREFIX = "";' 'var PATH_PREFIX = "/monitoring/prometheus";';

  rewrite ^/monitoring/prometheus/?$ /monitoring/prometheus/graph redirect;
  rewrite ^/monitoring/prometheus/(.*)$ /$1 break;
}

我认为需要注意的是将监听端口保持在80。其他端口对我来说都无法工作。我还向prometheus v2.28.1添加了--web.route-prefix=/--web.external-url=http://<ip>/prometheus标志。另一个注意点是警告nginx: [warn] duplicate MIME type "text/html",看起来sub_filter_types不再必要。 - philo

2
我认为最好使用prometheus的--web.external-url命令行选项。
这个沙盒示例展示了一个完整的工作堆栈,包括nginx配置。 https://github.com/prometheus-community/prometheus-playground/tree/master/nginx 值得注意的是docker-compose.yml文件中的prometheus命令部分。
command:
- --config.file=/etc/prometheus/prometheus.yml
- --web.route-prefix=/
- --web.external-url=http://example.com/prometheus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接