Windows Server 2016 TP3のDockerを試してみる


Windows Server 2016 Technology Preview 3で、ついにMSのコンテナランタイムとDockerの統合を試せるようになった。

サマリ

  • Cygwinはインストールは成功するものの、何かやってイメージを生成すると失敗する。このためCygwinアプリのDocker化はできなかった。
  • コンテナの生成はLinuxほど早くない。
  • コンソールハンドリングが変。対話的プログラムの出力は出たり出なかったりする
  • Linux上のDockerとは挙動が異なる点がある
    • docker commitが動作中のコンテナに対して発行できない、docker stopがコンテナを直ちに停止しないことが多い、docker topが無い等。
  • PID等のアイソレーションは提供しない。

まだ実用には厳しい感じがある。あとGUIアプリケーションも当然動作しない。

インストール

Windows Server 2016 TP3 をダウンロードして適当にセットアップする。Windows Server Containerの起動にHyper-Vは必要無いのでVirtualBox等でもOK。(OSイメージを共有しないHyper-V Containerも選択肢としては提供しているがDockerから使う簡単な方法な無いように見える。)
セットアップ方法は

の通りにやればOK。
powershellを起動し、

wget -uri http://aka.ms/setupcontainers -OutFile C:\ContainerSetup.ps1

してスクリプトを実行すると、Windows Server Coreのコンテナイメージがセットアップされる。(wgetGNU wgetでなくpowershellのcmdlet。このため、GNU wgetをインストールする必要はなく、デフォルトインストールなシステムでそのまま実行できる)
Dockerはc:\Windows\system32\docker.exeにインストールされる。他の常識的なMSのプログラムと異なり、PE中にバージョン等を含まない。くじらアイコンは付いているけど。

Dockerする

使用方法は

でも説明されているが、普通のLinux上dockerと大して違わない。
適当にCygwinをインストールするDockerfileを書く:

FROM windowsservercore
WORKDIR /
RUN powershell wget http://cygwin.com/setup-x86_64.exe -OutFile setup-x86_64.exe 
RUN setup-x86_64.exe -s http://ftp.iij.ad.jp/pub/cygwin -q -P openssh -v -n -l c:/cache/cygwin64
RUN c:\cygwin64\bin\touch /hoge

setup-x86_64.exeまでは問題なく進行するが、最後のtouch /hogeを行う段階で、

Step 4 : RUN c:\cygwin64\bin\touch /hoge
 ---> Running in 802547b43652
hcsshim::ImportLayer - Win32 API call returned error r1=2147549183
 err=Catastrophic failure layerId=27dccccf038a7af25f1ec22d9e4b349da31fbb87943c0037ba7f0c7b59f71842 flavour=1
 folder=C:\ProgramData\docker\windowsfilter\27dccccf038a7af25f1ec22d9e4b349da31fbb87943c0037ba7f0c7b59f71842-295779872

のようなエラーが発生する。
この行を消すとインストール自体はちゃんと完了し、docker run等で入ることはできるが、Cygwinプログラムのコンソールは表示されない。例えばリダイレクトするなりなんなりの方法で出力を得ることはできるが。。
Server Container内で起動したプロセスはホスト上のタスクマネージャで観察することができる。当然パスにはアクセスできないのでプロパティ等は使用できない(無反応になる)。
イメージ類は

  • c:\ProgramData\Microsoft\Windows\Images\ - Windows Server Coreイメージ
  • c:\ProgramData\docker\windowsfilter - コンテナイメージ(.vhdxとHives、Files)

に格納されている。モノによってはFilesとして分離されるが、.vhdxにもデータが格納されることもある。Process Explorerで実行中のモジュールをダンプすると、

Process: setup-x86_64.exe Pid: 4720

