Dockerコンテナの既存ディレクトリにマウントしたら,オーナやパーミションがどうなるか
環境
- ubuntu 20.04
- Docker Engine - Community 20.10
調べたこと
Dockerの既存ディレクトリにバインドマウントやボリュームマウントを使った際に, オーナやパーミションがどうなるのか調べました.
結果
- バインドマウントの場合,ホストのオーナとパーミションのままになります.
- ボリュームマウントの場合,ボリュームが空かどうかに依って挙動が変わります.
- マウントするボリュームが空である場合, コンテナのオーナ,パーミションに変更されます.(コンテナの既存ディレクトリが,中にあるファイル含めてまるごとボリュームにコピーされます.)
- マウントするボリュームが空でない(中にファイルが存在する)場合, ホストのオーナとパーミションのままになります.
コンテナのマウント先ディレクトリを空にしたいかどうか, コンテナのマウント先ディレクトリの状態を元にボリュームを作りたいかどうか などによって使い分けるのがよさそうです.
ちなみに,マウント先のディレクトリが存在しない場合,当然ながら,バインドマウントでもボリュームマウントでも,ホストのオーナとパーミションのままになります.
調査ログ
準備
マウント先のディレクトリを持つイメージを作っておきます.
FROM busybox
RUN adduser -D -u 42 cuser
RUN mkdir -p /work_existing
RUN chown cuser:cuser /work_existing
RUN chmod go+w /work_existing
RUN ls -ld /work_existing
RUN ls -ldn /work_existing
$ sudo docker build -t dir-inspection .
Sending build context to Docker daemon 18.94kB
Step 1/7 : FROM busybox
---> beae173ccac6
Step 2/7 : RUN adduser -D -u 42 cuser
---> Running in 06ac9d263762
Removing intermediate container 06ac9d263762
---> 39dc849cbbea
Step 3/7 : RUN mkdir -p /work_existing
---> Running in c6663ee5467f
Removing intermediate container c6663ee5467f
---> f7139cac2de2
Step 4/7 : RUN chown cuser:cuser /work_existing
---> Running in fea9cc3c5c60
Removing intermediate container fea9cc3c5c60
---> 6630bd739fcb
Step 5/7 : RUN chmod go+w /work_existing
---> Running in 15afb53ec001
Removing intermediate container 15afb53ec001
---> 69765c0256c3
Step 6/7 : RUN ls -ld /work_existing
---> Running in 911003bbe88f
drwxrwxrwx 1 cuser cuser 4096 Jan 22 10:34 /work_existing
Removing intermediate container 911003bbe88f
---> 4b710f9e9714
Step 7/7 : RUN ls -ldn /work_existing
---> Running in 251032f6b2d1
drwxrwxrwx 1 42 42 4096 Jan 22 10:34 /work_existing
Removing intermediate container 251032f6b2d1
---> 40919782236a
Successfully built 40919782236a
Successfully tagged dir-inspection:latest
バインドマウント
バインド用のホストのディレクトリを作ります.
$ mkdir hoge
$ ls -ld hoge
drwxrwxr-x 2 vagrant vagrant 4096 Jan 22 10:36 hoge
$ ls -ldn hoge
drwxrwxr-x 2 1000 1000 4096 Jan 22 10:36 hoge
コンテナに存在しないパスにマウントしてみます.
$ sudo docker run -it --rm -v $PWD/hoge:/work dir-inspection
/ # ls -ld /work
drwxrwxr-x 2 1000 1000 4096 Jan 22 10:36 /work
/ # ls -ldn /work
drwxrwxr-x 2 1000 1000 4096 Jan 22 10:36 /work
当然ながらホストと同じオーナとパーミションになりました.
つぎに,コンテナに存在するパス(ホストとオーナ,パーミションが異なる)にマウントしてみます.
$ sudo docker run -it --rm -v $PWD/hoge:/work_existing dir-inspection
/ # ls -ld /work_existing/
drwxrwxr-x 2 1000 1000 4096 Jan 22 10:36 /work_existing/
/ # ls -ldn /work_existing/
drwxrwxr-x 2 1000 1000 4096 Jan 22 10:36 /work_existing/
これも,ホストと同じオーナとパーミションになりました.
ボリュームマウント(手動作成したボリューム)
ボリュームを手動で作ります.
$ sudo docker volume create vol_hoge
vol_hoge
$ sudo docker volume inspect vol_hoge
[
{
"CreatedAt": "2022-01-22T10:42:37Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/vol_hoge/_data",
"Name": "vol_hoge",
"Options": {},
"Scope": "local"
}
]
$ sudo ls -ld /var/lib/docker/volumes/vol_hoge/_data
drwxr-xr-x 2 root root 4096 Jan 22 10:42 /var/lib/docker/volumes/vol_hoge/_data
$ sudo ls -ldn /var/lib/docker/volumes/vol_hoge/_data
drwxr-xr-x 2 0 0 4096 Jan 22 10:42 /var/lib/docker/volumes/vol_hoge/_data
オーナはrootで作成されました.
これを,コンテナに存在しないパスにマウントしてみます.
$ sudo docker run -it --rm -v vol_hoge:/work dir-inspection
/ # ls -ld /work
drwxr-xr-x 2 root root 4096 Jan 22 10:42 /work
/ # ls -ldn /work
drwxr-xr-x 2 0 0 4096 Jan 22 10:42 /work
当然ながらホストと同じオーナとパーミションになりました.
つぎに,コンテナに存在するパス(ホストとオーナ,パーミションが異なる)にマウントしてみます.
$ sudo docker run -it --rm -v vol_hoge:/work_existing dir-inspection
/ # ls -ld /work_existing/
drwxrwxrwx 2 cuser cuser 4096 Jan 22 10:34 /work_existing/
/ # ls -ldn /work_existing/
drwxrwxrwx 2 42 42 4096 Jan 22 10:34 /work_existing/
/ # exit
$ sudo ls -ld /var/lib/docker/volumes/vol_hoge/_data
drwxrwxrwx 2 42 shadow 4096 Jan 22 10:34 /var/lib/docker/volumes/vol_hoge/_data
$ sudo ls -ldn /var/lib/docker/volumes/vol_hoge/_data
drwxrwxrwx 2 42 42 4096 Jan 22 10:34 /var/lib/docker/volumes/vol_hoge/_data
コンテナに存在するパスのオーナとパーミションに変更されました. ホスト上でもオーナとパーミションが変わったことが確認できます.
これはDockerのドキュメントにあるように,コンテナの内容がコピーされたということだと思います.
cf. Docker におけるデータ管理 | Docker ドキュメント
コンテナー内のディレクトリに 空のボリューム をマウントしようとしていて、そのディレクトリ内にファイルやディレクトリが存在する場合、そのファイルやディレクトリはボリューム内にコピーされます。 コンテナー起動時に指定したボリュームがまだ存在していなかった場合は、空のボリュームが生成されます。 コンテナーの求めに応じて事前にデータを提供しておく方法として用いられます。
ドキュメントには「そのディレクトリ内にファイルやディレクトリが存在する場合」とありますが,ファイルやディレクトリが存在しなくても,マウント先のディレクトリ自体のオーナ,パーミションはコピーされるようです.
ボリュームマウント(自動作成されるボリューム)
コンテナに存在しないパスにマウントしてみます.
$ sudo docker run -it --rm -v vol_hoge_auto:/work dir-inspection
/ # ls -ld /work
drwxr-xr-x 2 root root 4096 Jan 22 10:50 /work
/ # ls -ldn /work
drwxr-xr-x 2 0 0 4096 Jan 22 10:50 /work
/ # exit
$ sudo docker volume inspect vol_hoge_auto
[
{
"CreatedAt": "2022-01-22T10:50:57Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/vol_hoge_auto/_data",
"Name": "vol_hoge_auto",
"Options": null,
"Scope": "local"
}
]
$ sudo ls -ld /var/lib/docker/volumes/vol_hoge_auto/_data
drwxr-xr-x 2 root root 4096 Jan 22 10:50 /var/lib/docker/volumes/vol_hoge_auto/_data
$ sudo ls -ldn /var/lib/docker/volumes/vol_hoge_auto/_data
drwxr-xr-x 2 0 0 4096 Jan 22 10:50 /var/lib/docker/volumes/vol_hoge_auto/_data
オーナはrootで作成され,ホストと同じオーナとパーミションになりました. (手動作成した場合と同様.)
つぎに,コンテナに存在するパス(ホストとオーナ,パーミションが異なる)にマウントしてみます.
$ sudo docker run -it --rm -v vol_hoge_auto:/work_existing dir-inspection
/ # ls -ld /work_existing/
drwxrwxrwx 2 cuser cuser 4096 Jan 22 10:34 /work_existing/
/ # ls -ldn /work_existing/
drwxrwxrwx 2 42 42 4096 Jan 22 10:34 /work_existing/
/ # exit
$ sudo ls -ld /var/lib/docker/volumes/vol_hoge_auto/_datals
ls: cannot access '/var/lib/docker/volumes/vol_hoge_auto/_datals': No such file or directory
$ sudo ls -ld /var/lib/docker/volumes/vol_hoge_auto/_data
drwxrwxrwx 2 42 shadow 4096 Jan 22 10:34 /var/lib/docker/volumes/vol_hoge_auto/_data
$ sudo ls -ldn /var/lib/docker/volumes/vol_hoge_auto/_data
drwxrwxrwx 2 42 42 4096 Jan 22 10:34 /var/lib/docker/volumes/vol_hoge_auto/_data
これも,手動作成した場合と同様に,コンテナに存在するパスのオーナとパーミションに変更されました.
ボリュームが空でない場合
手動作成したボリュームにデータを入れた上で, コンテナに存在するパス(ホストとオーナ,パーミションが異なる)にマウントしてみました.
$ sudo docker volume create vol_hoge_with_file
vol_hoge_with_file
$ sudo docker run -it --rm -v vol_hoge_with_file:/work busybox
/ # touch /work/piyo
/ # exit
$ sudo docker run -it --rm -v vol_hoge_with_file:/work_existing dir-inspection
/ # ls -ld /work_existing/
drwxr-xr-x 2 root root 4096 Jan 22 11:07 /work_existing/
/ # ls -ldn /work_existing/
drwxr-xr-x 2 0 0 4096 Jan 22 11:07 /work_existing/
/ # exit
空のボリュームの場合と異なり,ホストのオーナとパーミションは変更されず,そのままになりました.