紧接上篇 .NET Core 容器化 @Docker ,这一节我们先来介绍如何使用 Nginx 来完成. NET Core 应用的反向代理,然后再介绍多容器应用的部署问题。
.NET Core 中默认的 web Server 为 Kestrel。
Kestrel is great for serving dynamic content from ASP.NET, however the web serving parts aren't as feature rich as full-featured servers like IIS, Apache or Nginx. A reverse proxy-server can allow you to offload work like serving static content, caching requests, compressing requests, and SSL termination from the HTTP server.
Kestrel 可以很好的用来为 ASP.NET 提供动态内容,然而在 Web 服务方面没有 IIS、Apache、Nginx 这些全功能的服务器完善。我们可以借助一个反向代理服务器接收来自互联网的 HTTP 请求并在经过一些初步处理(比如请求的缓存和压缩、提供静态内容、SSL Termination)后将其转发给 Kestrel。
借助反向代理服务器(本文使用 Nginx),不仅可以给我们的 Web 网站提供了一个可选的附加层配置和防御,而且可以简化负载均衡和 SSL 设置。而更重要的是,反向代理服务器可以很好的与现有的基础设施进行整合。
同样我们还是基于 Docker 来试玩一下 Nginx。
- //拉取Nginx镜像
- $ docker pull nginx
- //启动Nginx容器
- $ docker run - d - p 8080 : 80--name hellonginx nginx
上面我们以后台运行的方式启动了一个命名为 hellonginx 的 nginx 容器,其端口映射到宿主机的 8080 端口,我们现在可以通过浏览器直接访问
即可看到 nginx 的欢迎界面。
- http://<ip address>:8080
至此,一个 Nginx 容器就启动完毕了。那如何进行反向代理呢?别急,我们一步一步来。
还记得我们上一篇本地打包 MVC 项目创建的 hellodocker.web 的镜像吗?这里我们再启动该镜像创建一个容器:
- //启动一个helodocker.web的镜像并命名容器为hellodocker.web.nginx
- # docker run -d -p 5000:5000 --name hellodocker.web.nginx hellodocker.web
- 160166b3556358502a366d1002567972e242f0c8be3a751da0a525f86c124933
- //尝试访问刚刚运行的容器
- [root@iZ288a3qazlZ ~]# curl -I http://localhost:5000
- HTTP/1.1 200 OK
- Date: Sun, 24 Dec 2017 02:48:16 GMT
- Content-Type: text/html; charset=utf-8
- Server: Kestrel
- Transfer-Encoding: chunked
OK,我们开放了宿主机的 5000 端口用来映射我们启动的 MVC 容器。
下面我们就来配置 Nginx 来反向代理我们刚启动的 Web 容器。
要想 Nginx 成功代理指定的容器内运行的 Web 网站,首先我们得知道容器对应的 IPAddress。使用
即可查到。
- docker inspect <container id/name>
- //查看正在运行的容器列表
- $ docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- d046b7b878a0 hellodocker.web "dotnet run" 5 seconds ago Up 3 seconds 0.0.0.0:5000->5000/tcp hellodocker.web.nginx
- //使用`|`管道操作符加上`grep`过滤操作符可以直接提取我们要查找的关键字
- $ docker inspect hellodocker.web.nginx | grep IPAddress
- "SecondaryIPAddresses": null,
- "IPAddress": "192.168.0.5",
- "IPAddress": "192.168.0.5",
从上面可以看到我的 Web 容器运行在宿主机的 192.168.0.5:5000。下面我们配置 Nginx 转发请求到 192.168.0.5:5000 即可完成反向代理。
Nginx 配置反向代理的配置文件路径为:/etc/nginx/conf.d/default.conf。
我们可以通过本地创建一个配置文件挂载到 Nginx 的容器内部进行反向代理配置。
- $ cd demo
- $ mkdir nginx
- //创建my_nginx.conf文件
- $ touch my_nginx.conf
- $ vi my_nginx.conf
- server {
- listen 80;
- location / {
- proxy_pass http://192.168.0.5:5000;
- }
- }
上面我们通过指定 listen 配置 nginx 去监听 80 端口,指定 proxy_pass 为我们 Web 容器的 IP 和端口完成反向代理文件的配置。
接下来就是启动一个新的 Nginx 容器并通过挂载的方式将配置文件共享到容器内部。
- $ docker run -d -p 8080:80 \
- > -v $HOME/demo/nginx/my_nginx.conf:/etc/nginx/conf.d/default.conf \
- > nginx
- 95381aa56a336f65b6d01ff9964ae3364f37d25e5080673347c1878b3a5bb514
- /usr/bin/docker-current: Error response from daemon: driver failed programming external connectivity on endpoint elated_mccarthy (5a576d5991dd164db69b1c568c94c15e47ec7c67e43a3dd6982a2e9b83b60e08): Bind for 0.0.0.0:8080 failed: port is already allocated.
我们发现容器启动失败,原因是 8080 端口被我们刚刚第一次启动的 nginx 容器占用了。怎么办?两个方法:第一种就是将刚才创建的 nginx 容器干掉;第二种就是映射到新的端口。这里选择第一种。
- $ docker ps
- 1bd630b60019 nginx "nginx -g 'daemon off" 59 minutes ago Up 59 minutes 0.0.0.0:8080->80/tcp hellonginx
- //使用docker rm <container id>删除容器,指定-f进行强制删除
- $ docker rm 1bd630b60019 -f
- //重新启动Nginx容器
- $ docker run -d -p 8080:80 \
- > -v $HOME/demo/nginx/my_nginx.conf:/etc/nginx/conf.d/default.conf \
- > nginx
- 793d4c62ec8ac4658d75ea0ab4273a0b1f0a9a68f9708d2f85929872888b121d
启动成功后,我们再在浏览器中访问
,发现返回的不再是 Nginx 的默认欢迎页,而是我们启动的 Web 容器中运行的 MVC 的首页,说明反向代理配置成功!
- http://<ipaddress>:8080
上面的步骤虽然简单,但要分两步进行:第一个就是我们的 Web 和 Nginx 要分两次部署,第二个就是我们必须知道 Web 容器的 IP 和端口号,以完成反向代理文件的配置。
对于需要多个容器(比如需要 Nginx、SqlServer、Redis、RabbitMQ 等)协调运行的复杂应用中,使用以上方式进行部署时,很显然会很麻烦,而且还要为各个容器之间的网络连接而苦恼。
还好,Docker 体贴的为我们想到了这一点。借助 Compose 模块,我们可以编写一个 docker-compose.yml 文件,使用声明性语法启动一系列相互连接的容器,即可一步完成上面的任务。
Docker Compose 是一个用来定义和运行复杂应用的 Docker 工具。使用 Compose,你可以在一个文件中定义一个多容器应用,然后使用一条命令来启动你的应用,完成一切准备工作。
依次执行以下命令:
- $ sudo curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
- $ sudo chmod +x /usr/local/bin/docker-compose
- $ docker-compose --version
- docker-compose version 1.18.0, build 1719ceb
dockers-compose.yml 文件要定义在我们项目的文件夹下,我们的项目文件夹位于
。
- $HOME/demo/HelloDocker.Web
- $ cd $HOME/demo/HelloDocker.Web
- $ touch docker-compose.yml
- $ vi docker-compose.yml
- version: '2'
- services:
- hellodocker-web:
- container_name: hellodocker.web.compose
- build: .
- reverse-proxy:
- container_name: reverse-proxy
- image: nginx
- ports:
- - "9090:8080"
- volumes:
- - ./proxy.conf:/etc/nginx/conf.d/default.conf
简单介绍下上面的配置文件,其中定义了两个服务:一个是 hellodocker-web,即以我们当前项目目录来构建镜像并启动一个叫
的容器。一个是 reverse-proxy,用来使用 nginx 镜像进行反向代理,其中又通过指定 volumes 来使用挂载的方式进行配置。
- hellodocker.web.compose
- $ touch proxy.conf
- $ vi proxy.conf
- server {
- listen 8080;
- location / {
- proxy_pass http://hellodocker-web:5000;
- }
- }
- $ ls
- [root@iZ288a3qazlZ HelloDocker.Web]# ls
- appsettings.Development.json Controllers Models Startup.cs
- appsettings.json docker-compose.yml obj Views
- bin Dockerfile Program.cs wwwroot
- bundleconfig.json HelloDocker.Web.csproj proxy.conf
- [root@iZ288a3qazlZ HelloDocker.Web]#
其中要注意反向代理的配置:
,其中 ip 部分直接指定的是 docker-compose.yml 中定义的第一个服务的名称 hellodocker-web。 下面我们就来启动 Compose:
- proxy_pass http://hellodocker-web:5000;
- $ docker-compose up -d
- Building hellodocker-web
- Step 1 : FROM microsoft/dotnet:latest
- ---> 7d4dc5c258eb
- Step 2 : WORKDIR /app
- ---> Using cache
- ---> 98d48a4e278c
- Step 3 : COPY . /app
- ---> 0cb9fc540afe
- Removing intermediate container 9fecf088f03f
- Step 4 : RUN dotnet restore
- ---> Running in 4bb7f34edbbe
- Restore completed in 597.13 ms for /app/HelloDocker.Web.csproj.
- Restoring packages for /app/HelloDocker.Web.csproj...
- Restore completed in 1.76 sec for /app/HelloDocker.Web.csproj.
- ---> 6869609ece23
- Removing intermediate container 4bb7f34edbbe
- Step 5 : EXPOSE 5000
- ---> Running in a97febf01e5a
- ---> 9b2639862a94
- Removing intermediate container a97febf01e5a
- Step 6 : ENV ASPNETCORE_URLS http://*:5000
- ---> Running in 4e2f4af28a8d
- ---> 0069661e891a
- Removing intermediate container 4e2f4af28a8d
- Step 7 : ENTRYPOINT dotnet run
- ---> Running in cbbf08d906f9
- ---> 0bbeef249b30
- Removing intermediate container cbbf08d906f9
- Successfully built 0bbeef249b30
- WARNING: Image for service hellodocker-web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
- Creating hellodocker.web.compose ... done
- Starting reverse-proxy ... done
- //执行docker-compose ps验证启动的服务
- $ docker-compose ps
- Name Command State Ports
- ---------------------------------------------------------------------------------------
- hellodocker.web.compose dotnet run Up 5000/tcp
- reverse-proxy nginx -g daemon off; Up 80/tcp, 0.0.0.0:9090->8080/tcp
- //使用curl指令验证nginx的反向代理
- $ curl -I http://localhost:9090
- HTTP/1.1 200 OK
- Server: nginx/1.13.7
- Date: Sun, 24 Dec 2017 04:37:35 GMT
- Content-Type: text/html; charset=utf-8
- Connection: keep-alive
可以看到,通过执行
验证代理服务器配置成功,我们再通过浏览器访问
- curl -I http://localhost:9090
发现正确返回了我们 MVC 项目的默认首页。
- http://<ip address>:9090
- // 查看当前运行的容器
- $ docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- a52830499cff hellodockerweb_hellodocker-web "dotnet run" 7 minutes ago Up 7 minutes 5000/tcp hellodocker.web.compose
- e1fe109e10bc nginx "nginx -g 'daemon off" 11 minutes ago Up 4 minutes 80/tcp, 0.0.0.0:9090->8080/tcp reverse-proxy
我们同时也发现通过 docker-compose 正确的创建了两个容器
和 reverse-proxy。
- hellodocker.web.compose
经过以上的练习,我们对 Nginx 有了一定的了解,且知道如何进行配置。同时了解了如何借助 docker-compose 打包运行需要多容器的复杂应用。
本篇就先讲到这里,下一篇我们介绍如何在 Linux 上玩耍 MySql 并打通 Nginx+Web+MySql 的容器化部署。
来源: https://www.cnblogs.com/sheng-jie/p/8116276.html