web-dev-qa-db-ja.com

docker compose v3を使用してコンテナにNFS共有/ボリュームを直接マウントする方法

同じボリュームを共有/使用する3つのサービスがあるv3の構成ファイルがあります。 swarmモードを使用している間、追加のコンテナとボリュームを作成して、クラスター全体でサービスを管理する必要があります。

NFSサーバーを使用して、単一のNFS共有がクラスター内のすべてのホストに直接マウントされるようにする予定です。

私はそれを行う2つの方法を以下に見つけましたが、ドッカーホストで実行するには追加の手順が必要です-

  • ホストで「fstab」または「mount」コマンドを使用してNFS共有をマウントし、それをdockerサービスのホストボリュームとして使用します。

  • Netshareプラグインを使用- https://github.com/ContainX/docker-volume-netshare

Dockerホストでいくつかの手順を実行することで(または「nfs-common」パッケージが必要であることを理解しています)、Docker Compose v3を使用してNFS共有を直接使用/マウントできる標準的な方法はありますか?

22
vivekyad4v

これが非常に文書化されていないことを発見した後、スタックとdocker composeを使用してNFSボリュームをマウントする正しい方法を次に示します。

最も重要なことは、version: "3.2"以上を使用する必要があることです。そうしないと、奇妙で​​明白なエラーが発生します。

2番目の問題は、ボリュームが定義が変更されるとnotが自動的に更新されることです。これにより、変更が適用されていない場合に、変更が正しくないと考えるウサギの穴に導かれる可能性があります。ボリュームが存在する場合は検証されないので、docker rm VOLUMENAMEが存在する可能性があるすべての場所で確認してください。

3番目の問題はNFSの問題です。NFSフォルダーが存在しない場合、サーバー上で作成されないになります。これは、NFSが機能する方法です。何かを行う前に、それが存在することを確認する必要があります。

(あなたが何をしているのか確信がない限り、 'soft'と 'nolock'を削除しないでください-これにより、NFSサーバーがなくなるとdockerがフリーズしなくなります)

完全な例を次に示します。

[root@docker docker-mirror]# cat nfs-compose.yml
version: "3.2"

services:
  rsyslog:
    image: jumanjiman/rsyslog
    ports:
      - "514:514"
      - "514:514/udp"
    volumes:
      - type: volume
        source: example
        target: /nfs
        volume:
          nocopy: true
volumes:
  example:
    driver_opts:
      type: "nfs"
      o: "addr=10.40.0.199,nolock,soft,rw"
      device: ":/docker/example"



[root@docker docker-mirror]# docker stack deploy --with-registry-auth -c nfs-compose.yml rsyslog
Creating network rsyslog_default
Creating service rsyslog_rsyslog
[root@docker docker-mirror]# docker stack ps rsyslog
ID                  NAME                IMAGE                       NODE                DESIRED STATE       CURRENT STATE                     ERROR               PORTS
tb1dod43fe4c        rsyslog_rsyslog.1   jumanjiman/rsyslog:latest   swarm-4             Running             Starting less than a second ago
[root@docker docker-mirror]#

さて、swarm-4で:

root@swarm-4:~# docker ps
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS               NAMES
d883e0f14d3f        jumanjiman/rsyslog:latest   "rsyslogd -n -f /e..."   6 seconds ago       Up 5 seconds        514/tcp, 514/udp    rsyslog_rsyslog.1.tb1dod43fe4cy3j5vzsy7pgv5
root@swarm-4:~# docker exec -it d883e0f14d3f df -h /nfs
Filesystem                Size      Used Available Use% Mounted on
:/docker/example          7.2T      5.5T      1.7T  77% /nfs
root@swarm-4:~#

このボリュームは、スタックが実行されているスウォームノード上に作成されます(しかし、破壊されない)。

root@swarm-4:~# docker volume inspect rsyslog_example
[
    {
        "CreatedAt": "2017-09-29T13:53:59+10:00",
        "Driver": "local",
        "Labels": {
            "com.docker.stack.namespace": "rsyslog"
        },
        "Mountpoint": "/var/lib/docker/volumes/rsyslog_example/_data",
        "Name": "rsyslog_example",
        "Options": {
            "device": ":/docker/example",
            "o": "addr=10.40.0.199,nolock,soft,rw",
            "type": "nfs"
        },
        "Scope": "local"
    }
]
root@swarm-4:~#
34
xrobau

はい、構成ファイルからNFSを直接参照できます。

volumes:
   db-data:
      driver: local
      driver_opts:
        type: nfs
        o: addr=$SOMEIP,rw
        device: ":$PathOnServer"

同様の方法で、各ホストにnfsボリュームを作成できます。

docker volume create --driver local --opt type=nfs --opt o=addr=$SomeIP,rw --opt device=:$DevicePath --name nfs-docker
8
herm

