【问题标题】:nginx reverse proxy to other nginx 502 bad gatewaynginx反向代理到其他nginx 502坏网关
【发布时间】:2021-01-27 18:21:58
【问题描述】:

我想创建两个服务,它们都有自己的 nginx。我想使用第三个 nginx 作为这两个的反向代理,但我得到了

502 网关错误

当我请求时

http://127.0.0.1:8080/
http://127.0.0.1:8080/one
http://127.0.0.1:8080/two

访问:

http://127.0.0.1:8081
http://127.0.0.1:8082

工作正常

我有这个 docker-compose.yml

version: "3.3"
services:
  nginx-one:
    image: nginx:1.17.8
    ports:
      - "8081:80"
    networks: 
      - frontend
      - backend
    volumes: 
      - ./nginx-one/html:/usr/share/nginx/html
  nginx-two:
    image: nginx:1.17.8
    ports:
      - "8082:80"
    networks: 
      - frontend
      - backend
    volumes: 
      - ./nginx-two/html:/usr/share/nginx/html
  nginx-reverse-proxy:
    image: nginx:1.17.8
    ports:
      - "8080:80"
    networks: 
      - frontend
      - backend
    volumes: 
      - ./nginx-reverse-proxy/html:/usr/share/nginx/html
      - ./nginx-reverse-proxy/conf.d:/etc/nginx/conf.d
  debian-network:
    image: cslev/debian_networking
    stdin_open: true # docker run -i
    tty: true        # docker run -t
    networks: 
      - frontend
      - backend
networks:
  frontend:
    internal: false
  backend:
    internal: true

和目录结构

.
├── docker-compose.yml
├── nginx-one
│   └── html
│       └── index.html
├── nginx-reverse-proxy
│   ├── conf.d
│   │   └── default.conf
│   └── html
│       └── index.html
├── nginx-two
    └── html
        └── index.html

nginx.conf 内容

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

conf.d/default.conf

server {

    listen 80;

    location /one {
        proxy_pass http://127.0.0.1:8081/;
    }

    location /two {
        proxy_pass http://127.0.0.1:8082/;
    }
}

当我评论 docker-compose.yml 这一行时

# ./nginx-reverse-proxy/conf.d:/etc/nginx/conf.d

所以conf.d/default.conf没有使用,我从主机的浏览器请求:

http://127.0.0.1:8080/

它从 nginx-reverse-proxy 本身给出了正确的响应,但显然

http://127.0.0.1:8080/one
http://127.0.0.1:8080/two

不提供任何回应

http://127.0.0.1:8081
http://127.0.0.1:8082

但是 404 代替。

docker ps 输出:

IMAGE                     COMMAND                  CREATED          STATUS         PORTS                  NAMES
cslev/debian_networking   "bash"                   25 minutes ago   Up 3 minutes                          nginxproblem_debian-network_1
nginx:1.17.8              "nginx -g 'daemon of…"   47 minutes ago   Up 3 minutes   0.0.0.0:8080->80/tcp   nginxproblem_nginx-reverse-proxy_1
nginx:1.17.8              "nginx -g 'daemon of…"   14 hours ago     Up 3 minutes   0.0.0.0:8082->80/tcp   nginxproblem_nginx-two_1
nginx:1.17.8              "nginx -g 'daemon of…"   14 hours ago     Up 3 minutes   0.0.0.0:8081->80/tcp   nginxproblem_nginx-one_1

运行这个脚本:

#!/bin/sh

docker exec nginxproblem_debian-network_1 curl -sS 127.0.0.1:8080
docker exec nginxproblem_debian-network_1 curl -sS nginxproblem_nginx-reverse-proxy_1:8080

docker exec nginxproblem_debian-network_1 curl -sS 127.0.0.1:8080/one
docker exec nginxproblem_debian-network_1 curl -sS nginxproblem_nginx-reverse-proxy_1:8080/one
docker exec nginxproblem_debian-network_1 curl -sS 127.0.0.1:8080/two
docker exec nginxproblem_debian-network_1 curl -sS nginxproblem_nginx-reverse-proxy_1:8080/two

docker exec nginxproblem_debian-network_1 curl -sS 127.0.0.1:8081
docker exec nginxproblem_debian-network_1 curl -sS nginxproblem_nginx-one_1:8080

docker exec nginxproblem_debian-network_1 curl -sS 127.0.0.1:8082
docker exec nginxproblem_debian-network_1 curl -sS nginxproblem_nginx-two_1:8082

给予:

curl: (7) Failed to connect to 127.0.0.1 port 8080: Connection refused
curl: (7) Failed to connect to nginxproblem_nginx-reverse-proxy_1 port 8080: Connection refused
curl: (7) Failed to connect to 127.0.0.1 port 8080: Connection refused
curl: (7) Failed to connect to nginxproblem_nginx-reverse-proxy_1 port 8080: Connection refused
curl: (7) Failed to connect to 127.0.0.1 port 8080: Connection refused
curl: (7) Failed to connect to nginxproblem_nginx-reverse-proxy_1 port 8080: Connection refused
curl: (7) Failed to connect to 127.0.0.1 port 8081: Connection refused
curl: (7) Failed to connect to nginxproblem_nginx-one_1 port 8080: Connection refused
curl: (7) Failed to connect to 127.0.0.1 port 8082: Connection refused
curl: (7) Failed to connect to nginxproblem_nginx-two_1 port 8082: Connection refused

- ./nginx-reverse-proxy/conf.d:/etc/nginx/conf.d未被评论时,

- ./nginx-reverse-proxy/conf.d:/etc/nginx/conf.d被注释时,输出与从浏览器访问IP地址相反。

【问题讨论】:

    标签: docker nginx reverse-proxy


    【解决方案1】:

    除非您启用了host networking,否则127.0.0.1 将指向容器本身。您可以通过服务名称从同一网络中的容器内部引用其他两个容器,例如nginx-onenginx-two

    您还将容器端口 80 映射到主机上的端口 8080/8081/8082。然而,这对同一网络中的容器之间的通信没有任何作用。检查the docs

    默认情况下,当您使用 docker create 或 docker run 创建或运行容器时,它不会向外界发布任何端口。要使端口可用于 Docker 外部的服务或未连接到容器网络的 Docker 容器,请使用 --publish 或 -p 标志。这将创建一个防火墙规则,该规则将容器端口映射到 Docker 主机上与外部世界的端口。

    所以,尝试将http://127.0.0.1:8081/; 更改为http://nginx-one/;,它应该可以工作。

    【讨论】:

    • 引用其他容器名称不起作用,请在编辑后查看我的问题。你能提供一个可行的例子吗?
    • 因为你还在使用映射到 Docker 主机的端口,所以我更新了我的答案。
    • 它现在正在工作,正如你所说,我将 localhost 地址更改为容器名称并删除了 808x 端口。如果我期望容器通过暴露的端口而不是使用它们在其网络中的端口(端口 80)进行通信,那我一定已经厌倦了。
    猜你喜欢
    • 2022-01-20
    • 2021-04-09
    • 1970-01-01
    • 2020-11-12
    • 1970-01-01
    • 1970-01-01
    • 2014-01-25
    • 2017-06-23
    • 2019-10-03
    相关资源
    最近更新 更多