Edited at

Windows Server でのコンテナ/Docker アーキテクチャ

More than 3 years have passed since last update.


はじめに

Windows Server 2016 TP3 で Windows Server Containers と Docker Engine が使えるようになりましたが、そのアーキテクチャは Linux とは大きく異なるように見えます。

大きく違うのは、Linux では Docker Engine に実装されている以下の中心的な機能が、Windows では OS 側に実装されていることです。


  • コンテナの制御(コンテナの作成、開始、停止など)

  • イメージのファイルシステム管理

そのため、Windows では Docker Engine が無くてもコンテナの作成や実行ができます。このあたりのアーキテクチャを調べてみたので、推測込ですが以下にまとめてみます。


アーキテクチャ概観

まず、Linux でのアーキテクチャを見て、Windows と比較してみます。


Linux の場合

Docker Engine 内部では上位のロジックを実装している部分は Daemon と呼ばれ、実際にコンテナの制御を行う部分は Exec Driver や Exection Driver、イメージのファイルシステム管理を行う部分 Graph Driver や Storage Driver などと呼ばれています。

DockerLinux.png

Exec Driver や Graph Driver はプラグイン構造になっており、実際に処理を行うモジュール(ドライバ)を切り替えられるようになっています。


  • Exec Driver

    コンテナの制御を担当。かつては LXC が使われていたが、Docker 0.9 から native ドライバがデフォルト。native ドライバは、コンテナの実処理を行う libcontainer を呼び出している。

  • Graph Driver

    イメージのファイルシステム管理を担当。devicemapper や aufs など複数のドライバがある。

このように、Linux の場合はコンテナ制御やイメージのファイルシステム管理は Docker Engine 内で行われます


Windows の場合

Docker Engine 内の Exec Driver や Graph Driver という仕組み自体は変わらないのですが、それらの実処理は hcsshim というモジュールを経由して OS 側で行われます

全体的なアーキテクチャとしては下図のようになっているようです。

DockerWindows.png

OS 側で処理を行うコンポーネントには Hyper-V という名前が付いていることから、Hyper-V のテクノロジーを利用しているのでしょう。このように処理の本体が OS 側にあるため、Docker Engine がなくても、PowerShell からコンテナの操作が可能になっています。

次に、Windows 上の各コンポーネントの役割をまとめてみます。


Windows での各コンポーネントの役割


Hyper-V Host Compute Service

Windows Server Containers の中心的な役割を担っていると思われるサービス。ファイルの実体は C:\windows\System32\vmcompute.exe。

hcmsvc.png

このサービスの依存関係を見ると、以下の2つのカーネルドライバに依存していることが分かります。

Windows Container Isolation

名前から見て、カーネル側でコンテナを分離する機能(Linux でいう Namespaces相当?)を実装しているようです。

Virtual Registry for Containers

こちらも名前から見て、コンテナ間でレジストリを分離するための機能を実装しているようです。

hcmsvc_drivers.png


Hyper-V Host Compute Service Library

Windows Server Containers の Win32 API を提供している DLL のようです。ファイルの実体は C:\windows\System32\vmcompute.dll です。

この DLL では、例えば以下のような API をエクスポートしており、これらは hcsshim 経由で Docker Engine から呼び出されています。


コンテナ関連のAPI

CreateComputeSystem

StartComputeSystem
WaitForProcessInComputeSystem
ShutdownComputeSystem
TerminateComputeSystem
・・・


ファイルシステム、ストレージ関連のAPI

CreateLayer

ActivateLayer
CopyLayer
CreateSandboxLayer
GetBaseImages
・・・

API 名をみると、Windows ではコンテナのことを ComputeSystem と呼んでいるんですかね。

なお余談ですが、この DLL を利用すれば、C++ や .NET から、Windows Server Containers を制御できるはずです。


hcsshim

Docker Engine から Hyper-V Host Compute Service Library(vmcompute.dll) を呼び出すための橋渡しをするモジュールで、ソースはGitHubで公開されてます

Go言語で書かれた Docker から Win32 API を呼び出すためにパラメータの形式変換などを行っており、vmcompute.dll を呼び出すためのラッパーと言っていいと思います。

ソースのコメントには以下のように書かれているので、Docker Engine から hcsshim 経由で Hyper-V Containers も管理できるようになるのでしょう。


Shim for the Host Compute Service (HSC) to manage Windows Server

containers and Hyper-V containers.



Exec Driver の windows ドライバ

Windows Server 用の Exec Driver。hcsshim 経由で vmcompute.dll を呼び出しながら、コンテナの起動といった処理を上位の Daemon に提供してます。


Graph Driver の windowsfilter/windowsdiff ドライバ

Windows Server 用の Graph Driver。Exec Driver と同じく、hcsshim 経由で vmcompute.dll を呼び出しながら、イメージのレイヤーの作成といった処理を上位の Daemon に提供してます。windowsfilter と windowsdiff の違いは不明。

なお、Exec Driver と Graph Driver(Storage Driver) は、docker info コマンドで実際に使用されているドライバを見ることができます。

DockerInfo.PNG


Docker Engine の役割

このようなアーキテクチャにより Windows では Docker Engine 無しでコンテナの作成や実行ができるわけですが、では Docker Engine の役割は何かというと、現状では Linux の Docker と同じ API やコマンド(run, ps, images ...)といったインターフェイスを提供することに見えます。

また、現在はまだ Docker イメージを使えないようなので(*1)、今後その辺の実装は Docker Engine 側に入ってくるのかもしれません。

*1) Windows では、windowsservercore という名前のイメージがデフォルトで登録されています。

Images.png

これらは、コンテナ環境を構築するスクリプト を実行した際に、http://aka.ms/ContainerOSImage から WIM(Windows イメージング)形式 のファイルがダウンロードされ、それが PowerShell の Install-ContainerOSImage Cmdlet によりインストールされたものです。