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