結合Docker Compose,將Nginx反向代理和負載均衡使用于ASP.NET 5應用
該文章描述了Nginx在ASP.NET 5中的使用,它提供了一個運行在本地的負載均衡機制,并使用Docker Compose技術。
ASP.NET 5,對于不同的操作系統,以及不同的Web服務,如 IIS ,有多種不同的宿主選擇。 Filip W 有大量的博客帖子,都是 運行在基于IIS服務的ASP.NET 5網站上 。在此,我主要描述了 NGINX 在 ASP.NET 5 中的使用,它提供了一個運行在本地的負載均衡機制,并使用 Docker Compose 技術。
太好啦!#aspnet5 + #nginx + #docker + #docker compose,組成簡單的負載均衡 :) https://t.co/YnJamDubIS pic.推ter.com/pBOWDDnVHR
— Tugberk Ugurlu (@tourismgeek) 2016.1.26
在之前的.NET網頁開發中,我們不曾有這些選擇。舉個例子,你可以很熟練的在Mono項目中使用ASP.NET Web API應用,并暴露在Nginx的下層。但是,ASP.NET 5使這些選項可以真正的直接被采用。
我們得出的結果如下圖所示,我把實例放在 此處 :
在RC1上的APS.NET 5應用
我有一個非常簡單的APS.NET 5應用,輸出一個Hello信息,列出該主機上的環境變量。該項目結構如下:
tugberk@ubuntu:~/apps/aspnet-5-samples/nginx-lb-sample$ tree.
├── docker-compose.yml
├── docker-nginx.dockerfile
├── docker-webapp.dockerfile
├── global.json
├── nginx.conf
├── NuGet.Config
├── README.md
└── WebApp
├── hosting.json
├── project.json
└── Startup.cs</pre>
我沒有把源碼放在這里,但是你可以在 這里 找到,。但是,我必須強調一點,通過Kestrel暴露給ASP.NET 5應用的Server URL應該是多少。為了Docker使用,我們需要配置“0.0.0.0”,而不是localhost或者127.0.0.1。 Mark Rendle 有 很多描述 來說明這個問題,我給出的如下文件 hosting.json 也同樣覆蓋了這個問題:
{"server": "Microsoft.AspNet.Server.Kestrel",
"server.urls": "
}</pre>
Docker在ASP.NET 5應用中的應用
下一步是在Docker下運行ASP.NET 5應用。在 Docker Hub 資源庫中有 ASP.NET 5 Docker 鏡像,特別的簡單。另外,Mark Rendle有三篇很有洞察力的關于ASP.NET 5,Docker和Linux混合使用的文章, Part1 , Part2 和 Part3 。強烈建議大家閱讀下這些文章。我有個實例,其 Dockerfile (指向 該文件 )如下:
FROM microsoft/aspnet:1.0.0-rc1-update1COPY ./WebApp/project.json /app/WebApp/
COPY ./NuGet.Config /app/
COPY ./global.json /app/
WORKDIR /app/WebApp
RUN ["dnu", "restore"]
ADD ./WebApp /app/WebApp/
EXPOSE 5090
ENTRYPOINT ["dnx", "run"]</pre>
這就是Docker下面運行ASP.NET 5的簡單的Dockerfile文件,下面生成Docker鏡像并運行該鏡像:
docker build -f docker-webapp.dockerfile -t hellowebapp .docker run -d -p 5090:5090 hellowebapp</pre>
該容器現在是以分離模式運行,你可以從主機訪問HTTP終端。
![]()
現在,你可以對這個Container做任何你想要做的事情。重新編譯,停止,移除,等等。
Nginx 和 Docker Compose
該篇章的最后一部分是Nginx和Docker Compose。對于還不了解Nginx的人員,Nginx是一個免費、開源的,高性能的HTTP服務器和反向代理。在實際開發環境中,你并不想把Kestrel直接暴露給外部。相反,你可以把Kestrel放在一個成熟的Web服務器后面,如Nginx,IIS或者 Apache Web Server 。
有兩個很好的錄像,你可以看下有關Kerstrel和Linux主機。從視頻中可以知道為什么把Kestrel放在一個Web服務器后面。我強烈建議你在Linux中使用這些應用之前看下這些視頻錄像。
Docker Compose,從不同角度看是一個完全不同的工具類型,定義并運行多容器的Docker應用。使用Compose,你可以使用一個 Compose文件 去配置自己的應用服務。這對于我們在此想要實現的項目是一個完美的結合,因為我們至少要三個運行的容器:
- ASP.NET 5 應用1: ASP.NET 5應用的一個實例
- ASP.NET 5 應用2:另一個ASP.NET 5應用的實例
- Nginx容器:一個Nginx進程,代理請求到ASP.NET 5應用
首先開始配置Nginx,讓其可以在Docker下運行。 Nginx鏡像 在Docker Hub已經存在。我們將會使用該鏡像,并使用如下的Nginx配置:
worker_processes 4;events { worker_connections 1024; }
http {
upstream web-app {
server webapp1:5090; server webapp2:5090;
}
server {
listen 80;
location / {
proxy_pass http://web-app; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade;
}
}
}</pre>
該配置文件中除了些通用的配置,重要的是負載均衡和反向代理的配置。在該配置文件中,Nginx服務器接收來自80端口的請求,然后代理這些請求給webapp1:5090和webapp2:5090。了解更多有關 NGINX反向代理 和 負載均衡 的信息,從中可以知道如何配置代理和負載均衡,上面的例子也足以說明。
在NGINX配置中,還有一個重要的部分。 Kestrel在RC1中有一個很讓人頭疼的問題 ,該問題在 RC2中已經解決 了。為了臨時解決這個問題,你需要設置“Connection: keep-alive”頭,這就是為什么我們在NGINX配置中做"proxy_set_header Connection keep-alive;"說明。
下面就是Nginx的Dockerfile文件( Github中地址 ):
FROM nginxCOPY ./nginx.conf /etc/nginx/nginx.conf</pre>
到此,你也許會問webapp1和webapp2(我們在Nginx配置中已經說明)映射到什么變量。這些是為運行ASP.NET 5應用的容器做的DNS引用,當我們在Docker Compose文件中引用webapp1和webapp2,該DNS映射將會自動生效。最后,下面就是組織出的Docker Compose文件內容( Github中地址 ):
webapp1:build: .
dockerfile: docker-webapp.dockerfile
container_name: hasample_webapp1
ports:
- "5091:5090"
webapp2:
build: .
dockerfile: docker-webapp.dockerfile
container_name: hasample_webapp2
ports:
- "5092:5090"
nginx:
build: .
dockerfile: docker-nginx.dockerfile
container_name: hasample_nginx
ports:
- "5000:80"
links:
webapp1
webapp2</pre>
你可以看到第三個容器的定義,我們鏈接之前定義的兩個容器到Nginx容器。或者,你也許想要在Docker的 上下文中查看Service Discovery 來替換鏈接。
現在,我們都已經準備完畢,只需要運行兩個docker-compose命令(在Docker Compose文件的目錄下面)去啟動該應用并運行:
docker-compose build
docker-compose up</pre>
到目前,我們可以看到三個正在運行的容器,也可以從主機終端訪問localhost:5000,可以看到負載被分發到兩臺ASP.NET 5應用的容器上。
棒極了!但是,這只是演示的一個簡單例子,目的是說明在本地運行一個像這樣的應用是很容易的。這可能對所有的容器運行在一個盒子中的場景不提供性能保障。我的下一步是融入 HAProxy ,讓它做負載均衡。
</div>來自: http://dockone.io/article/985