在Linux和Windows的Docker容器中運行ASP.NET Core

(此文章同時發表在本人微信公衆號「dotNET每日精華文章」,歡迎右邊二維碼來關注。)html

譯者序:其實過去這周我都在研究這方面的內容,結果週末有事沒有來得及總結爲文章,Scott Hanselman就捷足先登了。那麼我就來翻譯一下這篇文章,讓更多的中文讀者看到。固然Scott遇到的坑我也遇到了。linux

不過首先,對於不熟悉的朋友我仍是來解釋一下Linux容器和Windows容器的概念。git

因爲容器成爲虛擬化和應用託管的一種不可避免的選項,Windows也開始爲公衆提供容器功能(其實微軟具有和使用容器技術好久了)。這樣的容器功能在內部的引擎經過兩種方式來實現,內核級別(僅Windows Server 2016支持)和Hyper-v級別(Windows 10和Windows Server 2016支持)。可是對外的接口和標準又遵循Docker的,這樣的好處是Windows容器生態能夠和現有的Linux容器生態很好的結合。因此Windows容器稱之爲Docker on Windows。Windows容器的出現爲傳統的Windows服務端應用程序的容器化開啓了新天地,好比把Qlik Sense的服務器放到容器中來即時編排集羣。web

而以前Docker公司也針對Windows 10推出過利用Hyper-V來跑一個Linux虛擬機做爲容器宿主主機的發行版本。那個稱之爲Docker for Windows。docker

因此在Windows 10上,你能夠同時安裝Docker for Windows和Docker on Windows,只是不能同時運行二者。二者默認的安裝目錄不一樣,可是客戶端(即Docker.exe)是同名的,因此我把on版本的客戶端執行文件改了個名字就能夠兩個一塊兒用了。其實客戶端雖然版本不一樣,可是基本的命令仍是都是兼容的,用其中一個就夠了。由於Docker Deamon在二者中都是一樣的訪問地址。windows

Scott Hanselman的文章地址爲:http://www.hanselman.com/blog/ExploringASPNETCoreWithDockerInBothLinuxAndWindowsContainers.aspx服務器

=====我是譯文正文開始的分隔符=====微信

在去年5月的時候,使用ASP.NET和Docker來折騰一些事情還步履蹣跚。不過,偉大之處就是咱們一直在進步。我曾經就寫過一篇博客文章來展現如何把ASP.NET 5(當時還稱之爲5呢,如今已經更名爲Core 1.0了)應用發佈到Docker中。後來,在2015年11月,相似Docker Toolbox和Kitematic這樣的新工具讓事情變得更加容易。在2016年5月Docker for Windows Beta繼續讓這件事情易如反掌。網絡

那麼來到2016年10月這個時候,咱們來看看如何使用ASP.NET Core、Docker和Windows來進行開發。app

我安裝了以下東西:

Docker for Windows真的很是好,它能夠自動爲你配置好Hyper-V,建立一個Docker宿主OS,並啓動好這個虛擬機。節約了大量的時間。

Hyper-V manager

這是個人Linux宿主,我無需太多關心它的狀況。我將會經過命令行或Visual Studio來完成全部事情。

首先經過File | New Project來建立一個運行在.NET Core中的ASP.NET Core應用程序。

接着在項目名稱上點擊右鍵並選擇Add | Docker Support。這一菜單來自Visual Studio Tools for Docker擴展。這個步驟會添加基本的Dockerfile和其餘docker-compose文件。經過這樣的開箱即用的步驟,我就完成了全部的配置從而可以把ASP.NET Core應用程序部署到Docker Linux容器中。

ASP.NET Core運行在Docker Linux容器中

從我這個ASP.NET Core應用當中,咱們能夠看到其使用的基礎鏡像(就是Dockerfile中的FROM語句)是Linux的ASP.NET Core鏡像。

FROM microsoft/aspnetcore:1.0.1
ENTRYPOINT ["dotnet", "WebApplication4.dll"]
ARG source=.
WORKDIR /app
EXPOSE 80
COPY $source .

接下來,因爲我不但願Docker編譯個人應用程序,只想發佈到本地。能夠閱讀Steve Laske的博客文章"Building Optimized Docker Images with ASP.NET Core"來了解如何在一個容器中構建應用程序而在其餘容器中運行。這樣作優化了服務器的使用率和資源。

