Dockerは普段macOSで使っているのですが、そういえばDocker for WindowsがGAされて久しいです。ふつうにLinuxコンテナが動かせるのはWSLとは違うコンテナとしての良さに満ちてていいものです。
docker run -it centos /bin/bash
とはいえDocker for Windowsは、触るたびにHyper-Vをはじめとしていくつかの特徴的な挙動で難しく感じます。
さて、今回はAzureADでログインしているWindowsにおいて、DockerのShared Driveが上手く使えない症状に遭遇したので、解消方法をメモしておきます。
見つけるまで結構悩んでしまったので、ほかの方が同様の症状で悩まれているとき役立てば幸いです。
更新
2020年6月時点で、最新Docker Desktop for Windowsにて修正されています。やったね!
概要
Dockerはホストのドライブをコンテナで共有する機能があります。Docker for Windowsの場合は、SMB (TCP445) を使います。(SMB/CIFS)
これにより、ホストのファイル更新をコンテナと共有が可能だったり、ログ処理したりが可能になります
環境
Docker for Windows 17.09.1-ce-win42
Share Drive 方法
Docker for Windows > Settings > Shared Drivesに行きます。ここで共有したいドライブを有効にします。
- シェアしていない状態

- シェアした状態

うまくいきましたか? やりましたね! 完璧です。そのまま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ルールからしてセキュアに守られる)

Hyper-Vではない、自分のイーサネットやWifiのネットワークコネクションのプロファイルをプライベートネットワークに変更する場合は、PowerShell上で以下でさくっとできます。*1
# 対象のId を確認しましょう。 Get-NetConnectionProfile $id = "対象のConnectionIdをどうぞ" Set-NetConnectionProfile -NetworkCategory Private -InterfaceIndex $id
うまくホストのネットワークがプライベートになりましたか?

Firewall
Firewallの警告が出た場合はこのケースがあり得ます。
Firewallで弾かれる場合はTCP 445のコンテナip 10.0.75.1からのアクセスになっているDockerSmbMountのエントリが許可になっていますか?

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

もしアンチマルウェアを使っていらしゃる場合は、そのソフトのブロックを解除してあげるか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をご自身のユーザー名に置き換えてください

参考
- Windows 10: Docker for Windows: unable to share drive #690
- Unable to share C: Drive [firewall] #466
- Can't share drive. mounting .../C on /c failed: Invalid argument #646
- Can't share drive on domain account #313
- Sharing drives does not work for Azure AD user accounts #132 -Configuring Docker for Windows Shared Drives / Volume Mounting with AD
- Docker Troubleshooting SMB shares creation, mounting and related issues on Windows