Docker Volume & NFS:マルチホスト間でのデータ共有における「救世主」的解決策

Docker tutorial - IT technology blog
Docker tutorial - IT technology blog

クイックスタート:5分で完了するNFSボリュームのマウント

サードパーティのプラグインをインストールせずに、サーバー間でデータを共有したいですか?Docker標準のlocalドライバをそのまま活用できます。すぐにデプロイできるdocker-compose.ymlのサンプルを以下に示します。なお、リバースプロキシの設定が必要な場合は、Nginx Proxy Managerなどを組み合わせると便利です。

version: "3.8"

services:
  web:
    image: nginx:alpine
    volumes:
      - nfs_data:/usr/share/nginx/html

volumes:
  nfs_data:
    driver: local
    driver_opts:
      type: nfs
      o: "addr=192.168.1.100,nolock,soft,rw,nfsvers=4"
      device: ":/mnt/shared_folder"

重要なパラメータの注意点:

  • addr=192.168.1.100: NFSサーバーの静的IPアドレス。
  • device: ":/mnt/shared_folder": 共有フォルダへの絶対パス。
  • nfsvers=4: 安定性とセキュリティ向上のため、DockerにNFSv4の使用を強制します。

なぜNFSを使うのか?50GBのデータが「消失」したトラブルからの教訓

かつてECサイトのプロジェクトでDocker Swarmを導入した際、意気揚々と3ノード構成で運用していました。物理ノードの1つが突然シャットダウンするまでは、すべてが順調でした。Dockerは自動的にコンテナを別のノードに移動させましたが、50GBもの製品画像データがすべて消えてしまいました。理由は単純で、データが古いノードのローカルディスクに保存されていたからです。

この失敗から大きな教訓を得ました:ローカルボリュームこそが、高可用性(High Availability)を実現する上での最大の障壁であるということです。

コンテナの移動に合わせてデータも「移動」させるには、中央集権的なストレージが必要です。RAMを大量に消費するGlusterFSやCephのような複雑なシステムを選ぶ代わりに、中小規模のプロジェクトではNFSが依然として最良の選択肢です。軽量で設定が簡単であり、一般的なファイルストレージのニーズの約80%を十分に満たしてくれます。

具体的な導入手順

ステップ1:NFSサーバー(ストレージサーバー)の設定

データ保存用として、ディスク容量に余裕のあるサーバーを選択してください。Ubuntuでの環境構築手順は以下の通りです。

sudo apt update && sudo apt install nfs-kernel-server -y

# ストレージ領域の作成
sudo mkdir -p /mnt/docker_share
sudo chown nobody:nogroup /mnt/docker_share
sudo chmod 777 /mnt/docker_share

/etc/exportsファイルを開き、クライクライアント(ノード)に権限を付与するために以下の設定行を追加します:

/mnt/docker_share 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)

サーバー全体を再起動することなく、新しい設定を反映させるためにsudo exportfs -aコマンドを実行します。

ステップ2:Dockerノード(NFSクライアント)の準備

これは初心者が陥りやすいミスで、丸一日悩まされることもあります。ホストマシンにNFS制御ライブラリが不足していると、Dockerは「protocol not supported」というエラーを返します。

Dockerクラスタに参加する**すべてのノード**にnfs-commonパッケージをインストールする必要があります:

sudo apt update && sudo apt install nfs-common -y

ステップ3:Docker Swarmでの実戦的なデプロイ

Swarm環境では、コンテナがどこにスケジュールされても、NFSによってデータの状態を維持できます。以下は、wp-contentフォルダを共有する必要があるWordPressクラスタでの設定例です:

volumes:
  wp_uploads:
    driver: local
    driver_opts:
      type: nfs
      o: "addr=10.0.0.50,nolock,soft,rw"
      device: ":/mnt/nfs/wp_data"

最適化の経験とトラブルシューティング

1. 権限(パーミッション)問題の解決

NFSでは、クライアントとサーバーの間でUID(ユーザーID)が一致しないというトラブルがよく発生します。コンテナがwww-dataユーザー(UID 33)でWebサーバーを実行しているのに、サーバー上のディレクトリがroot所有である場合、「Permission Denied」エラーが発生します。

ヒント: no_root_squashオプションを使用すると、コンテナ内のrootユーザーがサーバー上でも同等の権限を持つようになります。より高いセキュリティを優先する場合は、コンテナ内のユーザーのUID/GIDをNFSサーバー上のディレクトリと正確に同期させる必要があります。

2. 覚えておくべきマウントパラメータ

  • soft: NFSサーバーの接続が突然切断された場合に、コンテナがフリーズ(ハング)するのを防ぎます。
  • nolock: 古いアプリケーションを実行する場合や、ネットワーク経由のファイル書き込み速度を最適化する必要がある場合に必要です。
  • timeo=14: リクエストを再送信するまでのタイムアウト時間(10分の1秒単位)を設定します。

実践的なアドバイス:NFSを過信しないこと

NFSは非常に便利ですが、「万能薬」ではありません。多くのプロジェクトを通じて得られた、3つの重要な注意点をまとめます:

  • 重いデータベースは避ける: PostgreSQLや大規模なMySQLなど、読み書き(IOPS)頻度が高いDBでは、NFSがボトルネックとなりシステムが低速化します。ディスク共有ではなく、レプリケーションの使用を優先してください。
  • 帯域幅を優先する: ノード間が1Gbps以上のスイッチで接続されていることを確認してください。100Mbpsのインフラでは、大容量ボリュームを持つコンテナの起動は速度面で悲惨な結果を招きます。
  • 厳重な監視: NFSサーバーがダウンすると、クラスタ全体が麻痺します。手遅れになる前に、OpenTelemetryなどを活用してこのサーバーに監視とアラート(Alerting)を設定しておきましょう。

NFSを活用してDockerボリュームをマスターすることで、インフラの柔軟性は格段に向上します。安定したシステム構築を応援しています!

Share: