私はDockerを初めて使用するので、それを使用して、コードの制御されたコンパイル環境を取得します。
必要なすべてのツールを備えたDockerイメージをすでに持っています。現時点での私の問題は次のとおりです。
これが私が最初に試したもの(ソースフォルダーをボリュームとしてコンテナーを実行)と私が得るエラーです:
[mbrandalero@machine ~]$ docker run -it --cap-add sys_admin -v "/homes/mbrandalero/src:/usr/local/src/" mbrandalero/my-image bash
/usr/bin/docker-current: Error response from daemon: error while creating mount source path '/homes/mbrandalero/src': mkdir /homes/mbrandalero/src: permission denied.
(どうやらそれはホスト側にディレクトリを作成しようとしていますが、すでにそこにあります)
不思議なことに、ホームフォルダー全体をボリュームとしてコンテナーを実行しようとすると、機能しますが別のエラーが発生します(フォルダーに書き込み権限がない)。
[mbrandalero@machine ~]$ docker run -it --cap-add sys_admin -v "/homes/mbrandalero/:/usr/local/src/home" mbrandalero/my_image bash
root@46712ad936f2:/usr/local/src# cd home/
bash: cd: home/: Permission denied
root@46712ad936f2:/usr/local/src# ls -lah | grep "\(\.\|home\)"
total 4.0K
drwxr-xr-x 1 root root 18 May 20 14:50 .
drwxr-xr-x 1 root root 17 May 15 14:06 ..
drwxr-x--- 30 10031 10031 4.0K May 20 15:03 home
私はそれを正しくやっていますか?何が欠けていますか?
追加情報:
更新(1):
docker run
の実行中にユーザーIDを設定すると問題が解決するようですが、これは正しい方法ですか?このように修正された方法で実行すると、奇妙に見えます(ユーザー名として「I have no name!」と表示されます)。
[mbrandalero@machine ~]$ docker run -it --cap-add sys_admin -v "/homes/mbrandalero/:/usr/local/src/home" --user $(id -u) mbrandalero/my_image bash
I have no name!@2efec822e572:/usr/local/src$ cd home/
I have no name!@2efec822e572:/usr/local/src/home$
更新で指摘したように、ファイルのUIDはバインドマウントにマッピングされていません。これがLinuxがバインドマウントを行う方法です。コンテナーを別のUIDで開始することもできますが、これによりコンテナー内の/ etc/passwdが別のユーザーにマッピングされるか、(ユーザーの場合は)ユーザーにマッピングされなくなります。さまざまなオプションがありますが、私の好みは、私の fix-perms script を使用して、イメージのエントリポイント内で実行されるusermodコマンドでコンテナのUIDを変更することです。これはルートとして実行する必要がありますが、コマンドを実行するときにgosu
を使用してユーザーにドロップダウンできます。私はこれについて dockerconプレゼンテーション で話しました。
ホストNFSディレクトリへのバインドマウントの代わりに、NFSサーバーに直接ボリュームマウントを行うこともできます。これを行う方法のいくつかの例を次に示します。
# create a reusable volume
$ docker volume create --driver local \
--opt type=nfs \
--opt o=nfsvers=4,addr=nfs.example.com,rw \
--opt device=:/path/to/dir \
foo
# or from the docker run command
$ docker run -it --rm \
--mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=nfs,\"volume-opt=o=nfsvers=4,addr=nfs.example.com\",volume-opt=device=:/Host/path \
foo
# or to create a service
$ docker service create \
--mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=nfs,\"volume-opt=o=nfsvers=4,addr=nfs.example.com\",volume-opt=device=:/Host/path \
foo
# inside a docker-compose file
...
volumes:
nfs-data:
driver: local
driver_opts:
type: nfs
o: nfsvers=4,addr=nfs.example.com,rw
device: ":/path/to/dir"
...
コンテナーをroot
として実行している場合、NFSホストがすべてのリモートルートUID(別名、ルートスカッシュ)を再マップしているため、error while creating mount source path ... permission denied
メッセージに遭遇することがあります。
https://en.wikipedia.org/wiki/Unix_security#Root_squash
これはセキュリティを重視した機能であり、悪意のあるアクターが自分のroot
ユーザーとして共有をマウントし、データを悪用することを防ぎます。そのため、NFSマウントでは通常、これらのタイプの問題を防ぐために、デフォルトでroot_squash
オプションが設定されています。コンテナーをroot
として実行する必要がある場合は、NFSホストのno_root_squash
ファイルで/etc/exports
オプションを使用してこれをオーバーライドできます。
/srv/nfs/shared_folder <hostname>(rw,sync,no_subtree_check,no_root_squash)
http://nfs.sourceforge.net/nfs-howto/ar01s03.html
https://www.thegeekdiary.com/understanding-the-etc-exports-file/