111: koneksi menolak proxy nginx untuk kontainer Docker

  • CentOS 7

Saya memiliki wadah Docker proxy Nginx sederhana yang mendengarkan pada port 80. Berikut adalah 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"]

Dan untuk Proxy Nginx ini di sini adalah nginx saya.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;}

Dan inilah konfigurasi proxy saya:

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

Konfigurasi proxy saya mendengarkan pada port 80 dan mencoba meminta permintaan dari account.staging.mysite.com ke wadah Docker yang berjalan pada Host Docker yang sama dengan proxy Ngnix yang mendengarkan pada port 5023.

Ini adalah docker-compose saya.yml untuk proxy Nginx saya:

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

Berikut adalah docker-compose.yml untuk wadah Docker ini mendengarkan pada port 5023: versi: '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 tidak terlalu penting untuk pertanyaan saya, tetapi ini dia:

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

Saya mengikuti contoh ini untuk setup proxy saya.

Saya sebelumnya telah mengajukan pertanyaan terkait di forum Stackexchange di sini dan di sini. Pertanyaan ini saya telah disempurnakan dan disederhanakan skenario untuk hanya proxy forwarding permintaan untuk satu kontainer Docker mendengarkan pada port 5023.

Karena gambar dasar saya adalah CentOS, saya telah mengikuti ini di sini untuk memastikan SELinux memungkinkan maju ke port 5023

Berkat ini pertanyaan dan jawaban di sini, Saya dapat menyadari bahwa saya memiliki dua masalah yang terjadi:

  1. wadah memiliki jaringan Docker default yang berbeda karena saya menggunakan dua docker-compose yang berbeda.file yml, saya telah membayangkan proxy Ngnix saya bekerja secara independen dari salah satu wadah api saya sepenuhnya, termasuk docker-compose, lebih lanjut tentang masalah di bawah ini
  2. masalah kedua adalah ketika saya mencoba proxy ke 127.0.0.1: 5023 yaitu localhost di dalam wadah Ngnix, bukan jaringan di luar wadah proxy Nginx

Jadi jaringan default berbeda yang dibuat oleh docker-compose untuk wadah docker proxy Nginx saya dan wadah docker api saya adalah karena saya menghibur dua docker-compose yang berbeda.berkas yml. Ini karena saya memiliki Jenkins Build untuk banyak layanan mikro API sehingga memiliki file Docker-compose independen dan saya memerlukan proxy Nginx untuk meneruskan permintaan pada port 80 ke setiap layanan mikro.

Untuk menguji ini, buat docker-compose.yml untuk kedua kontainer, API dan 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

Ya masih ada masalah, proxy lolos ke http//: 127.0.0.1: 5023, penerusan itu tetap ada di wadah Docker Nginx dan tidak pernah menemukan API berjalan di host Docker, saya hanya perlu menggunakan docker-compose.nama layanan yml untuk sampai ke sana:

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

Saya memiliki masalah ini tetapi masalah saya adalah saya memiliki dua folder yang keduanya memiliki docker-compose.file yml yang keduanya memiliki layanan bernama 'web'. Saya mengubah nama salah satu layanan.

Gambaran lengkap untuk membantu seseorang yang berjuang dengan jaringan docker sebanyak saya (am?):

Proyek Docker-compose sering menggunakan nginx sebagai reverse-proxy untuk merutekan lalu lintas http ke layanan docker lainnya. nginx adalah layanan di saya projectfolder/docker-compose.yml yang terhubung ke dua jaringan docker.

Salah satunya adalah jaringan default yang dibuat ketika saya menggunakan docker-compose up on projectfolder/docker-compose.yml (Hal ini bernama projectfolder_default dan layanan terhubung ke secara default kecuali Anda memiliki networks properti untuk layanan Anda dengan jaringan lain, maka pastikan Anda menambahkan - default ke Daftar). Ketika saya berlari docker network ls Aku melihat projectfolder_default dalam daftar dan ketika saya berlari docker network inspect projectfolder_default Saya melihat wadah nginx, jadi semuanya baik-baik saja.

Yang lain adalah jaringan yang disebut my_custom_network bahwa saya mengatur diri saya sendiri. Saya memiliki skrip startup yang membuatnya jika tidak ada Menggunakan https://stackoverflow.com/a/53052379/13815107 Aku membutuhkannya untuk berbicara dengan web layanan di otherproject/docker-compose.yml. Saya telah menambahkan dengan benar my_custom_network untuk:

  • nginx daftar jaringan layanan projectfolder/docker-compose.yml
  • bagian bawah projectfolder/docker-compose.yml
  • web jaringan layanan di otherproject/docker-compose.yml
  • bagian bawah otherproject/docker-compose.yml

Jaringan muncul dan memiliki wadah yang tepat menggunakan docker network ls dan docker network inspect my_custom_network

Namun, saya berasumsi bahwa memanggil http://web akan memetakan ke layanan docker web.projectfolder_default. Aku salah. Saya membuka shell pada wadah nginx (docker exec -it nginx sh). Ketika saya menggunakan ping web (mungkin perlu apt-get update, apt-get install iputils-ping) berhasil, tetapi mencetak url dengan my_custom_network begitulah cara saya menemukan kesalahannya.

projectfolder / docker-menulis.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-menulis.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 / server.conf.template (di sebelah 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;    }}