tech.guitarrapc.cóm

C#, PowerShell, Swift, Cloud, Serverless Technical Update and Features

AzureAD ログインと Docker for Windows Shared Drive によるボリュームマウント

Docker は普段 macOS で使っているのですが、そういえば Docker for Windows がGAされて久しいです。ふつうに Linux コンテナが動かせるのは WSL とは違うコンテナとしての良さに満ちてていいものです。

docker run -it centos /bin/bash

とはいえ Docker for Windows は、触るたびにHyper-V をはじめとしていくつかの特徴的な挙動で難しく感じます。

さて、今回は AzureAD でログインしている Windows において、Docker の Shared Drive が上手く使えない症状に遭遇したので、解消方法をメモしておきます。

見つけるまで結構悩んでしまったので、もしほかの方が同様の症状にあった時にうまくいくヒントとなることを祈ります。

目次

概要

Docker はホストのドライブをコンテナで共有する機能があります。Docker for Windows の場合は、SMB (TCP445) を使います。(SMB/CIFS)

これにより、ホストのファイル更新でコンテナと共有が可能だったり、ログ処理したりが可能になります

環境

Docker for Windows 17.09.1-ce-win42

Share Drive 方法

Docker for Windows for Windows > Settings > Shared Drives に行きます。ここで共有したいドライブを有効にします。

  • シェアしていない状態

f:id:guitarrapc_tech:20171227034308p:plain

  • シェアした状態

f:id:guitarrapc_tech:20171227034316p:plain

うまくいきましたか? やりましたね!完璧です。そのまま docker run -v を楽しみましょう。

docker run --rm -v c:/Users:/data alpine ls /data

単純にこれで済む場合は、local User でログインしている Administrators 権限を持っているケースか、AD でログインしていて適切に権限が付与されているケースが経験あります。

注意点

Network Connection Profile

もし自ネットワークプロファイルが private でない場合は、Private にしておきます。ただ、Hyper-V のプロファイルはパブリックネットワークで構いません。

自宅や職場で guest or public netrowk は、相応の理由がない場合はちょっと困ったことを引き起こしやすいです。(Firewall ルールからしてセキュアに守られる)

f:id:guitarrapc_tech:20171227034625p:plain

Hyper-V ではない、自分のイーサネットやWifi のネットワークコネクションのプロファイルを プライベートネットワークに変更する場合は、PowerShell 上で以下でさくっとできます。*1

# 対象のId を確認しましょう。
Get-NetConnectionProfile
$id = "対象のConnectionIdをどうぞ"
Set-NetConnectionProfile -NetworkCategory Private -InterfaceIndex $id

うまくホストのネットワークが プライベートになりましたか?

f:id:guitarrapc_tech:20171227035030p:plain

Firewall

Firewall の警告が出た場合はこのケースがあり得ます。

Firewall で弾かれる場合は TCP 445 のコンテナip 10.0.75.1からのアクセスになっている DockerSmbMount のエントリが許可になっていますか?

f:id:guitarrapc_tech:20171227042847p:plain

このコンテナIP 10.0.75.1 は、Docker for Windows > Settings > Network にあるデフォルトの値です。自分でIPを設定されている場合はよきように解釈してください

f:id:guitarrapc_tech:20171227035400p:plain

もしアンチマルウェアを使っていらしゃる場合は、そのソフトのブロックを解除してあげるか White list に追加するといいでしょう。

これで共有ができましたか?

AzureAD の場合

さて、本題です。

AzureAD でログインしたUserにおいては、そのままでは Shared Drives が失敗します。*2Driveのシェアを実行 > 認証を入力 > 数秒で Share がはずれる。という状態です。

ログを見ると原因がわかります。

[11:19:49.606][NamedPipeClient][Info   ] Sending Version()...
[11:19:49.607][NamedPipeClient][Info   ] Received response for Version
[11:19:49.607][NamedPipeServer][Info   ] Version()
[11:19:49.608][NamedPipeClient][Info   ] Sending Mount(C, AzureAD\UserName:**********, Docker.Core.Settings)...
[11:19:49.607][NamedPipeServer][Info   ] Version done in 00:00:00.
[11:19:49.609][NamedPipeServer][Info   ] Mount(C, AzureAD\UserName:**********, Docker.Core.Settings)
[11:19:49.629][SambaShare     ][Info   ] Mount C
[11:19:49.679][Cmd            ][Info   ] この共有リソースは存在しません。
[11:19:49.679][Cmd            ][Info   ] NET HELPMSG 2310 と入力すると、より詳しい説明が得られます。
[11:19:49.681][SambaShare     ][Info   ] "C" is not shared
[11:19:49.681][SambaShare     ][Info   ] Creating share "C:\" as "C" with Full Control to "AzureAD\UserName"
[11:19:49.740][Cmd            ][Info   ] C が共有されました。
[11:19:49.777][Cmd            ][Info   ] 共有名             C
[11:19:49.777][Cmd            ][Info   ] パス               C:\
[11:19:49.777][Cmd            ][Info   ] 注釈               
[11:19:49.777][Cmd            ][Info   ] 最大ユーザー数     制限なし
[11:19:49.777][Cmd            ][Info   ] ユーザー           
[11:19:49.777][Cmd            ][Info   ] キャッシュ         キャッシュは無効
[11:19:49.778][Cmd            ][Info   ] アクセス許可       AzureAD\UserName, FULL
[11:19:49.778][Cmd            ][Info   ] コマンドは正常に終了しました。
[11:19:49.780][SambaShare     ][Info   ] "C" is shared
[11:19:50.700][SambaShare     ][Info   ] Username: UserName
[11:19:50.700][SambaShare     ][Info   ] Host IP: 10.0.75.1
[11:19:50.700][SambaShare     ][Info   ] Cifs options: noperm,iocharset=utf8,nobrl,mfsymlinks,vers=3.02,domain=AzureAD
---- 中略 ----
[11:19:52.190][SambaShare     ][Error  ] Unable to mount C drive: 10.0.75.1 (10.0.75.1:445) open
umount: can't unmount /c: No such file or directory
umount: can't unmount /C: No such file or directory
rmdir: '/c': No such file or directory
rmdir: '/C': No such file or directory
mount error(13): Permission denied
Refer to the mount.cifs(8) manual page (e.g. man mount.cifs)
mount: mounting //10.0.75.1/C on /c failed: Invalid argument

