同じボリュームを共有/使用する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共有を直接使用/マウントできる標準的な方法はありますか?
これが非常に文書化されていないことを発見した後、スタックと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:~#
はい、構成ファイルから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
動作するAWS EFSのソリューション:
Nfs-commonパッケージをインストールします。
Sudo apt-get install -y nfs-common
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が存在する必要があります
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つのオプションがあります。
まず、名前付きボリュームを直接作成して、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サーバーでルートスカッシュを無効にする必要があります。
私の問題は、ドライバーオプションタイプをNFS4に変更することで解決しました。
volumes:
my-nfs-share:
driver: local
driver_opts:
type: "nfs4"
o: "addr=172.24.0.107,rw"
device: ":/mnt/sharedwordpress"