聽說Windows支持原生docker了,大家一定都很興奮。然而,大家想過沒有,Windows Server Docker最適合什么場景呢?部署.NET Core應(yīng)用?為什么不選擇Linux下的docker?正常的決策者腦袋被門擠了才會花錢額外買Windows Server的license,用來部署.NET Core吧?所以,在本人看來,Windows Server Docker最大的價值,還是在于部署傳統(tǒng)基于WindowsServerCore的應(yīng)用。這樣的應(yīng)用一般有兩大類,一類是基于iis的網(wǎng)站應(yīng)用;另一類是Windows Service。本文主要關(guān)注基于iis的應(yīng)用的docker部署。 那么,部署一個iis應(yīng)用到docker,是不是只要起一個iis的docker容器實(shí)例,遠(yuǎn)程連接,并且,copy文件進(jìn)去,能通過容器內(nèi)的iis訪問就行了?如果,有人問這樣的問題,那么,說明他還完全沒有容器的思維。上面說的這個,其實(shí)就成了將容器當(dāng)虛擬機(jī)用了,這將極大地限制了docker原有的靈活擴(kuò)展能力。因此,可以說是使用Windows docker最糟糕的姿勢之一了。 要正確部署一個iis應(yīng)用到Windows Server Docker,并不是表面那么簡單。限于篇幅,并且為了更專注,本文先不涉及容器編排、負(fù)載均衡、images的構(gòu)建和管理等問題(這些要考慮的問題還有很多,以后我們單獨(dú)聊),這里只關(guān)注如何將一個基于iis的應(yīng)用正確運(yùn)行于單個Windows Server Docker實(shí)例中。即便如此,一般至少也要解決下面這些問題:
應(yīng)用示例為便于理解和演示,我在github上寫了一個簡單的示例應(yīng)用:windows-docker-iis-demo 這個應(yīng)用只包含一個頁面,在我本機(jī)運(yùn)行時,顯示類似下面的內(nèi)容: Hello Docker!Configuration:env1=Dev (from appSettings in web.config)env2=Dev (from OS environment variable)Content of C:\Windows\System32\drivers\etc\hosts:# Localhost (DO NOT REMOVE)127.0.0.1 localhost::1 localhost ip6-localhost ip6-loopback 其中env1為web.config中的appSettings值,env2讀取的系統(tǒng)環(huán)境變量,頁面最下面打印出當(dāng)前Windows系統(tǒng)的的hosts。 定義Dockerfile如下:
我們分別來理解一下Dockerfile每一段的含義:
啟動腳本SetHostsAndStartMonitoring.cmd的內(nèi)容如下: powershell -executionpolicy bypass -Command 'If ($env:HOSTS) { $hosts = $env:HOSTS.Replace(':', ' ').Replace(',', '\r\n'); $hosts | Set-Content 'C:\Windows\System32\drivers\etc\hosts'; 'Applied hosts: ' + $hosts' }powershell -executionpolicy bypass -Command 'if ($env:env1) { (Get-Content 'c:\inetpub\wwwroot\iis-demo\web.config').replace('Dev', $env:env1) | Set-Content 'c:\inetpub\wwwroot\iis-demo\web.config' };c:\ServiceMonitor.exe w3svc 其中,第一部分讀取HOSTS這個系統(tǒng)環(huán)境變量,覆蓋當(dāng)前系統(tǒng)的hosts文件;第二步讀取env1環(huán)境變量,覆蓋web.config中的對應(yīng)配置;最后調(diào)用繼承自microsoft/iis image的ServiceMonitor.exe命令,監(jiān)控iis主進(jìn)程,直到其退出。 下面,我們來試著build這個docker。因?yàn)榈侥壳盀橹梗ū鞠盗械牡谝黄?第二篇),我們還只能從這臺Windows Server機(jī)器上執(zhí)行docker命令,以后的文章會講到如何從遠(yuǎn)程server build以及如何集成到CI工具進(jìn)行build,這里先繞過。我們在VS2015中編譯這個webapp,并且發(fā)布到publish目錄。然后,復(fù)制整個windows-docker-iis-demo目錄到這臺docker宿主機(jī)的C盤根目錄,以便進(jìn)行docker build。這個當(dāng)然不是build docker image的正常姿勢,只是因?yàn)槲覀冞€沒提到其他方式,我們先粗糙一點(diǎn),把它build出來,以便可以運(yùn)行。 在我們的Windows Server 2016機(jī)器上,打開一個administrator模式的powershell窗口,cd到c:\windows-docker-iis-demo目錄,然后執(zhí)行docker build命令制作image:
編譯成功后,執(zhí)行docker images,可以看到多了一個iis-demo:1.0的docker image。接著,讓我們在宿主機(jī)的C盤創(chuàng)建一個temp目錄(為下面的volume使用,mount到容器內(nèi)部的iis日志),然后執(zhí)行下面的命令運(yùn)行一個iis-demo的docker instance: docker run --ip 172.24.128.2 -p 80 -v 'c:/temp:c:/inetpub/logs/LogFiles' -e 'env1=LIVE1' -e 'env2=LIVE2' -e 'HOSTS=1.2.3.4:TEST.COM' iis-demo:1.0 這里的參數(shù)分別表示:
稍等片刻,等待容器實(shí)例運(yùn)行,然后在宿主機(jī)的瀏覽器中訪問,可以看到如下的內(nèi)容:
對比前面在開發(fā)環(huán)境運(yùn)行的結(jié)果,我們可以看到有一些有意思又詭異的區(qū)別:
另外,在宿主機(jī)的c:\temp目錄,我們可以看到從容器實(shí)例寫道外部的iis log。 好了,看看至此我們已經(jīng)解決了哪些最開始提到的問題了:
應(yīng)該說,我們已經(jīng)解決了大多數(shù)前面提到但實(shí)例運(yùn)行時需要解決的問題了。然而,別忘了,這一篇里,我們只針對單服務(wù)器,單容器實(shí)例。在實(shí)際的部署案例中,是絕不允許單點(diǎn),無法擴(kuò)展的。 后面幾篇,我會展開講講這一篇跳過的一些非常重要的話題,例如網(wǎng)絡(luò)配置、遠(yuǎn)程管理、負(fù)載均衡、實(shí)時監(jiān)控、以及更高級的容器編排和集群實(shí)現(xiàn)等等,敬請期待! |
|