如何使用Docker将nginx设置为反向代理
反向代理服务器是一个服务器,其通常在专用网络中的防火墙后面将其定位,并代表来自一个或者多个服务器的客户端检索资源。
反向代理提供了像SSL终端,负载均衡,请求路由,缓存,压缩等的添加抽象级别。
它还提供了控制,以确保客户端和服务器之间的流畅流动流畅。
在本教程中,我们将在NGINX中设置一个反向代理,该代理将为两个上游服务器提供服务器,所有内部都在Docker内部。
设置
我们的设置包括三个容器,两个上游服务器的两个容器和一个用于反向代理的容器。
客户端请求将由代理拦截并将其转发到上游。
内部容器,端口和IP是私有的,除非它们绑定到主机,否则无法在外部访问。
因此,只有一个容器可以绑定到Docker主机的端口80。
那么如何通过Docker主机的端口80访问多个容器上运行的多个Web应用程序?
答案是通过反向代理的,我们将在容器内使用Nginx反向代理,该容器将其端口80绑定到Docker主机的端口80并将请求转发到运行多个容器的Web应用程序。
安装Web服务
由于我们将为两个Web服务设置两个容器,因此它们中的每一个都将拥有自己的Docker-Composer。
YML,一个用于Site1,另一个用于Site2.
请记住,这些Web服务将不会绑定到任何外部端口,通过反向代理将与外界的通信。
对于本教程,这些Web服务将使用nginx返回一个简单HTML,尽管它也可以是PHP/JSP/Python应用程序。
此外,我们将使用名称站点1连接这两个Web服务。
测试和site2.
测试
让我们为WebService1创建文件夹和文件:对于Site1
Site1├──Docker-Compose。
yml└──指数。
HTML.
root@demohost:~# cd ~ root@demohost:~# mkdir site1 root@demohost:~# cd site1 root@demohost:~/site1# vi docker-compose.yml version: '2' services: app: image: nginx:1.9 volumes: - .:/usr/share/nginx/html/ expose: - "80"
为Web服务创建索引文件1
root@demohost:~/site1# vi index.html <!DOCTYPE html> <html> <head> <title>Site 1</title> </head> <body> <h1>This is a sample "site1" response</h1> </body> </html>
Docker撰写。
YML非常直接。
此Web服务是"App"服务,并将提取Nginx版本1. 9.
从Docker主机的Site1根源安装到/usr/share/nginx/html/html /并暴露端口80.使用以下命令构建Web服务1.
root@demohost:~/site1# docker-compose build
现在开始用于服务的容器。
root@demohost:~/site1# docker-compose up -d
列出容器
root@demohost:~# docker ps -a
类似地创建第二个容器:Web服务2
site2├──Docker组成。
yml└──指数。
HTML.
root@demohost:~# cd ~ root@demohost:~# mkdir site2 root@demohost:~# cd site2 root@demohost:~/site2# vi docker-compose.yml version: '2' services: app: image: nginx:1.9 volumes: - .:/usr/share/nginx/html/ expose: - "80"
为Web服务创建索引文件2
root@demohost:~/site2# vi index.html <!DOCTYPE html> <html> <head> <title>Site 2</title> </head> <body> <h1>This is a sample "site2" response</h1> </body> </html>
使用以下命令构建Web服务2.
root@demohost:~/site2# docker-compose build
现在开始用于服务的容器。
root@demohost:~/site2# docker-compose up -d
列出容器
root@demohost:~# docker ps -a
设置代理
既然两个Web服务都在容器中启动并运行,我们继续在容器内配置反向代理。
我们将首先创建代理的文件夹和文件。
Proxy /├──后端找不到。
HTML├──默认。
conf├──Docker组成。
yml├──dockerfile├──包括│├──代理。
conf│└──ssl。
conf└──ssl├──site1.
CRT├──Site1.
关键├──Site2.
crt└──site2.
钥匙
root@demohost:~# mkdir proxy root@demohost:~# cd proxy/ root@demohost:~/proxy# touch Dockerfile root@demohost:~/proxy# touch backend-not-found.html root@demohost:~/proxy# touch default.conf root@demohost:~/proxy# touch docker-compose.yml root@demohost:~/proxy# mkdir includes root@demohost:~/proxy# mkdir ssl root@demohost:~/proxy# cd ../includes root@demohost:~/proxy/includes# touch proxy.conf root@demohost:~/proxy/includes# touch ssl.conf
使用以下内容编辑dockerfile
root@demohost:~/proxy# vi Dockerfile FROM nginx:1.9 # default conf for proxy service COPY ./default.conf /etc/nginx/conf.d/default.conf # NOT FOUND response COPY ./backend-not-found.html /var/www/html/backend-not-found.html # Proxy and SSL configurations COPY ./includes//etc/nginx/includes/ # Proxy SSL certificates COPY ./ssl//etc/ssl/certs/nginx/
编辑后端 - 找不到。
HTML.
root@demohost:~/proxy# vi backend-not-found.html <html> <head><title>Proxy Backend Not Found</title></head> <body > <h2>Proxy Backend Not Found</h2> </body> </html>
编辑默认值。
conf
root@demohost:~/proxy# vi default.conf # web service1 config. server { listen 80; listen 443 ssl http2; server_name site1.test; # Path for SSL config/key/certificate ssl_certificate /etc/ssl/certs/nginx/site1.crt; ssl_certificate_key /etc/ssl/certs/nginx/site1.key; include /etc/nginx/includes/ssl.conf; location/{ include /etc/nginx/includes/proxy.conf; proxy_pass http://site1_app_1; } access_log off; error_log /var/log/nginx/error.log error; } # web service2 config. server { listen 80; listen 443 ssl http2; server_name site2.test; # Path for SSL config/key/certificate ssl_certificate /etc/ssl/certs/nginx/site2.crt; ssl_certificate_key /etc/ssl/certs/nginx/site2.key; include /etc/nginx/includes/ssl.conf; location/{ include /etc/nginx/includes/proxy.conf; proxy_pass http://site2_app_1; } access_log off; error_log /var/log/nginx/error.log error; } # Default server { listen 80 default_server; server_name _; root /var/www/html; charset UTF-8; error_page 404 /backend-not-found.html; location = /backend-not-found.html { allow all; } location/{ return 404; } access_log off; log_not_found off; error_log /var/log/nginx/error.log error; }
在nginx配置中,两个Web服务中的每一个都有自己的服务器块。
此块指示nginx将请求传递给相应的Web服务应用程序容器,它们是Site1_App_1和Site2_App_1.
在Docker PS-A的输出中找到此名称在名称列下。
proxy_intercept_errors选项设置为ON,以便从Web Apps容器本身而不是默认的nginx响应中的nginx返回错误。
SSL配置/键/证书的路径指示Nginx从何处挑选这些文件。
编辑docker组件。
yml.
version: '2' services: proxy: build: ./ networks: - site1 - site2 ports: - 80:80 - 443:443 networks: site1: external: name: site1_default site2: external: name: site2_default
上面的Docker组合。
yml将创建一个代理服务,并连接到两个外部网络即我们的两个Web服务。
这是由于代理服务需要连接到这些外部网络的代理从Web服务Docker容器接收的请求。
Port No 80/443的Proxy Service的绑定是对Docker主机的端口80/443完成的。
两个外部Web服务/容器的名称是Site1_default和site2_default。
为SSL文件夹中的Web服务生成证书和密钥。
适用于Site1.
root@demohost:~/proxy# cd ssl root@demohost:~/proxy/ssl# sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout site1.key -out site1.crt Generating a 2048 bit RSA private key ..........................+++ ..............+++ writing new private key to 'site1.key' ----
对于Site2.
root@demohost:~/proxy/ssl# sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout site2.key -out site2.crt Generating a 2048 bit RSA private key ....................+++ ..........................................+++ writing new private key to 'site2.key' ----
编辑代理。
confine包括目录。
root@demohost:~/proxy/includes# vi proxy.conf 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_buffering off; proxy_request_buffering off; proxy_http_version 1.1; proxy_intercept_errors on;
编辑内部的SSL配置包含文件夹
root@demohost:~/proxy/includes# vi ssl.conf ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256 GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA AES128-SHAECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256 SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256: DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256: AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES CBC3-SHA:!DSS'; ssl_prefer_server_ciphers on;
对于两个Web服务的名称解析,请在/etc/hosts中添加以下两行
root@demohost:~/proxy# vi /etc/hosts 172.31.30.78 site1.test 172.31.30.78 site2.test
上述IP地址是Docker-Host的私有IP。
请记住,客户端的请求将到达Dockerhost的端口80,该端口将被映射到Nginx容器的端口80。
构建代理容器
root@demohost:~/proxy# docker-compose build Building proxy Step 1 : FROM nginx:1.9 ---> c8c29d842c09 Step 2 : COPY ./default.conf /etc/nginx/conf.d/default.conf ---> Using cache ---> 4c459326c3a2 Step 3 : COPY ./backend-not-found.html /var/www/html/backend-not-found.html ---> Using cache ---> e3d817f5fb8e Step 4 : COPY ./includes//etc/nginx/includes/ ---> Using cache ---> 0c5ca9eb16d8 Step 5 : COPY ./ssl//etc/ssl/certs/nginx/ ---> Using cache ---> 92007e83d405 Successfully built 92007e83d405
运行代理容器
root@demohost:~/proxy# docker-compose up -d Building proxy Step 1 : FROM nginx:1.9 ---> c8c29d842c09 Step 2 : COPY ./default.conf /etc/nginx/conf.d/default.conf ---> 4c459326c3a2 Removing intermediate container 86c1ea72022e Step 3 : COPY ./backend-not-found.html /var/www/html/backend-not-found.html ---> e3d817f5fb8e Removing intermediate container 51b12caded59 Step 4 : COPY ./includes//etc/nginx/includes/ ---> 0c5ca9eb16d8 Removing intermediate container 66f2c8dd0d56 Step 5 : COPY ./ssl//etc/ssl/certs/nginx/ ---> 92007e83d405 Removing intermediate container 29bca9e3ba0a Successfully built 92007e83d405 Creating proxy_proxy_1
现在列出所有正在运行的容器。
root@demohost:~/# docker ps -a
上面的命令将列出所有三个容器。
要验证,我们已正确设置反向代理,请使用CURL从Docker主机的两个Web服务获取响应。
root@demohost:~/proxy# curl site1.test <!DOCTYPE html> <html> <head> <title>Site1</title> </head> <body> <h1>This is a sample "Site1" response</h1> </body> </html> root@demohost:~/proxy# curl site2.test <!DOCTYPE html> <html> <head> <title>Site2</title> </head> <body> <h1>This is a sample "Site2" response</h1> </body> </html>