111: conexão recusou proxy nginx para contêineres Docker

  • CentOS 7

Eu tenho um contêiner Docker proxy Nginx simples ouvindo na porta 80. Aqui está o Dockerfile:

FROM centos:7MAINTAINER Brian Ogden# Not currently being used but may come in handyARG ENVIRONMENTRUN 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 needRUN rm -f /etc/nginx/conf.d/default.confCOPY /conf/proxy.conf /etc/nginx/conf.d/proxy.confCOPY /conf/nginx.conf /etc/nginx/nginx.confCMD ["nginx"]

E para este Proxy Nginx aqui está o meu 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;}

E aqui está minha configuração de proxy:

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;    }}

Minha configuração de proxy está ouvindo na porta 80 e tentando solicitar solicitações de account.staging.mysite.com para um contêiner Docker em execução no mesmo host Docker que o proxy Ngnix escuta na porta 5023.

Aqui está o meu docker-compose.yml para o meu proxy Nginx:

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

Aqui está o docker-compose.yml para este contêiner Docker ouvindo na porta 5023: versão: '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"

O Dockerfile realmente não importa muito para a minha pergunta, mas aqui está de qualquer maneira:

FROM tsl.devops.dotnetcore.base.image:2MAINTAINER Brian OgdenWORKDIR /appCOPY ./src/Tsl.Example/bin/Release/netcoreapp2.0/publish .ENTRYPOINT ["dotnet", "Tsl.Example.dll"]

Eu segui exemplo para configurar meu proxy.

Eu já fiz uma pergunta relacionada em fóruns Stackexchange aqui e aqui. Esta pergunta eu refinei e simplifiquei o cenário para um simplesmente proxy encaminhando uma solicitação para um contêiner Docker ouvindo na porta 5023.

Como minha imagem base é CentOS, segui isto aqui para certificar-se de SELinux está permitindo para a frente ao porto 5023

Graças a isso pergunta e resposta here, Eu era capaz de perceber que eu tinha dois problemas acontecendo:

  1. os contêineres têm redes Docker padrão diferentes porque estou usando dois docker-compose diferentes.arquivos yml, eu imaginei meu proxy Ngnix funcionando independentemente de qualquer um dos meus contêineres de API inteiramente, incluindo o docker-compose, mais sobre esse problema abaixo
  2. o segundo problema é simplesmente quando tentei proxy para 127.0.0.1: 5023 que é localhost dentro do contêiner Ngnix, não a rede fora do contêiner proxy Nginx

Portanto, as diferentes redes padrão que estão sendo criadas pelo docker-compose para meu contêiner Docker proxy Nginx e meu contêiner Docker api são porque estou divertindo dois docker-compose diferentes.arquivos yml. Isso ocorre porque tenho compilações Jenkins para muitos microsserviços de API, então tenho arquivos docker-compose independentes e precisava de um proxy Nginx para encaminhar solicitações na porta 80 para cada microsserviço.

Para testar isso, criou um docker-compose.yml para ambos os contêineres, a API e o proxy 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

Sim, ainda havia um problema, a passagem do proxy para http//:127.0.0.1: 5023, que forward permanece no contêiner do Docker do Nginx e nunca encontra a API em execução no host do Docker, eu simplesmente precisava usar o docker-compose.nome do serviço yml para chegar a ele:

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;    }}

Eu tive esse problema, mas meu problema era que eu tinha duas pastas que tinham docker-compose.arquivos yml que ambos tinham um serviço chamado 'web'. Mudei o nome de um dos serviços.

A imagem completa para ajudar alguém lutando com redes docker tanto quanto eu era(sou?):

Os projetos Docker-compose costumam usar o nginx como proxy reverso para rotear o tráfego http para os outros serviços do docker. nginx foi um serviço no meu projectfolder/docker-compose.yml que estava conectado a duas redes docker.

Uma foi a rede padrão criada quando usei docker-compose em projectfolder/docker-compose.yml (É nomeado projectfolder_default e os Serviços se conectam a ele por padrão, a menos que você tenha um networks propriedade para o seu serviço com outra rede e, em seguida, certifique-se de adicionar - default para a lista). Quando eu corri docker network ls Eu vi projectfolder_default na lista e quando eu corri docker network inspect projectfolder_default Eu vi o contêiner nginx, então tudo estava bom.

A outra era uma rede chamada my_custom_network que eu mesmo montei. Eu tinha um script de inicialização que o criou se não existisse usando https://stackoverflow.com/a/53052379/13815107 Eu precisava disso para falar com o web serviço em otherproject/docker-compose.yml. Eu tinha adicionado corretamente my_custom_network para:

  • nginx lista de redes do serviço de projectfolder/docker-compose.yml
  • fundo do projectfolder/docker-compose.yml
  • web redes do serviço em otherproject/docker-compose.yml
  • fundo do otherproject/docker-compose.yml

A rede apareceu e tinha os contêineres certos usando docker network ls e docker network inspect my_custom_network

No entanto, presumi que chamar http://web mapearia para o serviço docker web.projectfolder_default. Estava enganado. Eu abri o shell no contêiner nginx (docker exec -it nginx sh). Quando eu usei ping web (pode ser necessário apt-get update, apt-get install iputils-ping) foi bem-sucedido, mas imprimiu um url com my_custom_network foi assim que descobri o erro.

projectfolder / 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

otherproject / 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

projectfolder/.../ nginx / servidor.conf.modelo (ao lado de 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;    }}