ホスト上の NFS マウントを Docker コンテナ内で表示および読み取り/書き込み可能にする

ホスト上の NFS マウントを Docker コンテナ内で表示および読み取り/書き込み可能にする

私は 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: Linux 7.6
  • Docker バージョン: 1.13.1

更新(1):

実行時にユーザー ID を設定するとdocker run問題が解決するようです。しかし、これは正しい方法でしょうか? この方法で実行すると、問題はある程度解決しましたが、見た目がおかしくなっています (ユーザー名として「名前がありません!」と表示されます):

[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$

答え1

アップデートで指摘されているように、ファイルの UID はバインドマウントにマッピングされません。これは Linux がバインドマウントを行う方法です。別の UID でコンテナを起動することもできますが、コンテナ内の /etc/passwd が別のユーザーにマッピングされるか、または (あなたの場合) ユーザーにマッピングされなくなります。さまざまなオプションがありますが、私の好みは、イメージのエントリポイント内で実行される 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"
  ...

答え2

コンテナを として実行している場合、 NFS ホストがすべてのリモート ルート UID (別名 root-squash) を再マッピングしているため、rootこのメッセージが表示されることがあります。error while creating mount source path ... permission denied

https://en.wikipedia.org/wiki/Unix_security#ルートスカッシュ

これは、悪意のある人物が自分のユーザーとして共有をマウントしroot、データに対して不正行為を行うことを防ぐためのセキュリティ重視の機能です。そのため、NFS マウントでは通常root_squash、この種の問題を防ぐために、オプションがデフォルトで設定されています。コンテナーを として実行する必要がある場合は、 NFS ホストのファイルで オプションrootを使用してこれを上書きできます。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/

答え3

これは私の場合はうまくいきました - ホスト NFS パスをコンテナへのボリュームとして宣言しました。また、ホスト NFS パスは非ホーム ディレクトリ パスであり、ホーム ディレクトリではありません。

私のホストの NFS マウント ポイント:/mnt/abc

私の docker-compose.yml ファイル スニペット。

   ...
   volumes:
  - /mnt/abc/:/abc
   ...

関連情報