我將經過以下命令行指令來發布、構建鏡像並運行它。

>dotnet publish

>docker build bin\Debug\netcoreapp1.0\publish -t aspnetcoreonlinux

>docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
aspnetcoreonlinux latest dab2bff7e4a6 28 seconds ago 276.2 MB
microsoft/aspnetcore 1.0.1 2e781d03cb22 44 hours ago 266.7 MB

>docker run -it -d -p 85:80 aspnetcoreonlinux
1cfcc8e8e7d4e6257995f8b64505ce25ae80e05fe1962d4312b2e2fe33420413

>docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1cfcc8e8e7d4 aspnetcoreonlinux "dotnet WebApplicatio" 2 seconds ago Up 1 seconds 0.0.0.0:85->80/tcp clever_archimedes

到此,個人ASP.NET Core應用就能夠運行在Docker中了。咱們如今已經嘗試了一個Docker容器,它是託管在Windows中經過Hyper-V來運行的Linux宿主中。

咱們還能夠作點別的什麼呢?

ASP.NET Core運行在一個運行着Windows Nano Server的Docker Windows容器中

有這樣一種Windows Server,稱之爲Windows Server Core,它刪除了UI相關的東西;有這樣一種Windows Server,稱之爲Windows Nano Server,它讓Windows縮減到只有幾百M而不是幾G。這意味着從所需功能和服務器使用率的角度看,這是一個很是好的選擇,讓你部署的空間佔用儘量的小。

讓我來看一下我是否能把ASP.NET Core經過Kestrel【譯者注:ASP.NET Core的跨平臺Web服務器實現】運行到Windows Nano Server中。固然,因爲Nano功能強大,我也能在這個容器中運行IIS,這裏有文檔說明

來自Docker公司的Michael Friis有一篇很棒的博客文章描述了在Windows Server容器中構建和運行Docker應用。在安裝了最新版的Docker for Windows以後,你就能夠經過上下文菜單來在Linux和Windows容器間切換。

Docker switches between Mac and Windows easily

那麼如今我就來用用Windows容器的Docker。你可能還不知道你已經擁有Windows容器了!它已經和Windows 10週年更版本一塊兒發佈了。你能夠在Windows特性對話框中啓用容器功能:

Add Containers in Windows 10

我將修改一下Dockerfile來使用Windows Nano Server鏡像。我也能夠在Docker內部經過環境變量和Expose命令來控制ASP.NET暴露的端口。

FROM microsoft/dotnet:nanoserver
ENTRYPOINT ["dotnet", "WebApplication4.dll"]
ARG source=.
WORKDIR /app
ENV ASPNETCORE_URLS http://+:82
EXPOSE 82
COPY $source .

接着,我發佈並構建……

>dotnet publish
>docker build bin\Debug\netcoreapp1.0\publish -t aspnetcoreonnano

而後,運行它,映射Windows外部端口到Windows容器內部!

注意:在Windows 10經過「NAT」(網絡地址轉換)來和容器通信的時候,有一個Bug,你不能如你(我)所願的那樣,直接經過 http://localhost:82 來訪問容器應用。你不得不經過容器自己的IP來訪問。一旦聽到這個Bug的更多消息和被修復的狀況,我會及時公佈在這裏。它應該會經過Windows Update在幾天內出現。從Docker獲得容器的IP地址的方法爲:docker inspect -f "{{ .NetworkSettings.Networks.nat.IPAddress }}" HASH

那麼,我將經過以下命令在Windows Nano Server中運行個人ASP.NET Core應用(再次說明一下,它將運行在Windows 10的Nano Server容器內)。

>docker run -it -d -p 88:82 aspnetcoreonnano
afafdbead8b04205841a81d974545f033dcc9ba7f761ff7e6cc0ec8f3ecce215

>docker inspect -f "{{ .NetworkSettings.Networks.nat.IPAddress }}" afa
172.16.240.197

如今,我能夠經過172.16.240.197:82來訪問這個站點。一旦上面的Bug被修復後,咱們就能像其餘容器那樣訪問它了。

Windows容器的最美好的一面就是它很是快和輕量級。一旦鏡像被下載下來,在機器上構建好,那麼你經過Docker來啓動和中止它們都是秒完成。