[11:19:52.192][SambaShare     ][Info   ] Removing share C
[11:19:52.244][SambaShare     ][Info   ] Mount C
[11:19:52.273][Cmd            ][Info   ] この共有リソースは存在しません。
[11:19:52.273][Cmd            ][Info   ] NET HELPMSG 2310 と入力すると、より詳しい説明が得られます。
[11:19:52.275][SambaShare     ][Info   ] "C" is not shared
[11:19:52.275][SambaShare     ][Info   ] Creating share "C:\" as "C" with Full Control to "UserName"
[11:19:52.300][ApiProxy       ][Info   ] proxy >> GET /images/sha256:9e4f13a0901e7cdc0c16babf4ebec822828ecae42947c79b69c51e2e22e0470e/json
[11:19:52.300][ApiProxy       ][Info   ] Dial Hyper-V socket 45ef270d-7ba5-4a0c-9633-f0d79d3b0f30:23a432c2-537a-4291-bcb5-d62504644739
[11:19:52.300][ApiProxy       ][Info   ] Successfully dialed Hyper-V socket 45ef270d-7ba5-4a0c-9633-f0d79d3b0f30:23a432c2-537a-4291-bcb5-d62504644739
[11:19:52.302][ApiProxy       ][Info   ] proxy << GET /images/sha256:9e4f13a0901e7cdc0c16babf4ebec822828ecae42947c79b69c51e2e22e0470e/json
[11:19:52.309][Cmd            ][Info   ] システム エラー 1332 が発生しました。
[11:19:52.309][Cmd            ][Info   ] アカウント名とセキュリティ ID の間のマッピングは実行されませんでした。
[11:19:52.311][SambaShare     ][Error  ] Failed to create share "C:\" as "C" with Full Control to "UserName" with code: 2
[11:19:52.341][Cmd            ][Info   ] この共有リソースは存在しません。
[11:19:52.343][NamedPipeClient][Info   ] Received response for Mount
[11:19:52.341][Cmd            ][Info   ] NET HELPMSG 2310 と入力すると、より詳しい説明が得られます。
[11:19:52.343][SambaShare     ][Info   ] "C" is not shared
[11:19:52.343][NamedPipeServer][Info   ] Mount done in 00:00:02.7347295.
[11:19:52.449][ApiProxy       ][Info   ] proxy >> GET /images/sha256:9e4f13a0901e7cdc0c16babf4ebec822828ecae42947c79b69c51e2e22e0470e/json
[11:19:52.449][ApiProxy       ][Info   ] Dial Hyper-V socket 45ef270d-7ba5-4a0c-9633-f0d79d3b0f30:23a432c2-537a-4291-bcb5-d62504644739
[11:19:52.449][ApiProxy       ][Info   ] Successfully dialed Hyper-V socket 45ef270d-7ba5-4a0c-9633-f0d79d3b0f30:23a432c2-537a-4291-bcb5-d62504644739
[11:19:52.450][ApiProxy       ][Info   ] proxy << GET /images/sha256:9e4f13a0901e7cdc0c16babf4ebec822828ecae42947c79b69c51e2e22e0470e/json

原因は アカウント名とセキュリティ ID の間のマッピングは実行されませんでした。 がまさにそれです。要は no mapping between security id ですが、Windows においてこれは Security上の アクセスIdが一致していないことを示します。一度 C: とドライブ共有できているにもかかわらず、なのがなかなか厄介です。 何がセキュリティIdと違うのかというと、 認証時に AzureAD ログインしているときに入れないといけない AzureAD\ が原因です。では、ということで AzureAD\ を除いてユーザー名のみにすると、そんなIdはないので共有自体が失敗します。にもかかわらず、セキュリティIdが一致していない、AzureAD で Windows ログインすることはかなり快適なのですが、こういう問題はたびたびあります。

対処方法は、AzureAD\UserName の UserName だけの ローカルユーザーを作りましょう。ユーザー作成後、Administrators を与えます。これで、AzureAD\UserName で共有後に、UserName も見つかるので正常にドライブ共有が可能になります。

PowerShell ならこうです。

# ここでポップアップがでるので、追加したいユーザーのUsername と Password をいれます。
$credential = Get-Credential
New-LocalUser -AccountNeverExpires -PasswordNeverExpires -UserMayNotChangePassword -Name $credential.UserName -Password $credential.Password
Add-LocalGroupMember -Group Administrators -Member $credential.UserName

もしGUI でやりたい場合、UserName をご自身のユーザー名に置き換えてください

f:id:guitarrapc_tech:20171227042219p:plain f:id:guitarrapc_tech:20171227042230p:plain

参考

*1:管理者権限がいります。ADならDomainAuthenticated なので問題ないはずですが Firewall ルールが問題になる可能性はあります

*2:私は5度やって5度失敗したのでそういうものでしょう