Windows 应用容器化

背景

在这个时间点,我们可能已经对 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:1803

COPY 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 processorhypervisolation Supports Onlyhypervisolation Supports Onlyhypervisolation Supports Onlyhypervisolation Supports Onlyhypervisolation Supports Onlyhypervisolation
Windows Server version 1709 Builds 16299. Not supported Not supported Supports processorhypervisolation Supports Onlyhypervisolation Supports Onlyhypervisolation Supports Onlyhypervisolation
Windows Server version 1803 Builds 17134. Not supported Not supported Not supported Not supported Supports processorhypervisolation Supports Onlyhypervisolation

翻译过是:

  1. 相同的 OS 版本可以支持 native container 和 hyperv container
  2. Host OS 版本高,Container OS 版本低,可以用 hyperv container
  3. 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 WebAdministration

New-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 80

ENTRYPOINT ["powershell", "C:/runapp.ps1"]

上面的例子做了一件事是把 iis 的文件日志输出通过 tail 的方式转换成了标准输出,这样 docker logs 就能看到日志输出了

提问😂

  1. 什么情况下用 ContainerOS 使用 latest 的 tag?
  2. 如果是在 Kubernetes 的环境下除了通过转换成标准输出,还能怎样采集 iis 的文件日志?

下一篇: 快速搭建 Windows Kubernetes 环境


Ref:

posted @ 2018-09-19 07:12  温酒伴青枫  阅读(5798)  评论(0编辑  收藏  举报