Windowsコンテナでボリュームを割り当てる際の注意点

# 概要

Windowsコンテナ(Windows Server Core)でボリュームを割り当てる際の注意点について記載します。

# 対象者

* Docker for Windows を利用する
* Windowsコンテナを利用する
* ボリュームの割り当てを行う

# 内容

まず、WindowsコンテナはLinuxコンテナと違ってボリュームの割り当て方やエラーメッセージが非常に分かりにくくなっています。
以下に実際のコマンドと表示されるエラーメッセージについてご紹介します。

はじめにWindowsコンテナのイメージを `docker pull` コマンドで取得します。
イメージが正しくpullされていることを `docker images` コマンドで確認します。

```
> docker pull microsoft/windowsservercore:ltsc2016

> docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
microsoft/windowsservercore   ltsc2016            0534c30e0e3e        3 months ago        10.9GB
```

イメージの存在を確認後、コンテナの起動とボリュームの割り当てを行います。
コンテナの起動は `docker run` コマンド、ボリュームの割り当ては `-v` オプションから指定します。

ホスト側はカレントフォルダ、コンテナ側はCドライブのドライブルートを割り当ててみます。

```
> docker run --rm -it -v .:c:\ 053 cmd
docker: Error response from daemon: invalid volume specification: '.:c:\': invalid mount config for type "volume": destination path cannot be `c:` or `c:\`: c:\.
See 'docker run --help'.
```

何やらボリュームの指定が正しくないエラーメッセージが表示されました。
エラーメッセージにあるように `c:` `c:\` は使えないようなので `c:\.` で試してみます。

```
> docker run --rm -it -v .:c:\. 053 cmd
docker: Error response from daemon: create .: volume name is too short, names should be at least two alphanumeric characters.
See 'docker run --help'.
```

今度はホスト側のカレントフォルダの指定が正しくないエラーとなりました。
最低でも2文字以上の英数字を含む必要があるようです。

コマンドプロンプトでカレントフォルダを表す `%cd%` 変数を利用してカレントフォルダを絶対パスで指定してみます。

```
> docker run --rm -it -v %cd%:c:\. 053 cmd
docker: Error response from daemon: container d77570804178a497efb3dc869b7df94ba3a907d197e3b30ba69f9ac071bb7934 encountered an error during Start: failure in a Windows system call: The compute system exited unexpectedly. (0xc0370106).
```

ホスト側の指定は正しく認識され、エラーメッセージの内容が変わりました。
ボリュームの指定方法は正しいようですが、今度は謎のWindowsのシステムコールのエラーとなりました。
詳しいエラーの内容についてはエラーメッセージからは読み取ることができません。

このエラーを解消するのには苦労しましたが、実はLinuxコンテナと違ってWindowsコンテナは既に存在するフォルダを指定してしまうとシステムコールのエラーメッセージが表示されてしまいます。

既に存在するフォルダとして `c:\windows` の指定も試してみます。

```
> docker run --rm -it -v %cd%:c:\windows 053 cmd
docker: Error response from daemon: container 8143fc5476555ff229a837dd2fa96b813486930f57371d3c3f32164fe79095ca encountered an error during Start: failure in a Windows system call: The compute system exited unexpectedly. (0xc0370106).
```

先ほどと同様のエラーメッセージとなりました。
今度は存在しないフォルダの指定を試してみます。

```
> docker run --rm -it -v %cd%:c:\test 053 cmd
```

存在しないフォルダを指定したところ、無事にコンテナを起動することができました。

存在するフォルダを指定した場合にエラーとなってしまう原因については、コンテナに入ってみると分かりますが、先ほど割り当てた `test` フォルダが `<SYMLINKD>` となっています。

つまり、Windowsコンテナではボリュームの割り当てをシンボリックリンクで実現しているということです。
Windowsの仕様として、既に存在するフォルダに対してはシンボリックリンクは作成できません。
そのため、コンテナ起動時に呼び出されるシンボリックリンクの作成処理でエラーが発生し、Docker for Windowsではシステムコールのエラーとして扱ってしまうようです。システムコールではなくもう少し分かりやすい形でエラーメッセージを表示してくれるといいのですが。

Linuxコンテナでは存在するディレクトリに対してもボリュームの割り当てを行うことができますが、Windowsコンテナではできないので注意が必要です。

```
C:\>dir
 Volume in drive C has no label.
 Volume Serial Number is 40B2-E002

 Directory of C:\

11/23/2016  07:45 AM             1,894 License.txt
09/10/2018  03:43 AM    <DIR>          PerfLogs
12/18/2018  11:22 AM    <DIR>          Program Files
07/16/2016  10:18 PM    <DIR>          Program Files (x86)
12/18/2018  11:22 AM    <SYMLINKD>     test [\\?\ContainerMappedDirectories\17799130-1A60-4B18-81E1-18B2B33774D2]
09/10/2018  03:54 AM    <DIR>          Users
10/05/2018  05:07 PM    <DIR>          Windows
               1 File(s)          1,894 bytes
               6 Dir(s)  21,197,295,616 bytes free
```

また、以下のようにボリュームの割り当てをたくさん(今回は50個)行った際にも何故かシステムコールのエラーとなるため注意が必要です。
解決方法は今のところ不明なので、ボリュームの割り当て数を減らす方向での対応が必要となります。

```
> docker run --rm -it -v %cd%:c:\test1 -v %cd%:c:\test2 -v %cd%:c:\test3 -v %cd%:c:\test4 -v %cd%:c:\test5 -v %cd%:c:\test6 -v %cd%:c:\test7 -v %cd%:c:\test8 -v %cd%:c:\test9 -v %cd%:c:\test10 -v %cd%:c:\test11 -v %cd%:c:\test12 -v %cd%:c:\test13 -v %cd%:c:\test14 -v %cd%:c:\test15 -v %cd%:c:\test16 -v %cd%:c:\test17 -v %cd%:c:\test18 -v %cd%:c:\test19 -v %cd%:c:\test20 -v %cd%:c:\test21 -v %cd%:c:\test22 -v %cd%:c:\test23 -v %cd%:c:\test24 -v %cd%:c:\test25 -v %cd%:c:\test26 -v %cd%:c:\test27 -v %cd%:c:\test28 -v %cd%:c:\test29 -v %cd%:c:\test30 -v %cd%:c:\test31 -v %cd%:c:\test32 -v %cd%:c:\test33 -v %cd%:c:\test34 -v %cd%:c:\test35 -v %cd%:c:\test36 -v %cd%:c:\test37 -v %cd%:c:\test38 -v %cd%:c:\test39 -v %cd%:c:\test40 -v %cd%:c:\test41 -v %cd%:c:\test42 -v %cd%:c:\test43 -v %cd%:c:\test44 -v %cd%:c:\test45 -v %cd%:c:\test46 -v %cd%:c:\test47 -v %cd%:c:\test48 -v %cd%:c:\test49 -v %cd%:c:\test50 053 cmd
docker: Error response from daemon: container b38aaecd69bdcd1871e0f99981c16e9503f5ac2d8e4285995eac073e7700327b encountered an error during Start: failure in a Windows system call: The compute system exited unexpectedly. (0xc0370106).
```