|
聽說Windows支持原生docker了,大家一定都很興奮。然而,大家想過沒有,Windows Server Docker最適合什么場景呢?部署.NET Core應用?為什么不選擇Linux下的docker?正常的決策者腦袋被門擠了才會花錢額外買Windows Server的license,用來部署.NET Core吧?所以,在本人看來,Windows Server Docker最大的價值,還是在于部署傳統基于WindowsServerCore的應用。這樣的應用一般有兩大類,一類是基于iis的網站應用;另一類是Windows Service。本文主要關注基于iis的應用的docker部署。 那么,部署一個iis應用到docker,是不是只要起一個iis的docker容器實例,遠程連接,并且,copy文件進去,能通過容器內的iis訪問就行了?如果,有人問這樣的問題,那么,說明他還完全沒有容器的思維。上面說的這個,其實就成了將容器當虛擬機用了,這將極大地限制了docker原有的靈活擴展能力。因此,可以說是使用Windows docker最糟糕的姿勢之一了。 要正確部署一個iis應用到Windows Server Docker,并不是表面那么簡單。限于篇幅,并且為了更專注,本文先不涉及容器編排、負載均衡、images的構建和管理等問題(這些要考慮的問題還有很多,以后我們單獨聊),這里只關注如何將一個基于iis的應用正確運行于單個Windows Server Docker實例中。即便如此,一般至少也要解決下面這些問題:
應用示例為便于理解和演示,我在github上寫了一個簡單的示例應用:windows-docker-iis-demo 這個應用只包含一個頁面,在我本機運行時,顯示類似下面的內容: 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讀取的系統環(huán)境變量,頁面最下面打印出當前Windows系統的的hosts。 定義Dockerfile如下: 我們分別來理解一下Dockerfile每一段的含義:
啟動腳本SetHostsAndStartMonitoring.cmd的內容如下: 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這個系統環(huán)境變量,覆蓋當前系統的hosts文件;第二步讀取env1環(huán)境變量,覆蓋web.config中的對應配置;最后調用繼承自microsoft/iis image的ServiceMonitor.exe命令,監(jiān)控iis主進程,直到其退出。 下面,我們來試著build這個docker。因為到目前為止(本系列的第一篇+第二篇),我們還只能從這臺Windows Server機器上執(zhí)行docker命令,以后的文章會講到如何從遠程server build以及如何集成到CI工具進行build,這里先繞過。我們在VS2015中編譯這個webapp,并且發(fā)布到publish目錄。然后,復制整個windows-docker-iis-demo目錄到這臺docker宿主機的C盤根目錄,以便進行docker build。這個當然不是build docker image的正常姿勢,只是因為我們還沒提到其他方式,我們先粗糙一點,把它build出來,以便可以運行。 在我們的Windows Server 2016機器上,打開一個administrator模式的powershell窗口,cd到c:\windows-docker-iis-demo目錄,然后執(zhí)行docker build命令制作image: 編譯成功后,執(zhí)行docker images,可以看到多了一個iis-demo:1.0的docker image。接著,讓我們在宿主機的C盤創(chuàng)建一個temp目錄(為下面的volume使用,mount到容器內部的iis日志),然后執(zhí)行下面的命令運行一個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這里的參數分別表示:
稍等片刻,等待容器實例運行,然后在宿主機的瀏覽器中訪問,可以看到如下的內容: 對比前面在開發(fā)環(huán)境運行的結果,我們可以看到有一些有意思又詭異的區(qū)別:
另外,在宿主機的c:\temp目錄,我們可以看到從容器實例寫道外部的iis log。 好了,看看至此我們已經解決了哪些最開始提到的問題了:
應該說,我們已經解決了大多數前面提到但實例運行時需要解決的問題了。然而,別忘了,這一篇里,我們只針對單服務器,單容器實例。在實際的部署案例中,是絕不允許單點,無法擴展的。 后面幾篇,我會展開講講這一篇跳過的一些非常重要的話題,例如網絡配置、遠程管理、負載均衡、實時監(jiān)控、以及更高級的容器編排和集群實現等等,敬請期待! |
|
|