はじめに
評価用にNFSサーバが必要になったため、コンテナで構築できないか調べてみた。
環境
$ cat /etc/os-release | grep PRETTY_NAME PRETTY_NAME="Ubuntu 22.04 LTS" $ uname -srvm Linux 5.15.0-25-generic #25-Ubuntu SMP Wed Mar 30 15:54:22 UTC 2022 x86_64 $ docker version Client: Docker Engine - Community Version: 20.10.14 (略) Server: Docker Engine - Community Engine: Version: 20.10.14 (略)
利用したコンテナイメージ
DockerHubで公開されている以下を利用。
更新が2019年と古いが、NFSは枯れた技術なので数年前のものでも機能的には問題ないはず。
NFSサーバの構築
(1) ディレクトリの準備
まず、今回の調査の作業用として、ホスト側に以下のディレクトリを準備した。
/ `-- nfs `-- nfs-root
ホスト側の/nfs/nfs-root
を、コンテナ側の/export
にバインドマウントし、これをNFSで共有する。
ホスト側の/nfs
は、後述するdocker-compose.yml
の配置場所にしている。
ディレクトリの作成のために、以下のコマンドを実行する。
$ sudo mkdir -p /nfs/nfs-root
また、後ほどNFSマウントができたかどうかを確認するために、/nfs/nfs-root
の中にファイルを一つ作成しておく。
$ sudo echo "hello, world!" > /nfs/nfs-root/greeting.txt
(2) docker-compose.ymlの作成
以下の内容でdocker-compose.yml
を作成し、/nfs
に配置しておく。
一部ドキュメントどおりでは動かなかった部分があり手を加えているが、詳細は後述する。
version: "3.8" services: "nfs-server": image: erichough/nfs-server privileged: true # cap_add: # - SYS_ADMIN # - SYS_MODULE ports: - "2049:2049" environment: NFS_EXPORT_0: "/export *(rw,sync,all_squash,no_subtree_check,fsid=0)" volumes: - /nfs/nfs-root:/export - /lib/modules:/lib/modules:ro
(3) NFSサーバの起動
以下のコマンドを実行して、NFSサーバのコンテナを起動する。
$ cd /nfs $ docker-compose up -d
動作確認
(1) ホストからマウント
適当なディレクトリ/nfs-test
を作成して、マウントを試してみる。
$ sudo apt update $ sudo apt install nfs-common $ sudo mkdir /nfs-test $ sudo mount -v -t nfs4 [ホストマシンのIP]:/ /nfs-test
マウントに成功すると、以下のようにgreeting.txt
を読み込むことができる。
$ cat /nfs-test/greeting.txt hello, world!
(2) コンテナからマウント
まずはUbuntuのコンテナを起動する。
ネットワークはDocker Composeが作成したnfs_default
を利用する。
$ docker run -it --privileged --net nfs_default ubuntu:latest /bin/bash
コンテナ起動後、コンテナの中に先ほどと同様に適当なディレクトリ/nfs-test
を作成して、マウントを試してみる。
$ apt update $ apt install nfs-common $ mkdir /nfs-test $ mount -v -t nfs4 nfs-server:/ /nfs-test
マウントに成功すると、以下のようにgreeting.txt
を読み込むことができる。
$ cat /nfs-test/greeting.txt hello, world!
ちなみに、コンテナ起動時にオプション--privileged
を付与しておかないと、以下のようなエラーが出てマウントに失敗する。
$ mount -t nfs4 nfs-server:/ /mnt mount.nfs4: Operation not permitted
参考
ドキュメントどおりでは動かなかった部分
コンテナイメージerichough/nfs-server
のドキュメントは、ドキュメント内のリンクの都合上、DockerHubよりもGitHubの方を見たほうがよい。
主に次の2つのドキュメントを参照した。
ここで、コンテナに付与する権限について--privileged
ではなく--cap-add
を推奨しているが、ドキュメントどおりにSYS_ADMIN
とSYS_MODULE
を付与しても権限が足りずに起動に失敗する。
他に何が必要なのかを調べる時間がないので、--privileged
を利用した。
クライアント側でも--privileged
がないとマウントに失敗するので、NFSはLinuxカーネルと密結合しているように思う。
NFSのバージョンについて
NFS v3はRPCやロックなどの様々なサービス(デーモン)を動的に組み合わせて実現しているため、設定が複雑で単にコンテナのポートをホスト側で公開するだけでは動かない。 そのため、コンテナでのNFS v3サーバの構築はハードルが高い。
一方、NFS v4はその辺りが改善されていて、ポート2049にアクセスできればNFSの利用が可能であり、コンテナでのNFS v4サーバの構築は比較的ハードルが低い。
とはいえ、--privileged
等を利用した権限付与が必要であり、コンテナを運用する際のセキュリティポリシー次第では、NFS v4は利用できない可能性がある。