如何使用Docker将nginx设置为反向代理

时间:2020-03-05 15:31:15  来源:igfitidea点击:

反向代理服务器是一个服务器,其通常在专用网络中的防火墙后面将其定位,并代表来自一个或者多个服务器的客户端检索资源。
反向代理提供了像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>