web-dev-qa-db-ja.com

ホスト上のNFSマウントを表示し、Dockerコンテナー内で読み書き可能にする

私はDockerを初めて使用するので、それを使用して、コードの制御されたコンパイル環境を取得します。

必要なすべてのツールを備えたDockerイメージをすでに持っています。現時点での私の問題は次のとおりです。

  • ホストマシンの、NFSサーバーからマウントされたホームフォルダー内にコードがあります。
  • このフォルダーをDockerコンテナー内にr + w権限で表示したい

これが私が最初に試したもの(ソースフォルダーをボリュームとしてコンテナーを実行)と私が得るエラーです:

[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

私はそれを正しくやっていますか?何が欠けていますか?

追加情報:

  • OS:CentOS Linux 7.6
  • Dockerバージョン:1.13.1

更新(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$
4
mbrandalero

更新で指摘したように、ファイルの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"
  ...
4
BMitch

コンテナーを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/

0
spaceman spiff