web-dev-qa-db-ja.com

Docker Swarmはどこのようにボリューム共有を実装しますか?

Docker Swarmは、ボリュームとバインドの2種類のストレージを管理できます。 bindは、(それぞれのSwarmノード上の)ローカルディレクトリとタスクとの間のバインディングを作成するのでDockerドキュメンテーションでは推奨されていませんが、ボリュームメソッドの実装は言及されていません。

Docker Swarmはどのようにノード間でボリュームを共有するのですか?ボリュームはどこに保存されていますか(マネージャ上、および複数のマネージャが存在する場合)。

異なるネット上の異なるマシンで実行されている場合、ノード間で問題はありませんか?それはVPNを作成しますか?

55
alessandro308

あなたが求めているのは、よくある質問です。ボリュームデータとそのボリュームでできることの機能は、ボリュームドライバによって管理されます。 overlaybridgeHostなどの異なるネットワークドライバを使用できるのと同じように、異なるボリュームドライバを使用することもできます。

DockerとSwarmには標準のlocalドライバが付属しています。 Swarmを意識することはなく、サービスタスクがスケジュールされているどのノードでも、データ用の新しいボリュームを作成するだけです。これは通常あなたが望むものではありません。

Swarmに対応したサードパーティ製ドライバプラグインが必要で、サービスタスク用に作成したボリュームが適切なタイミングで適切なノードで利用できるようになります。オプションには「Docker for AWS/Azure」とそれに含まれる CloudStor ドライバ、または一般的なオープンソース REX-Ray ソリューションの使用が含まれます。

Docker Store で見つけることができるたくさんのサードパーティ製のボリュームドライバがあります。

40
Bret Fisher

Swarm Mode自体はボリュームに対して何も変わりません。コンテナが実行されているノード上でユーザーが指定したボリュームマウントコマンドを実行します。ボリュームマウントがそのノードに対してローカルである場合、データはそのノードにローカルに保存されます。ノード間でデータを自動的に移動するための組み込み機能はありません。

GlusterFSのようなソフトウェアベースの分散ストレージソリューションがいくつかあり、DockerにはInfinitと呼ばれるものがまだGAないので、その開発はEEのKubernetes統合の後押しをしています。

典型的な結果は、あなたがあなたのアプリケーション内のストレージの複製を管理する必要がある(例えば、etcdや他のラフトベースのアルゴリズム)か、外部ストレージシステムでマウントを実行することです(うまくいけばそれ自身のHAで)。外部ストレージシステムのマウントには、ブロックベースとファイルベースの2つのオプションがあります。ブロックベースの記憶装置(例えば、EBS)は通常、より高い性能を伴うが、単一のノードにマウントされることに限定される。そのためには、通常、dockerノードにそのブロックストレージへのアクセスを許可するためのサードパーティ製のボリュームプラグインドライバが必要になります。ファイルベースの記憶装置(例えば、EFS)は、性能は低いが、よりポータブルであり、複数のノードに同時にマウントすることができ、これは複製サービスに有用である。

最も一般的なファイルベースのネットワークストレージはNFSです(これはEFSで使用されているものと同じプロトコルです)。そして、サードパーティのプラグインドライバがなくてもマウントできます。 dockerに同梱されている残念なことに「local」ボリュームプラグインドライバには、ドライバオプションを指定してmountコマンドに任意の値を渡すオプションがあります。港湾労働者/ボリューム。オプションを使用すると、NFSパラメータを渡すことができ、NFSホスト名に対してDNSルックアップを実行することさえできます(通常NFSにはないものです)。ローカルボリュームドライバを使ってNFSファイルシステムをマウントするさまざまな方法の例を示します。

  # create a reusable volume
  $ docker volume create --driver local \
      --opt type=nfs \
      --opt o=nfsvers=4,addr=192.168.1.1,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=192.168.1.1\",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=192.168.1.1\",volume-opt=device=:/Host/path \
    foo

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

AWS EFSのための私の解決策、それはうまくいきます:

  1. 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 
     ...:
     [アップロード] _tmp_efs:
    ドライバ:ローカル
     driver_opts:
    タイプ:nfs 
     o:addr = [YOUR_EFS_DNS]、nfsvers = 4.1、rsize = 1048576 wsize = 1048576、hard、timeo = 600、retrans = 2 
    デバイス:[YOUR_EFS_DNS]:/
2
super_p