Nginx

111:連接拒絕 Docker 容器的 nginx 代理

  • December 2, 2021
  • CentOS 7

我有一個簡單的 Nginx 代理 Docker 容器在埠 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 請求到與在埠 5023 上偵聽的 Ngnix 代理在同一 Docker 主機上執行的 Docker 容器。

這是我的 Nginx 代理的 docker-compose.yml:

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

這是 Docker 容器在埠 5023 上偵聽的 docker-compose.yml:版本:‘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 論壇上問過一個相關問題。這個問題我已經改進並簡化了場景,將請求轉發到一個偵聽埠 5023 的 Docker 容器。

由於我的基本映像是 CentOS,因此我在此處遵循此操作以確保 SELinux 允許轉發到埠 5023

感謝這個問題和答案here,我能夠意識到我遇到了兩個問題:

  1. 容器具有不同的預設 Docker 網路,因為我使用了兩個不同的 docker-compose.yml 文件,我曾設想我的 Ngnix 代理完全獨立於我的任何 API 容器(包括 docker-compose)工作,更多關於該問題的內容如下
  2. 第二個問題只是當我嘗試代理到 127.0.0.1:5023 時,它是 Ngnix 容器內的 localhost,而不是 Nginx 代理容器外的網路

因此,docker-compose 為我的 Nginx 代理 docker 容器和我的 api docker 容器創建的不同預設網路是因為我使用了兩個不同的 docker-compose.yml 文件。這是因為我為許多 API 微服務建構了 Jenkins,因此它們具有獨立的 docker-compose 文件,並且我需要一個 Nginx 代理來將埠 80 上的請求轉發到每個微服務。

為了測試這一點,為兩個容器、API 和 Nginx 代理創建了一個 docker-compose.yml:

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,轉發保留在 Nginx Docker 容器中,並且永遠找不到在 Docker 主機上執行的 API,我只需要使用 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;
   }
}

引用自:https://serverfault.com/questions/895789