不過,你也能夠經過以下命令來使用Docker隔離Windows容器:

docker run --isolation=hyperv -it -d -p 86:82 aspnetcoreonnano

如此一來,實例徹底是經過Hyper-v自己來隔離運行的。你能夠得到世界上最好的東西:速度、方便的部署加上可選且便捷的隔離。

ASP.NET Core運行在一個運行着Windows Server Core的Docker Windows容器中

接下來,我把Dockerfile修改成使用完整的Windows Server Core鏡像。在下載安裝這個鏡像後,其佔用大約8G的空間,須要花一點時間來下載和解壓,不過它確實是真正的Windows。你也能夠選擇運行爲一個容器或者隔離的Hyper-V容器。

這裏,我經過修改FROM語句來使用包含了.NET Core的Windows Sever Core:

FROM microsoft/dotnet:1.0.0-preview2-windowsservercore-sdk
ENTRYPOINT ["dotnet", "WebApplication4.dll"]
ARG source=.
WORKDIR /app
ENV ASPNETCORE_URLS http://+:82
EXPOSE 82
COPY $source .

注意:我據說使用Windows Sever Core的.NET Core鏡像有可能會取消。由於讓.NET Core運行在Windows Nano Server或其餘輕量級鏡像中更有意義。你應該把Sever Core用於那些更加笨重的應用。若是你真的須要運行在Sever Core的.NET Core,你能夠製做本身的Dockerfile來輕易構建你所要的鏡像。

接下來,我將再次發佈、構建和運行。

>docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
aspnetcoreonnano latest 7e02d6800acf 24 minutes ago 1.113 GB
aspnetcoreonservercore latest a11d9a9ba0c2 28 minutes ago 7.751 GB

因爲容器可以很是快的啓動和中止,因此我能夠利用跑在容器中的Redis、一個SQL容器和包含其餘部分的第三個容器來跑一個完整的Web集羣。或者混合並配對。

>docker ps
CONTAINER ID IMAGE COMMAND PORTS NAMES
d32a981ceabb aspnetcoreonwindows "dotnet WebApplicatio" 0.0.0.0:87->82/tcp compassionate_blackwell
a179a48ca9f6 aspnetcoreonnano "dotnet WebApplicatio" 0.0.0.0:86->82/tcp determined_stallman
170a8afa1b8b aspnetcoreonnano "dotnet WebApplicatio" 0.0.0.0:89->82/tcp agitated_northcutt
afafdbead8b0 aspnetcoreonnano "dotnet WebApplicatio" 0.0.0.0:88->82/tcp naughty_ramanujan
2cf45ea2f008 a7fa77b6f1d4 "dotnet WebApplicatio" 0.0.0.0:97->82/tcp sleepy_hodgkin

總結

再次,讓咱們閱讀Michae的另一篇文章,他使用Docker Compose來把ASP.NET Music Store示例跑在一個Windows容器中,而SQL Express跑在另一箇中,以及Steve Lasker的博客文章(實際上他的整篇文章都是金礦)中提到的爲ASP.NET Core製做一個優化的Docker鏡像

IMAGE ID            RESPOSITORY                   TAG                 SIZE
0ec4274c5571 web optimized 276.2 MB
f9f196304c95 web single 583.8 MB
f450043e0a44 microsoft/aspnetcore 1.0.1 266.7 MB
706045865622 microsoft/aspnetcore-build 1.0.1 896.6 MB

Steve提到了大量的技巧,讓你能夠解決Docker和ASP.NET Core在一塊兒的大部分問題。

全部的一切意味着(IMHO),你能夠把ASP.NET Core用在:

  • 在Linux中跑ASP.NET Core
    • 在Docker容器裏面
    • 在任何雲平臺中
  • 在Windows,、Windows Server、Server Core和Nano Server中跑ASP.NET Core
    • 在Docker的Windows容器裏面
    • 在Docker的Hyper-V隔離容器裏面

這意味着你能夠選擇任意特性支持和爲服務器使用率和便捷度優化過的尺寸大小。一旦全部的工具(Docker for Windows和Visual Studio Docker Tools)準備穩當,咱們就能擁有良好的調試環境,和從開發到生產的工做流支持。

你在使用Docker、容器和ASP.NET Core進行開發了嗎?但願在評論中看到大家的聲音。

相關文章
相關標籤/搜索