動作するAWS EFSのソリューション:

  1. Create EFS (セキュリティグループでNFSポート2049を開くことを忘れないでください)
  2. Nfs-commonパッケージをインストールします。

    Sudo apt-get install -y nfs-common

  3. Efsが機能するかどうかを確認します。

    mkdir efs-test-point 
     sudo chmod go + rw efs-test-point
    Sudoマウント-t nfs -o nfsvers = 4.1、rsize = 1048576、wsize = 1048576、hard、timeo = 600、retrans = 2、noresvport [YOUR_EFS_DNS]:/ efs-test-point
    touch efs-test-point/1.txt 
     Sudo umount efs-test-point /
     ls -la efs-test-point /

    ディレクトリは空でなければなりません

    Sudoマウント-t nfs -o nfsvers = 4.1、rsize = 1048576、wsize = 1048576、hard、timeo = 600、retrans = 2、noresvport [YOUR_EFS_DNS]:/ efs-test-point

    ls -la efs-test-point/

    ファイル1.txtが存在する必要があります

  4. Docker-compose.ymlファイルを構成します。

    services:
     sidekiq:
     volume:
    -uploads_tmp_efs:/ home/application/public/uploads/tmp 
     ... 
     volumes:
     uploads_tmp_efs:
     driver:local 
     driver_opts:
     type:nfs 
     o:addr = [YOUR_EFS_DNS]、nfsvers = 4.1、rsize = 1048576、 wsize = 1048576、hard、timeo = 600、retrans = 2 
    デバイス:[YOUR_EFS_DNS]:/
3
super_p

ボリュームの使用方法に応じて、次の3つのオプションがあります。

まず、名前付きボリュームを直接作成して、composeの外部ボリュームとして使用するか、docker runまたはdocker service createコマンドで名前付きボリュームとして使用できます。

  # 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

次に、--mountおよびdocker runから機能するdocker service create構文があります。これはかなり長いオプションであり、別のコンマ区切りオプション内にコンマ区切りオプションを埋め込む場合、実行中のコマンドに引用符(シェルがそれらを削除しないようにエスケープする)を渡す必要があります。私は、NFSにアクセスする必要がある一時コンテナ(たとえば、NFSディレクトリをセットアップするユーティリティコンテナ)にこれを使用する傾向があります:

  # 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

最後に、作成ファイル内で名前付きボリュームを定義できます。これを行う際の重要な注意点の1つは、名前ボリュームは一度だけ作成され、変更による更新は行われないことです。したがって、名前付きボリュームを変更する必要がある場合は、新しい名前を付ける必要があります。

  # inside a docker-compose file
  ...
  services:
    example-app:
      volumes:
      - "nfs-data:/data"
  ...
  volumes:
    nfs-data:
      driver: local
      driver_opts:
        type: nfs
        o: nfsvers=4,addr=nfs.example.com,rw
        device: ":/path/to/dir"
  ...

これらの例のそれぞれで:

  • タイプは、nfs4ではなくnfsに設定されます。これは、DockerがaddrフィールドにいくつかのNice機能を提供するためですが、nfsタイプに対してのみです。
  • oは、マウントsyscallに渡されるオプションです。 Linuxでのsyscallマウントとmountコマンドの違いの1つは、:の前の部分がaddrオプションに移動したことです。
  • nfsversは、NFSバージョンの設定に使用されます。これにより、OSが最初に他のNFSバージョンを試行する際の遅延が回避されます。
  • addrは、IPアドレスのみではなく、type=nfsを使用する場合のDNS名です。同じDNS名を使用する異なるNFSサーバーで複数のVPCがある場合、またはすべてのボリュームマウントを更新せずに将来NFSサーバーを調整する場合に非常に便利です。
  • rw(読み取り/書き込み)などの他のオプションは、oオプションに渡すことができます。
  • deviceフィールドは、リモートNFSサーバー上のパスです。先頭のコロンは必須です。これは、mountコマンドがIPアドレスをsyscallのaddrフィールドに移動する方法の成果物です。このディレクトリは、ボリュームをコンテナにマウントする前にリモートホストに存在する必要があります。
  • --mount構文では、dstフィールドはコンテナ内のパスです。名前付きボリュームの場合は、docker run -vコマンドで(短い構文で)ボリュームマウントの右側にこのパスを設定します。

リモートNFSボリュームへのアクセス許可の問題が発生した場合、遭遇する一般的な原因は、NFSサーバーがルートスカッシュに設定されたルートとして実行されているコンテナーです(すべてのルートアクセスをnobodyユーザーに変更します)。 NFSサーバー上のディレクトリにアクセスできる既知の非ルートUIDとして実行するようにコンテナーを構成するか、NFSサーバーでルートスカッシュを無効にする必要があります。

0
BMitch

私の問題は、ドライバーオプションタイプをNFS4に変更することで解決しました。

volumes:
  my-nfs-share:
    driver: local
    driver_opts:
      type: "nfs4"
      o: "addr=172.24.0.107,rw"
      device: ":/mnt/sharedwordpress"
0
namaiiee