111: в соединении отказано прокси nginx для контейнеров Docker

  • CentOS 7

У меня есть простой Docker-контейнер Nginx, прослушивающий порт 80. Вот Dockerfile:

FROM centos:7
MAINTAINER Brian Ogden

# Not currently being used but may come in handy
ARG ENVIRONMENT

RUN yum -y update && \
    yum clean all && \
    yum -y install http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm \
    yum -y makecache && \
    yum -y install nginx-1.12.0 wget

# Cleanup some default NGINX configuration files we don’t need
RUN rm -f /etc/nginx/conf.d/default.conf


COPY /conf/proxy.conf /etc/nginx/conf.d/proxy.conf
COPY /conf/nginx.conf /etc/nginx/nginx.conf


CMD ["nginx"]

И для этого прокси Nginx вот мой nginx.conf:

daemon off;
user  nginx;
worker_processes  2;

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


events {
    worker_connections  1024;
    use epoll;
    accept_mutex off;
}


http {
    include       /etc/nginx/mime.types;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    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;

    client_max_body_size 300m;
    client_body_buffer_size 300k;
    large_client_header_buffers 8 64k;

    gzip  on;
    gzip_http_version 1.0;
    gzip_comp_level 6;
    gzip_min_length 0;
    gzip_buffers 16 8k;
    gzip_proxied any;
    gzip_types text/plain text/css text/xml text/javascript application/xml application/xml+rss application/javascript application/json;
    gzip_disable "MSIE [1-6]\.";
    gzip_vary on;

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

И вот моя конфигурация прокси:

upstream accountstaging {
    server 127.0.0.1:5023;
}

server {

    listen 80;
    server_name account.staging.mysite.com;

    location / {
        proxy_pass         http://accountstaging;
        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-Host $server_name;
    }
}

Моя конфигурация прокси-сервера прослушивает порт 80 и пытается запросить запросы от account.staging.mysite.com к контейнеру Docker, работающему на том же хосте Docker, что и прокси-сервер Ngnix, прослушивающий порт 5023.

Вот мой docker-compose.yml для моего прокси Nginx:

version: '3'
services:
  reverseproxy:
    build: 
      context: ./
      dockerfile: docker/Dockerfile
    image: tsl.devops.reverseproxy.image
    container_name: tsl.devops.reverseproxy.container
    ports:
      - "80:80"

Вот docker-compose.yml для этого контейнера Docker, прослушивающего порт 5023: версия: '3'

services:
  apistaging:
    build: 
      context: ./
      dockerfile: docker/staging/Dockerfile
    image: tsl.api.example.image
    container_name: tsl.api.example.container
    ports:
      - "127.0.0.1:5023:80"

Dockerfile не имеет большого значения для моего вопроса, но вот он:

FROM tsl.devops.dotnetcore.base.image:2
MAINTAINER Brian Ogden

WORKDIR /app
COPY ./src/Tsl.Example/bin/Release/netcoreapp2.0/publish .

ENTRYPOINT ["dotnet", "Tsl.Example.dll"]

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

Ранее я задавал соответствующий вопрос на форумах Stackexchange здесь и здесь. Этот вопрос я уточнил и упростил сценарий до простого прокси-сервера, перенаправляющего запрос в один контейнер Docker, прослушивающий порт 5023.

Поскольку мой базовый образ - CentOS, я следовал этому здесь, чтобы убедиться, что SELinux разрешает переадресацию на порт 5023

2 ответа

Решение

Благодаря этому вопросу и ответу здесь я смог понять, что у меня есть две проблемы:

  1. контейнеры имеют разные сети Docker по умолчанию, потому что я использую два разных файла docker-compose.yml, я предполагал, что мой прокси-сервер Ngnix будет работать независимо от любого из моих контейнеров API, включая docker-compose, подробнее об этом ниже.
  2. Вторая проблема заключается в том, что я просто пытался прокси-сервер на 127.0.0.1:5023, который является локальным в контейнере Ngnix, а не в сети вне прокси-контейнера Nginx.

Таким образом, разные сети по умолчанию, создаваемые docker-compose для моего прокси-контейнера Nginx и моего api-докера, связаны с тем, что я забавляю два разных файла docker-compose.yml. Это потому, что у меня есть сборки Jenkins для многих микросервисов API, поэтому у меня есть независимые файлы для создания докеров, и мне нужен прокси-сервер Nginx для пересылки запросов на порт 80 каждому микросервису.

Чтобы проверить это, создали docker-compose.yml для обоих контейнеров, API и прокси-сервера Nginx:

version: '3'

services:
  reverseproxy:
    build: 
      context: ./
      dockerfile: docker/nginxproxy/docker/Dockerfile
    image: tsl.devops.reverseproxy.image
    container_name: tsl.devops.reverseproxy.container
    ports:
      - "80:80"
  apistaging:
    build: 
      context: ./
      dockerfile: docker/staging/Dockerfile
    image: tsl.api.example.image
    container_name: tsl.api.example.container
    ports:
      - "5023:5023"
    environment: 
      ASPNETCORE_URLS: http://+:5023

Да, все еще была проблема, передача прокси на http //: 127.0.0.1:5023, что forward остается в контейнере Docker Nginx и никогда не находит API, работающий на хосте Docker, мне просто нужно было использовать docker-compose. имя сервиса yml, чтобы добраться до него:

upstream accountstaging {
    server apistaging:5023;
}

server {

    listen 80;
    server_name account.staging.mysite.com;

    location / {
        proxy_pass         http://accountstaging;
        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-Host $server_name;
    }
}

У меня была эта проблема, но моя проблема заключалась в том, что у меня было две папки, в каждой из которых были файлы docker-compose.yml, в каждой из которых была служба с именем «web». Я изменил название одного из сервисов.

Полная картина, которая поможет кому-то, кто так же борется с докер-сетями, как и я (есть?):

Проекты Docker-compose часто используют nginx в качестве обратного прокси-сервера для маршрутизации http-трафика к другим службам Docker. У меня nginx был сервисом, который был подключен к двум сетям докеров.

Одной из них была сеть по умолчанию, созданная, когда я использовал docker-compose (она имеет имя, и службы подключаются к ней по умолчанию, ЕСЛИ у вас нетnetworksсвойство для вашего сервиса в другой сети, затем обязательно добавьте - defaultв список). Когда я побежал, я увиделprojectfolder_defaultв списке и когда я запустилdocker network inspect projectfolder_defaultЯ видел контейнер nginx, значит, все было хорошо.

Другой была сеть под названием, которую я создал сам. У меня был сценарий запуска, который создавал его, если он не существовал, используя https://stackoverflow.com/a/53052379/13815107 . Он мне нужен был для общения со службой в . Я правильно добавил:

  • nginxсписок сетей сервиса
  • дноprojectfolder/docker-compose.yml
  • webсети сервиса в
  • дноotherproject/docker-compose.yml

Сеть появилась и имела нужные контейнеры, используяdocker network lsиdocker network inspect my_custom_network

Однако я предполагал, что вызов http://web будет соответствовать службе докеров.web.projectfolder_default. Я ошибался. Я открыл оболочку в контейнере nginx (docker exec -it nginx sh). Когда я использовалping web(может понадобитьсяapt-get update,apt-get install iputils-ping) это удалось, но он напечатал URL-адрес сmy_custom_networkвот как я понял ошибку.

папка проекта/docker-compose.yml

        services:
    # http://web did NOT map to this service!! Use http://web.main_default or change the names
    web:
      ... 
    nginx:
        ...
      links:
        - web
      networks:
        - default
        - my_custom_network
    ...
  networks:
    - my_custom_network
      external: true

другойпроект/docker-compose.yml

        services:
    # http://web connected to this service instead. You could use http://web.my_custom_network to call it out instead
    web:
      ... 
      networks:
        - default
        - my_custom_network
    ...
  networks:
    - my_custom_network
      external: true

папка проекта/.../nginx/server.conf.template (рядом с Dockerfile) ...

      server {

    ...

    location /auth {
        internal;
        # This routed to wrong 'web'
        proxy_pass              http://web:9001;
        proxy_pass_request_body off;
        proxy_set_header        Content-Length "";
    }

    location / {
        alias /data/dist/;
    }

    location /robots.txt {
        alias /robots.txt;
    }

    # Project Folder backend
    location ~ ^/(api|login|logout)/ {
        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;
        proxy_connect_timeout 300s;
        proxy_read_timeout 300s;
        # This routed to wrong 'web'
        proxy_pass http://web:9001;
    }

    # Other project UI
    location /other-project {
        alias /data/other-project-client/dist/;
    }

    # Other project Django server
    location ~ ^/other-project/(rest)/ {
        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;
        proxy_connect_timeout 300s;
        proxy_read_timeout 300s;
        # This should work
        proxy_pass http://web.my_custom_network:8000;
    }
}
Другие вопросы по тегам