Назад | Перейти на главную страницу

Простейший обратный прокси-сервер nginx для другого контейнера на том же хосте дает 502 Bad Gateway / соединение отклонено

Полностью застрял сейчас.

Это то, что у меня есть. Я создаю и запускаю простую HTML-страницу в nginx на порту 8080 (в конечном итоге я хочу запустить приложение Java tomcat, когда я это выясню).

Это в Windows 10 с Docker 17.09 и nginx 1.13.

Это конфиг:

$ cat Dockerfile
FROM nginx
COPY nginx.conf /etc/nginx
COPY static-html /usr/share/nginx/html
EXPOSE 80

и конфиг:

$ cat nginx.conf

user  nginx;
worker_processes  1;

error_log  /dev/stdout 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  /dev/stdout  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

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

Запускаем так:

$ docker run -p 8080:80 --name dummy --rm dummy-nginx

Хорошо реагирует на curl:

$ curl -i http://localhost:8080
HTTP/1.1 200 OK
Server: nginx/1.13.7
Date: Thu, 30 Nov 2017 16:46:17 GMT
Content-Type: text/html
Content-Length: 101
Last-Modified: Wed, 29 Nov 2017 16:24:39 GMT
Connection: keep-alive
ETag: "5a1edf47-65"
Accept-Ranges: bytes

<head>
  <title>oh yeah</title>
</head>
<body>
  <h1>Absolutely</h1>
  <p>did this work?</p>
</body>

Так что все работает нормально. То же самое и с обратным прокси-сервером, который не работает:

Обратный прокси Dockerfile

FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf
COPY apt-proxy.conf /etc/apt/apt.conf.d
COPY nginx_signing.key /etc/apt
RUN apt-get update
RUN apt-get -y install apt-utils
RUN apt-get -y install gnupg gnupg2 gnupg1
RUN apt-key add /etc/apt/nginx_signing.key
RUN apt-get -y install curl
RUN apt-get -y install net-tools
EXPOSE 10040
CMD ["nginx"]

(Я вложил туда эти дополнительные инструменты, чтобы попытаться диагностировать это)

Обратный прокси nginx.conf

daemon off;
user  nginx;
worker_processes  1;
pid        /var/run/nginx.pid;
error_log /dev/stdout debug;
events { worker_connections 1024; }

http {
    access_log /dev/stdout;

    upstream myapp {
        server localhost:8080;
    }

    server {
        listen 10040;

        location / {
            proxy_pass $scheme://myapp;
            proxy_redirect default;
            proxy_set_header HOST $host;
            proxy_set_header Referer $http_referer;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }    
}

Я сильно подозреваю, что вся проблема - это просто небольшая ошибка где-то там (биться головой о стену).

Командная строка для запуска обратного прокси

Это включает в себя немного журнала с ошибкой от nginx и элемент access_log, который я также отправил в / dev / stdout.

$ docker run -p 10040:10040 --name rproxy --rm we1p202420008.cloud.registry(example).com:11095/rproxy
2017/11/30 16:55:20 [notice] 1#1: using the "epoll" event method
2017/11/30 16:55:20 [notice] 1#1: nginx/1.13.7
2017/11/30 16:55:20 [notice] 1#1: built by gcc 6.3.0 20170516 (Debian 6.3.0-18)
2017/11/30 16:55:20 [notice] 1#1: OS: Linux 4.9.49-moby
2017/11/30 16:55:20 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2017/11/30 16:55:20 [notice] 1#1: start worker processes
2017/11/30 16:55:20 [notice] 1#1: start worker process 5
2017/11/30 16:55:25 [error] 5#5: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.17.0.1, server: , request: "GET / HTTP/1.1", upstream: "http://0.0.0.0:8080/", host: "localhost:10040"
172.17.0.1 - - [30/Nov/2017:16:55:25 +0000] "GET / HTTP/1.1" 502 173 "-" "curl/7.56.1"
2017/11/30 16:55:25 [info] 5#5: *1 client 172.17.0.1 closed keepalive connection

Эта ошибка регистрируется, когда я пытаюсь получить доступ к фиктивному веб-сайту через r-прокси следующим образом:

$ curl -i http://localhost:10040
HTTP/1.1 502 Bad Gateway
Server: nginx/1.13.7
Date: Thu, 30 Nov 2017 18:05:06 GMT
Content-Type: text/html
Content-Length: 173
Connection: keep-alive

<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.13.7</center>
</body>
</html>

Теперь, если в конфигурации, которую я только что опубликовал, нет ничего очевидного, и это действительно не просто моя глупость, то есть некоторые непонятные вещи, с которыми я не могу продолжить. Например, когда я бегу curl внутри моего экземпляра обратного прокси:

docker exec rproxy curl -i http://localhost:8080

он дает мне результат заблокированного содержимого корпоративного брандмауэра:

Веб-сайт http: // localhost / к которому вы пытаетесь получить доступ, в настоящее время классифицируется как URL-адреса без категорий <и считается потенциально небезопасным или непригодным для просмотра.

С помощью bridge как волшебное ключевое слово, я наконец начал получать результаты поиска, которые мне были нужны.

Комментарий к вопросу указал на проблему: nginx просто перенаправлял запросы на localhost:8080 внутри своего собственного контейнера, а не host:ports где находятся другие контейнеры докеров.

Я проверил, многие люди записывают полные доменные имена своих прокси-серверов в свои nginx.conf, чего я не хотел, так как полагал, что это может стать чрезмерно сложным, когда сборка заполняет файлы конфигурации для каждой среды.

Так что из Доступ к хост-машине из контейнера докеров и Документы Docker Я узнал о docker network сегодня и реализовал следующее, чтобы дать моей среде разработки уникальный и неизменный IP-адрес хоста.

В моем nginx.conf для обратного прокси у меня есть proxy_pass http://myapp:8080 где myapp будет именем контейнера докеров, которое я даю прокси-приложению.

Затем я создаю определяемую пользователем мостовую сеть:

docker network create -d bridge myapp-net

Я пока не понимаю, почему сеть моста докеров по умолчанию не работает.

А потом запускаю контейнеры, прикрепляя их к myapp-net:

docker run -p 8080:8080 --network=myapp-net --name myapp --rm myregistry:11095/myapp

docker run -p 10040:443 --network=myapp-net --name rproxy --rm myregistry:11095/myapp-rproxy

и это работает.

Я работаю на своей рабочей станции Windows, и я решил записать настоящее полное доменное имя внешнего хоста в nginx.conf потребуется новое определение среды для каждой рабочей станции, но с myapp вместо этого в файле conf он удаляет зависимость от имени хоста или IP.