Name	Description	Company Name	Path
advapi32.dll	Advanced Windows 32 Base API	Microsoft Corporation	C:\Windows\System32\advapi32.dll
bcryptprimitives.dll	Windows Cryptographic Primitives Library	Microsoft Corporation	C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\bcryptprimitives.dll
clbcatq.dll	COM+ Configuration Catalog	Microsoft Corporation	C:\Windows\System32\clbcatq.dll
combase.dll	Microsoft COM for Windows	Microsoft Corporation	C:\Windows\System32\combase.dll
comctl32.dll	User Experience Controls Library	Microsoft Corporation	C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.10514.0_none_8c13ae7a515fe73d\comctl32.dll
comctl32.dll.mui			\Device\HarddiskVolume134\Windows\WinSxS\amd64_microsoft.windows.c..-controls.resources_6595b64144ccf1df_6.0.10514.0_en-us_a21ef75f7e06192a\comctl32.dll.mui
gdi32.dll	GDI Client DLL	Microsoft Corporation	C:\Windows\System32\gdi32.dll
imm32.dll	Multi-User Windows IMM32 API Client DLL	Microsoft Corporation	C:\Windows\System32\imm32.dll
kernel.appcore.dll	AppModel API Host	Microsoft Corporation	C:\Windows\System32\kernel.appcore.dll
kernel32.dll	Windows NT BASE API Client DLL	Microsoft Corporation	C:\Windows\System32\kernel32.dll
KernelBase.dll	Windows NT BASE API Client DLL	Microsoft Corporation	C:\Windows\System32\KernelBase.dll
locale.nls			C:\Windows\System32\locale.nls
msctf.dll	MSCTF Server DLL	Microsoft Corporation	C:\Windows\System32\msctf.dll
msvcrt.dll	Windows NT CRT DLL	Microsoft Corporation	C:\Windows\System32\msvcrt.dll
nsi.dll	NSI User-mode interface DLL	Microsoft Corporation	C:\Windows\System32\nsi.dll
ntdll.dll	NT Layer DLL	Microsoft Corporation	C:\Windows\System32\ntdll.dll
ole32.dll	Microsoft OLE for Windows	Microsoft Corporation	C:\Windows\System32\ole32.dll
powrprof.dll	Power Profile Helper DLL	Microsoft Corporation	C:\Windows\System32\powrprof.dll
profapi.dll	User Profile Basic API	Microsoft Corporation	C:\Windows\System32\profapi.dll
psapi.dll	Process Status Helper	Microsoft Corporation	C:\Windows\System32\psapi.dll
rpcrt4.dll	Remote Procedure Call Runtime	Microsoft Corporation	C:\Windows\System32\rpcrt4.dll
sechost.dll	Host for SCM/SDDL/LSA Lookup APIs	Microsoft Corporation	C:\Windows\System32\sechost.dll
setup-x86_64.exe			C:\ProgramData\docker\windowsfilter\6b3ee63a1aa54af2e4d809df5fe118db83833efc279bef6775ba75b19f247620\Files\setup-x86_64.exe
SHCore.dll	SHCORE	Microsoft Corporation	C:\Windows\System32\SHCore.dll
shell32.dll	Windows Shell Common Dll	Microsoft Corporation	C:\Windows\System32\shell32.dll
shlwapi.dll	Shell Light-weight Utility Library	Microsoft Corporation	C:\Windows\System32\shlwapi.dll
SortDefault.nls			\Device\HarddiskVolume134\Windows\Globalization\Sorting\SortDefault.nls
user32.dll	Multi-User Windows USER API Client DLL	Microsoft Corporation	C:\Windows\System32\user32.dll
user32.dll.mui			\Device\HarddiskVolume134\Windows\System32\en-US\user32.dll.mui
uxtheme.dll	Microsoft UxTheme Library	Microsoft Corporation	C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\uxtheme.dll
windows.storage.dll	Microsoft WinRT Storage API	Microsoft Corporation	C:\Windows\System32\windows.storage.dll
wininet.dll	Internet Extensions for Win32	Microsoft Corporation	C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\wininet.dll
ws2_32.dll	Windows Socket 2.0 32-Bit DLL	Microsoft Corporation	C:\Windows\System32\ws2_32.dll
wsock32.dll	Windows Socket 32-Bit DLL	Microsoft Corporation	C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\wsock32.dll

