Nginx反向代理无法访问prometheus容器

Osk*_*son 0 reverse-proxy nginx docker grafana prometheus

我创建了这个 docker compose 文件,该文件构建+运行没有错误

version: '3.7'

volumes:
  grafana:
    driver: local
  prometheus-data:
    driver: local

services:
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    expose:
      - 9090
    volumes:
      - prometheus-data:/prometheus
      - ./prometheus:/etc/prometheus
    restart: unless-stopped
    command:
      - "--config.file=/etc/prometheus/prometheus.yml"
  
  grafana:
    image: grafana/grafana-oss:latest
    container_name: grafana
    expose:
      - 3000
    volumes:
      - grafana:/etc/grafana
    restart: unless-stopped
  
  nginx:
    image: nginx
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /opt/certs/:/etc/nginx/certs/
      - ./nginx/gw-web/:/usr/share/nginx/html:ro
      - ./nginx/nginx_proxy.conf:/etc/nginx/conf.d/default.conf
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    command: [nginx-debug, '-g', 'daemon off;']

Run Code Online (Sandbox Code Playgroud)

nginx 具有以下反向代理配置:

server {
    listen 80;
    listen [::]:80;
    server_name 10.23.225.72;

    location /prometheus {

        proxy_pass http://prometheus:9090;

        proxy_set_header   Host             $host;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_max_temp_file_size 0;
        proxy_read_timeout 3000;    
    }


    location /grafana {

        proxy_pass http://grafana:3000;

        proxy_set_header   Host             $host;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_max_temp_file_size 0;
        proxy_read_timeout 3000;    
    }

    location / {
       root /usr/share/nginx/html;
    }
}
Run Code Online (Sandbox Code Playgroud)

根页面可以访问并且按预期工作,但是当我尝试访问任何容器时,我只是收到“404:未找到”错误。

