✍️

Dockerのuserns-remapが有効な環境でボリュームマウントの書き込みに失敗する

に公開

TL;DR

  • 現象: コンテナ内でrootなのにマウントしたボリュームに書き込めない
  • 原因: userns-remapによりコンテナ内のUID=0がホスト上では別のUID(例: 165536)にマッピングされている
  • 解決策: ホストディレクトリの所有者をマッピング後のUIDに変更する

問題

ホストの/mnt/shared/storageをコンテナ内の/app/storageにマウントしたところ、書き込みがPermission deniedで失敗した。

ホスト側

$ ls -al /mnt/shared/
drwxr-xr-x 2 app-user app-user 1 Dec 11 16:43 storage

ディレクトリはapp-userが所有しており、パーミッションは755。

コンテナ内

root@container:/app# id
uid=0(root) gid=0(root) groups=0(root)

root@container:/app# ls -al storage/
drwxr-xr-x 2 nobody nogroup 1 Dec 11 07:43 .

root@container:/app# mkdir storage/test
mkdir: cannot create directory 'storage/test': Permission denied

コンテナ内ではrootなのに書き込めない。所有者がnobody:nogroupと表示されている。

原因

docker infoでuserns-remapの設定を確認する。

$ docker info | grep -i userns
  userns

Security Optionsにusernsが含まれていれば、userns-remapが有効になっている。

マッピング先のUID/GIDは/etc/subuid/etc/subgidで確認できる。

$ cat /etc/subuid
app-user:165536:65536

$ cat /etc/subgid
app-user:165536:65536

userns-remapが有効な場合、コンテナ内のUID/GID=0はホスト上では165536にマッピングされる。ホストディレクトリの所有者はapp-userなので、UID=165536からは書き込めない。

解決策

ホストディレクトリの所有者をマッピング後のUID/GIDに変更する。

sudo chown 165536:165536 /mnt/shared/storage
sudo chmod 700 /mnt/shared/storage

確認:

# ホスト側
$ ls -aln /mnt/shared/storage
drwx------ 165536 165536 ... storage

# コンテナ内
root@container:/app# ls -al storage/
drwx------ 12 root root 11 Dec 11 13:51 .

ホスト側ではUID=165536として見え、コンテナ内ではrootとして見えるようになった。

参考

https://docs.docker.com/engine/security/userns-remap/

https://man7.org/linux/man-pages/man5/subuid.5.html

タケユー・ウェブ株式会社

Discussion