のようにファイルが様々なパスからロードされていることがわかる。ホストからはWindows\Images以下のファイルが見える。これはコンテナ内でも同様でありコンテナ内からCygwinのpsコマンドでプロセスを一覧すると:

      PID    PPID    PGID     WINPID   TTY         UID    STIME COMMAND
        4       0       0          4  ?              0 04:05:38 System
     5728       0       0       5728  ?              0 08:26:55 C:\Windows\System32\smss.exe
     5572       0       0       5572  ?              0 08:26:55 C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\csrss.exe
      996       0       0        996  ?              0 08:27:01 C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\wininit.exe
     5392       0       0       5392  ?              0 08:27:03 C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\services.exe
     5804       0       0       5804  ?              0 08:27:03 C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\lsass.exe
     5768       0       0       5768  ?              0 08:27:04 C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\svchost.exe
     5068       0       0       5068  ?              0 08:27:04 C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\svchost.exe
     5280       0       0       5280  ?              0 08:27:04 C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\svchost.exe
      200       0       0        200  ?              0 08:27:04 C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\svchost.exe
     3328       0       0       3328  ?              0 08:27:05 C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\svchost.exe
     3768       0       0       3768  ?              0 08:27:05 C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\svchost.exe
     4064       0       0       4064  ?              0 08:27:05 C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\svchost.exe
     1700       0       0       1700  ?              0 08:27:05 C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\svchost.exe
     5816       0       0       5816  ?              0 08:27:05 C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\CExecSvc.exe
     6012       0       0       6012  ?              0 08:27:06 C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\cmd.exe
     4720       0       0       4720  ?              0 08:28:16 C:\ProgramData\docker\windowsfilter\6b3ee63a1aa54af2e4d809df5fe118db83833efc279bef6775ba75b19f247620\Files\setup-x86_64.exe
     2072       0       0       2072  ?              0 08:29:06 C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\msdtc.exe
      820       0       0        820  ?              0 08:29:08 C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\sppsvc.exe
     5092       0       0       5092  ?              0 08:29:14 C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\SppExtComObj.Exe
     3144       0       0       3144  ?              0 08:42:01 C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\lpremove.exe
     2368       0       0       2368  ?              0 08:42:01 C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\conhost.exe
     3616       0       0       3616  ?              0 08:42:01 C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\lpksetup.exe
      156       0       0        156  ?              0 08:46:34 C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10514.0\Files\Windows\System32\wbem\WmiPrvSE.exe
     5108       1    5108       5108  ?             18 08:55:54 /usr/bin/ps

のようにホスト上のパスがそのまま得られる。基本的にWindows Server Containerは対象プロセスを信頼することが前提になっており、通常のContainerと同様のレベルのアイソレーションを期待するならば、Hyper-V Containersを使うべきと言える。
PID空間もホストと共有している。また、コンテナ毎にwininitが起動し付随するサービスが起動するのもちょっともったいない。。

PIDはアイソレーションされていないものの、ファイルシステムツリーやネットワークはアイソレーションされて見える。コンテナ側(右)ではipconfigコマンドで列挙されるインターフェースがvEthernetだけになっている。

コンテナ操作インターフェースとしてのDocker

Docker自体は明確にPlatform agnosticなコンテナランタイムとしての方向性を志向している。DockerのWindowsサポートはその傾向の最も先鋭的なもので、当然Linux用のコンテナイメージは実行できないし、そもそもどれだけのアプリケーションがDocker hubエコシステムに入ってこれるのかも謎と言える。(現状のシステムだとイメージを再配布するとWindows毎再配布することになる可能性が高い)
Linux以外のDockerとして他にFreeBSD上のDockerがある。これはZFS上にイメージが実現されている等Linuxとの実装上の違いは有るが、FreeBSD-CURRENTにはLinux64エミュレーションが入っているのでこちらはLinuxコンテナを実行することもできる。

というかVisual Studio Tools for docker( https://visualstudiogallery.msdn.microsoft.com/0f5b2caa-ea00-41c8-b8a2-058c7da0b3e4 )とかWindows Server 2016で同時に導入されるNano Serverが事実上ASP.NETをターゲットにしていて、sysinternalsのMark Russinovichは現在Azure領域のCTOをやっていることからも判るように、Azureで動くASP.NETがDockerサポートのプライマリターゲットなのだろう。
MarkRの記事では、

Dockerのオーケストレーションの活用等に触れている。
もちろんHyper-Vが最初にServerで導入されその後クライアント版にも導入されたように、Windows Server Containerもクライアントサポートを望みたいところではあるが。。