背景
在這個時間點,我們可能已經對 Linux 容器使用已經達到熟練掌握的程度,因為 Docker 與 Kubernetes 都是最早為 Linux 平臺設計。當我們從容器這項技術中體會到種種收益,對于我們的 windows 的應用是否也能利用容器技術簡化我們的開發運維?對于大型的企業來說,Windows 系列的開發程序也會占一定的比例,這個時候領導可能會有一個指示下來:“我們 .Net 應用也要上容器云”。
好的,任務拿到以后我們首先要解決的第一件事就是 Windows 應用容器化,雖然我們知道 .Net Core 是一個可以跨平臺運行,但仍然有很多使用 .Net Framwork 編寫的應用仍在運行和迭代,所以 Docker on Windows 是一條必須要走的路,好在微軟和 Docker 在這方面有足夠的投入。
小貼士:對于企業來說,轉型并不是把原來所有的資產全部拋棄,是利用能利用的原有資產和新的技術繼續向前進
Windows 容器類型
雖然我們常說 Container 的實現方案不僅只有 Docker, 但我們在實際使用上用的最最最多還是 Docker。這里心疼 Docker 三秒鐘?。在 Windows 容器化的實現上分為兩類:
- Hyper-V 容器
- 類似于 Docker on Mac, Docker on Windows 也經歷了通過基于 Hypervisor 的虛擬化技術來實現非原生 Linux 平臺上的容器方案。 Mac 上使用的是 hyperkit ,Windows 上有 Hyper-V 。
- 這就相當于每個容器運行在一個被高度優化過的虛擬機里,他們之間不共享操作系統內核,好處是會有更好的安全隔離性,以及在操作系統的內核上有更多的選擇性。
- Native 容器
- 類似于我們在 Linux 上使用的容器,基于 process 和 namespace 的隔離。
這兩種不同的容器類型,從操作角度上是一致的,像Build、Push、Run 等等,不同的是它是 Windows 環境,需要使用 powershell 或者 cmd 去寫 Dockerfile, 當然這個對于 Windows 的運維人員沒什么問題。
Windows Dockerfile 示例
看一個簡單的例子:
FROM microsoft/windowsservercore:1803COPY ConsoleTest.exe C:/ENTRYPOINT C:/ConsoleTest.exe
我們注意到這個 Dockerfile 的 base 鏡像是 windowsservercore:1803 ,意味著這個鏡像是可以和 windowsserver 1803 兼容的 Docker 鏡像, 這里提到到了一個 Windows Host OS 與 容器 OS 的版本兼容性:
Container OS version | Host OS Version | |||||
---|---|---|---|---|---|---|
Windows Server 2016 Builds: 14393. | Windows 10 1609, 1703 Builds: 14393., 15063. | Windows Server version 1709 Builds 16299. | Windows 10 Fall Creators Update Builds 16299. | Windows Server version 1803 Builds 17134. | Windows 10 version 1803 Builds 17134. | |
Windows Server 2016 Builds: 14393. | Supports process orhyperv isolation | Supports Onlyhyperv isolation | Supports Onlyhyperv isolation | Supports Onlyhyperv isolation | Supports Onlyhyperv isolation | Supports Onlyhyperv isolation |
Windows Server version 1709 Builds 16299. | Not supported | Not supported | Supports process orhyperv isolation | Supports Onlyhyperv isolation | Supports Onlyhyperv isolation | Supports Onlyhyperv isolation |
Windows Server version 1803 Builds 17134. | Not supported | Not supported | Not supported | Not supported | Supports process orhyperv isolation | Supports Onlyhyperv isolation |
翻譯過是:
- 相同的 OS 版本可以支持 native container 和 hyperv container
- Host OS 版本高,Container OS 版本低,可以用 hyperv container
- Container OS 比 Host OS 高? 那就不行了。
再看一個例子:
buildapp.ps1
# Remove existing default web site files remove-item C:\inetpub\wwwroot\iisstart.*# Ensure write permissions over web app project files icacls C:\inetpub\wwwroot\WebTest /grant Everyone:F /t /q# Import necessary IIS modules then set app project folder as web application Import-Module IISAdministration Import-Module WebAdministrationNew-Item 'IIS:\Sites\Default Web Site\WebTest' -Type Application -PhysicalPath 'C:\inetpub\wwwroot\WebTest' Set-WebConfigurationProperty -p 'MACHINE/WEBROOT/APPHOST' -fi 'system.applicationHost/log' -n 'centralLogFileMode' -v 'CentralW3C'; ` Set-WebConfigurationProperty -p 'MACHINE/WEBROOT/APPHOST' -fi 'system.applicationHost/log/centralW3CLogFile' -n 'truncateSize' -v 4294967295; ` Set-WebConfigurationProperty -p 'MACHINE/WEBROOT/APPHOST' -fi 'system.applicationHost/log/centralW3CLogFile' -n 'period' -v 'MaxSize'; ` Set-WebConfigurationProperty -p 'MACHINE/WEBROOT/APPHOST' -fi 'system.applicationHost/log/centralW3CLogFile' -n 'directory' -v 'c:\iislog'
runapp.ps1
Start-Service W3SVC; ` Invoke-WebRequest http://localhost -UseBasicParsing | Out-Null; ` netsh http flush logbuffer | Out-Null; ` Get-Content -path 'c:\iislog\W3SVC\u_extend1.log' -Tail 1 -Wait
Dockerfile
FROM microsoft/dotnet-framework:4.7.2-sdk-20180814-windowsservercore-1803# WebTest.NET dependencies RUN dism.exe /online /enable-feature /all /featurename:iis-webserver /NoRestart RUN powershell add-windowsfeature web-asp-net45# Configure Web App COPY runapp.ps1 buildapp.ps1 WebTest.zip C:/SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] RUN powershell -Command { Expand-Archive -Path C:\WebTest.zip -DestinationPath C:\inetpub\wwwroot\WebTest } RUN powershell -Command { Remove-Item C:\WebTest.zip -Force }RUN powershell.exe C:/buildapp.ps1 EXPOSE 80ENTRYPOINT ["powershell", "C:/runapp.ps1"]
上面的例子做了一件事是把 iis 的文件日志輸出通過 tail 的方式轉換成了標準輸出,這樣 docker logs
就能看到日志輸出了
提問?
- 什么情況下用 ContainerOS 使用 latest 的 tag?
- 如果是在 Kubernetes 的環境下除了通過轉換成標準輸出,還能怎樣采集 iis 的文件日志?
下一篇: 快速搭建 Windows Kubernetes 環境
Ref:
- https://docs.docker.com/docker-for-mac/
- https://github.com/moby/hyperkit
- https://docs.microsoft.com/en-us/windows-server/virtualization/hyper-v/hyper-v-technology-overview
- https://docs.microsoft.com/en-us/virtualization/windowscontainers/about/#windows-container-types
- https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/version-compatibility