轉自:https://www.jianshu.com/p/1cf84a27de0fhtml
緊接上篇.NET Core容器化@Docker,這一節咱們先來介紹如何使用Nginx來完成.NET Core應用的反向代理,而後再介紹多容器應用的部署問題。nginx
.NET Core中默認的Web Server爲Kestrel。git
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.github
Kestrel能夠很好的用來爲ASP.NET提供動態內容,然而在Web服務方面沒有IIS、Apache、Nginx這些全功能的服務器完善。咱們能夠藉助一個反向代理服務器接收來自互聯網的HTTP請求並在通過一些初步處理(好比請求的緩存和壓縮、提供靜態內容、SSL Termination)後將其轉發給Kestrel。web
藉助反向代理服務器(本文使用Nginx),不只能夠給咱們的Web網站提供了一個可選的附加層配置和防護,並且能夠簡化負載均衡和SSL設置。而更重要的是,反向代理服務器能夠很好的與現有的基礎設施進行整合。docker
一樣咱們仍是基於Docker來試玩一下Nginx。json
//拉取Nginx鏡像 $ docker pull nginx //啓動Nginx容器 $ docker run -d -p 8080:80 --name hellonginx nginx
上面咱們之後臺運行的方式啓動了一個命名爲hellonginx的nginx容器,其端口映射到宿主機的8080端口,咱們如今能夠經過瀏覽器直接訪問http://<ip address>:8080
便可看到nginx的歡迎界面。
瀏覽器
至此,一個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
啓動成功後,咱們再在瀏覽器中訪問http://<ipaddress>:8080
,發現返回的再也不是Nginx的默認歡迎頁,而是咱們啓動的Web容器中運行的MVC的首頁,說明反向代理配置成功!
上面的步驟雖然簡單,但要分兩步進行:第一個就是咱們的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
,即以咱們當前項目目錄來構建鏡像並啓動一個叫hellodocker.web.compose
的容器。一個是reverse-proxy
,用來使用nginx鏡像進行反向代理,其中又經過指定volumes
來使用掛載的方式進行配置。
$ 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]#
其中要注意反向代理的配置:proxy_pass http://hellodocker-web:5000;
,其中ip部分直接指定的是docker-compose.yml中定義的第一個服務的名稱hellodocker-web
。
下面咱們就來啓動Compose:
$ 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
驗證代理服務器配置成功,咱們再經過瀏覽器訪問http://<ip address>:9090
發現正確返回了咱們MVC項目的默認首頁。
// 查看當前運行的容器 $ 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
正確的建立了兩個容器hellodocker.web.compose
和reverse-proxy
。
通過以上的練習,咱們對Nginx有了必定的瞭解,且知道如何進行配置。同時瞭解瞭如何藉助docker-compose打包運行須要多容器的複雜應用。
本篇就先講到這裏,下一篇咱們介紹如何在Linux上玩耍MySql並打通Nginx+Web+MySql的容器化部署。