111:連接拒絕 Docker 容器的 nginx 代理
- 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,我能夠意識到我遇到了兩個問題:
- 容器具有不同的預設 Docker 網路,因為我使用了兩個不同的 docker-compose.yml 文件,我曾設想我的 Ngnix 代理完全獨立於我的任何 API 容器(包括 docker-compose)工作,更多關於該問題的內容如下
- 第二個問題只是當我嘗試代理到 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; } }