我也尝试过:

    location /prometheus {

        proxy_pass http://prometheus:9090/;
Run Code Online (Sandbox Code Playgroud)

    location /prometheus/ {

        proxy_pass http://prometheus:9090/;
Run Code Online (Sandbox Code Playgroud)

    location /prometheus/ {

        proxy_pass http://prometheus:9090;
Run Code Online (Sandbox Code Playgroud)

我也尝试过在主机上将 nginx 作为服务运行,但也没有成功,无论如何我的项目要求我将其容器化。

为了搞笑,我尝试将另一个 nginx 容器添加到 docker compose 文件中:

  nginx2:
    image: nginx
    container_name: webserver2
    restart: unless-stopped
    expose:
      - 8080
Run Code Online (Sandbox Code Playgroud)

和 nginx 配置:

    location /webserver {

        proxy_pass http://webserver2:8080/;

        proxy_set_header   Host             $host;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_max_temp_file_size 0;
        proxy_read_timeout 3000;    
    }
Run Code Online (Sandbox Code Playgroud)

但这也会返回 404。

也许是 docker 网络出了什么问题吗?

我通过从 vscode 检查网络配置 json

{
    "Name": "frp-6_default",
    "Id": "940872d1cf151f8d1bb060edbf95c1bcfe29a544c7ea9561091b79a6c5588510",
    "Created": "2023-01-25T11:52:01.520893117Z",
    "Scope": "local",
    "Driver": "bridge",
    "EnableIPv6": false,
    "IPAM": {
        "Driver": "default",
        "Options": null,
        "Config": [
            {
                "Subnet": "172.18.0.0/16",
                "Gateway": "172.18.0.1"
            }
        ]
    },
    "Internal": false,
    "Attachable": false,
    "Ingress": false,
    "ConfigFrom": {
        "Network": ""
    },
    "ConfigOnly": false,
    "Containers": {
        "4a2c2b6ca8aec52f801ad554c6b2c14abbe616078393f1e8ef40bd82ad12aa2a": {
            "Name": "webserver2",
            "EndpointID": "86228e6678d82a9d6735b5440618be7fc281127e6d610d281d9ffc5bcb4f256f",
            "MacAddress": "02:42:ac:12:00:05",
            "IPv4Address": "172.18.0.5/16",
            "IPv6Address": ""
        },
        "9e13cbc4805fedf4db05b5de989f726bc110b97596b99b933a93e701641294a9": {
            "Name": "webserver",
            "EndpointID": "1bbcfe058373b225e5f53e8ff4d907d39bed578d9ac14d514ccf8da2d3c9628a",
            "MacAddress": "02:42:ac:12:00:04",
            "IPv4Address": "172.18.0.4/16",
            "IPv6Address": ""
        },
        "b846cc374fa09e90589c982613224f31135660a17a5f4585b24d876ea2abd53c": {
            "Name": "grafana",
            "EndpointID": "3c0dac6d612a48dc067a5c208334af4f90c8c1d9122e263ca464186c1cf19f35",
            "MacAddress": "02:42:ac:12:00:03",
            "IPv4Address": "172.18.0.3/16",
            "IPv6Address": ""
        },
        "dbe81d7b88413f78a06ce94f86781242299a3f6eee0f96f607ebaf8fb0b17be6": {
            "Name": "prometheus",
            "EndpointID": "4792bbd19cc7b782ec522d148eef7dcb5e31b5e38d99e886ff728a3f519b4973",
            "MacAddress": "02:42:ac:12:00:02",
            "IPv4Address": "172.18.0.2/16",
            "IPv6Address": ""
        }
    },
    "Options": {},
    "Labels": {
        "com.docker.compose.network": "default",
        "com.docker.compose.project": "frp-6",
        "com.docker.compose.version": "2.15.1"
    }
}
Run Code Online (Sandbox Code Playgroud)

以下几点对我来说很突出:

    "Internal": false,
    "Attachable": false,
Run Code Online (Sandbox Code Playgroud)

这些可能是罪魁祸首吗?如果是这样,我该如何更改它们?作为记录,我还尝试将容器的 IP 地址放入 nginx 配置中,如下所示

    location /prometheus {

        proxy_pass http://172.18.0.2:9090/;
Run Code Online (Sandbox Code Playgroud)

还是不成功...

lar*_*sks 5

这里的问题出在你的普罗米修斯配置中。因为你有:

    location /prometheus {
        proxy_pass http://prometheus:9090;
        ...
    }
Run Code Online (Sandbox Code Playgroud)

当您访问 时http://yourhost/prometheus/,该请求将被代理到http://prometheus:9090/prometheus/,并且默认情况下 prometheus 不知道如何处理该/prometheus路径。

您需要使用命令行选项告诉它它是从非根路径提供的--web.external-url。这可能看起来像:

services:
  prometheus:
    image: prom/prometheus:latest
    volumes:
      - ./prometheus:/etc/prometheus
      - prometheus-data:/prometheus
    restart: unless-stopped
    command:
      - --config.file=/etc/prometheus/prometheus.yml
      - --storage.tsdb.path=/prometheus
      - --web.console.libraries=/usr/share/prometheus/console_libraries
      - --web.console.templates=/usr/share/prometheus/consoles
      - --web.external-url=http://localhost:8080/prometheus/
Run Code Online (Sandbox Code Playgroud)

(我保留了普罗米修斯图像中默认使用的所有命令行选项;这里唯一的新东西就是选项--web.external-url。)


在进行此更改之前:

$ curl -i http://localhost:8080/prometheus
HTTP/1.1 404 Not Found
Server: nginx/1.23.3
Date: Wed, 25 Jan 2023 13:17:42 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 19
Connection: keep-alive
X-Content-Type-Options: nosniff

404 page not found
Run Code Online (Sandbox Code Playgroud)

进行此更改后:

$ curl -i http://localhost:8080/prometheus
HTTP/1.1 302 Found
Server: nginx/1.23.3
Date: Wed, 25 Jan 2023 13:18:19 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 40
Connection: keep-alive
Location: /prometheus/graph

<a href="/prometheus/graph">Found</a>.
Run Code Online (Sandbox Code Playgroud)