.NET Core容器化之多容器應用部署(Docker-Compose)
1.引言
緊接上篇.NET Core
容器化@Docker,這一節我們先來介紹如何使用Nginx
來完成.NET Core
應用的反向代理,然後再介紹多容器應用的部署問題。
2. Why Need Nginx
.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
設定。而更重要的是,反向代理伺服器可以很好的與現有的基礎設施進行整合。
3. Hello Nginx
同樣我們還是基於Docker
來試玩一下Nginx
。
//拉取Nginx映象
$ docker pull nginx
//啟動Nginx容器
$ docker run -d -p 8080:80 --name hellonginx nginx
上面我們以後臺執行的方式啟動了一個命名為hellonginx
的nginx
容器,其埠對映到宿主機的8080
埠,我們現在可以通過瀏覽器直接訪問http://<ip address>:8080
即可看到nginx
的歡迎介面。
至此,一個Nginx
容器就啟動完畢了。那如何進行反向代理呢?別急,我們一步一步來。
4. 反向代理.NET Core MVC
4.1. 啟動Web容器
還記得我們上一篇本地打包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
容器。
4.2. 配置反向代理
下面我們就來配置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
的首頁,說明反向代理配置成功!
5. Docker Compose
讓一切更簡單
上面的步驟雖然簡單,但要分兩步進行:第一個就是我們的Web
和Nginx
要分兩次部署,第二個就是我們必須知道Web
容器的IP
和埠號,以完成反向代理檔案的配置。
對於需要多個容器(比如需要Nginx、SqlServer、Redis、RabbitMQ
等)協調執行的複雜應用中,使用以上方式進行部署時,很顯然會很麻煩,而且還要為各個容器之間的網路連線而苦惱。
還好,Docker
體貼的為我們想到了這一點。藉助Compose
模組,我們可以編寫一個docker-compose.yml
檔案,使用宣告性語法啟動一系列相互連線的容器,即可一步完成上面的任務。
Docker Compose
是一個用來定義和執行復雜應用的Docker
工具。使用Compose
,你可以在一個檔案中定義一個多容器應用,然後使用一條命令來啟動你的應用,完成一切準備工作。
5.1. 安裝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
5.2. 編寫第一個docker-compose.yml
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
。
6. 最後
經過以上的練習,我們對Nginx
有了一定的瞭解,且知道如何進行配置。同時瞭解瞭如何藉助docker-compose
打包執行需要多容器的複雜應用。
本篇就先講到這裡,下一篇我們介紹如何在Linux
上玩耍MySql
並打通Nginx+Web+MySql
的容器化部署。
相關文章
- .NET Core容器化之多容器應用部署@Docker-ComposeDocker
- NET Core+MySql+Nginx 容器化部署MySqlNginx
- .NET Core+MySql+Nginx 容器化部署MySqlNginx
- .NET Core容器化(Docker)Docker
- .NET Core容器化@DockerDocker
- 如何快速部署容器化應用
- Asp.Net Core Blazor之容器部署ASP.NETBlazor
- Docker容器化部署Python應用DockerPython
- Docker容器中執行.Net Core應用程式Docker
- Vue.js應用程式容器化部署Vue.js
- 容器化部署實踐之Django應用部署(二)Django
- Docker容器與虛擬化技術:OpenEuler 部署 docker容器應用Docker
- Docker容器學習梳理 - 應用程式容器環境部署Docker
- 使用Docker容器化部署實踐之Django應用部署(一)DockerDjango
- Kubernetes 部署 PHP-fpm 與 nginx 多容器應用PHPNginx
- 容器中的 .net core應用,生成dump檔案並匯出
- 一套標準的ASP.NET Core容器化應用日誌收集分析方案ASP.NET應用日誌
- Docker的安裝與容器應用部署Docker
- 容器化改造應用-資料
- .NET應用載入容器Glue4Net
- docker容器化.NET程式Docker
- Java服務端容器化:Docker與Kubernetes的應用Java服務端Docker
- Asp.net core自定義依賴注入容器,替換自帶容器ASP.NET依賴注入
- 應用容器化的五個步驟
- Docker容器化部署嘗試——多容器通訊(node + mongoDB + nginx)DockerMongoDBNginx
- 容器化 | 在 Kubernetes 上部署 RadonDB MySQL 叢集MySql
- 應用容器引擎-DockerDocker
- 雲伺服器:如何在docker容器中部署應用伺服器Docker
- Terraform部署容器服務Swarm叢集及WordPress應用ORMSwarm
- Docker中部署.NET CORE應用(控制檯應用程式篇)Docker
- 容器化部署GVM掃漏系統
- Linux Docker 部署 ASP.NET Core應用LinuxDockerASP.NET
- 在 Docker 中部署 ASP.NET CORE 應用DockerASP.NET
- .NET Core應用程式的2種部署方式
- 使用Jexus 容器化您的 Blazor 應用程式Blazor
- 微軟Azure Container Service的容器化應用微軟AI
- 谷歌助力,快速實現 Java 應用容器化谷歌Java
- 對傳統應用進行容器化改造