先に結論
めんどい!EFSを使おう!!
なぜEFSでなく、NFS?
NFSなんぞ使わず、EFSやら何かしらのマネージド使えばええやん…となるが、実現するとなると下記問題が生じた。
- EFS
- そもそもEFSはNFSを包括したサービスらしい
- WindowsServer2012に標準搭載されているNFSクライアントはv3だが、EFSはNFSv4でないと使用できない
- それでも非公式のNFSクライアント導入することで使えるっぽい
- この方法だと、Windows側からLinux側へファイルを書き込めないらしい
- 自環境で動作しなかった → 今思い返すと、色々設定忘れがあった気がするし、ここをきちんと動作確認すべきだった…
- FSx
- NFSクライアントのバージョンに関係なく使用できるとのことだが、コスト高になりそう
- StorageGateway
- 推奨インスタンスタイプが
m4.xlarge
や推奨EBSサイズが150GB
と貴族でないとやっていられなそう
- 推奨インスタンスタイプが
これらの問題からNFSを使用することに。。。
環境構成
実現するにあたって、構成は下図のイメージ。
Linux側では、 /linux-dir
を操作ディレクトリとし、Windows側では、 Z:\\windows-dir
が操作ディレクトリとなる。
/windows-dir
やら fuse-convmvfs
については後述。
検証環境
Linux(NFS-Server) Amazon Linux AMI release 2018.03
Windows(NFS-Client) WindowsServer 2012 R2
NFSサーバ(AmazonLinux)側の設定
nfs-utilsのチェック
AmazonLinuxであれば標準でnfs-utilsがインストールされているはず。
されていない場合は、 yum install nfs-utils
でインストールする。
NFSで使用されるポート番号の固定
- ここを参考に
-
/etc/sysconfig/nfs
の以下コメントアウトを外す
# Port rquotad should listen on.
RQUOTAD_PORT=875
...
# TCP port rpc.lockd should listen on.
LOCKD_TCPPORT=32803
# UDP port rpc.lockd should listen on.
LOCKD_UDPPORT=32769
...
# Port rpc.mountd should listen on.
MOUNTD_PORT=892
...
# Port rpc.statd should listen on.
STATD_PORT=662
-
/etc/nfsmount.conf
の以下コメントアウトを外す
# Server Port
Port=2049
- AWS上のSecurityGroupで以下ポートのinboundを開放する
-
TCP:
111, 892, 2049, 32803
-
UDP:
111, 892, 2049, 32769
-
TCP:
NFSをサービスとして登録する
$ chkconfig rpcbind on
$ chkconfig nfs on
$ chkconfig nfslock on
$ service rpcbind start
$ service nfs start
$ service nfslock start
/etc/exportsに共有情報を記述
WindowsServer側のIPアドレスがa.b.c.d/32とした場合、
/windows-dir a.b.c.d/32(rw,fsid=1,sync,no_root_squash,no_all_squash)
なお、ここで fsid=1
の記述が無いと以下エラーが出る場合がある
exportfs requires fsid= for nfs export
追記したら、以下を実行
$ exportfs -ar
↓で反映状態を確認し、 /etc/exports
に記述した内容が表示されればOK
$ exportfs -v
/etc/hosts.allow にNFSクライアントからのアクセスを許可する
portmap: a.b.c.d/32
lockd: a.b.c.d/32
rquotad: a.b.c.d/32
mountd: a.b.c.d/32
statd: a.b.c.d/32
fuse-convmvfsをビルド/インストールする
- ここを参考に
- Linux⇔Windows間だと、文字エンコーディングの問題でファイル名が化けてしまう
- この問題をfuse-convmvfs(以下convmvfs)で解決する
- convmvfsとは、こちらの記事によると以下の機能を持ったツールとなる。細かな導入作業については、この記事を参考にしてもらいたい
◆fuse-convmvfsってなんぞ?
fuseという、ファイルシステム単位でシンボリックリンクっぽいものを張る(暴論)機能をラッピングして、このエイリアスパスを通したときだけファイル名の変換を行うためのユーティリティ。
- つまるところ、
/windows-dir
は特段触れないディレクトリとなる - fuseはここ、fuse-convmvfsはここからダウンロードする
- 当環境では、
fuse-2.9.9
およびfuse-convmvfs-0.2.5
で動作を確認した
1: fuseの導入
$ tar -zxvf fuse-2.9.9.tar.gz fuse-2.9.9
$ cd fuse-2.9.9 && make
$ make install
2: fuse.pcをpkg-configで読めるようにする
# fuse.pcファイルを探す
$ find / -name fuse.pc
# 見つけたファイルが /usr/lib64/pkgconfig/ に存在しなければコピーする
$ cp /path/to/fuse.pc /usr/lib64/pkgconfig/
# 下記コマンドを実行し、同じ出力がでればOK
$ pkg-config --libs fuse
-pthread -L/usr/local/lib -lfuse
3: fuse-convmvfsの導入
$ tar -zxvf fuse-convmvfs-0.2.5.tar.gz fuse-convmvfs-0.2.5
$ cd fuse-convmvfs-0.2.5 && make
$ make install
4: convmvfsの動作確認
$ convmvfs --help
usage: convmvfs mountpoint [options]
...
convmvfs用のマウントポイントを作成
構成図にも書いたが、Linux側で操作するディレクトリを linux-dir
、WindowsServer側でマウントするディレクトリを windows-dir
とする。
なお、今回は /
直下に両ディレクトリがあることを想定する。
Linuxサーバ側では、
$ convmvfs /windows-dir -o ocharset=CP932,srcdir=/linux-dir,allow_other
でマウントする。
これで、 /linux-dir
に作成されたファイルは、 /windows-dir
に自動リンクされ、Windosサーバ上では、文字化けしていないファイル名のファイルが共有される。
# 後述するが、文字化けしないのはファイル名のみで、例えばテキストファイルであると、中身についてはがっつり文字化けしたままとなる。
インスタンス再起動時に自動マウントするようにする
crontabに @reboot
をつけることでインスタンス再起動のたびに自動マウントできる。
$ crontab -e
@reboot convmvfs /windows-dir -o ocharset=CP932,srcdir=/linux-dir,allow_other
なお、アンマウントについては以下コマンドで可能。
$ fusermount -u /windows-dir
# buzyでアンマウントできない場合は `-z` オプション付与で強制断できる
NFSクライアント(WindowsServer)側の設定
WindowsServerのmountコマンド有効化
WindowsServerはデフォルトでNFSクライアントが有効でない(= mount
コマンドが有効でない)ので、有効化する。
- サーバーマネージャーを起動し、「役割と機能の追加」を選択する
- 「機能の選択」で「Client for NFS」にチェック。「次へ」を選択
- 次へを押し、インストール(再起動については必要に応じて)
- コマンドプロンプトで
mount
と打ち、実行できることを確認
WindowsServer側からNFSマウント
LinuxServerのIPがd.e.f.g、WindowsServerログオン時ユーザがAdministratorだった場合
C:\> mount -o mtype=soft -o lang=shift-jis -u:Administrator \\d.e.f.g\windows-dir Z:
# このコマンドをbatファイルに記述し、スタートアップディレクトリに放り込めば
# 起動時に自動的にマウントさせることが可能
でマウントする。
成功すると、エクスプローラー上にZドライブが出現する。
LinuxとWindows間のユーザーマッピングを行う
Windows側から共有ドライブ(今回のケースだとZドライブ)上に作成したファイルは、所有者、グループのuidとgidがLinux側に存在しないことになる。
そのため、Windows側から書き込んだ場合にLinuxのec2-userが所有者、グループになるようにユーザマッピングを行う。
Linux側で以下コマンドを実行
$ cat /etc/passwd | grep ec2-user
ec2-user:x:500:500:EC2 Default User:/home/ec2-user:/bin/bash
上記実行内容をもとに
C:\Windows\System32\drivers\etc
内で 新規ファイル passwd
と group
を作成する。
passwd
Administrator:x:500:500:EC2 Default User:/home/ec2-user:/bin/bash
group
Administratorsグループに所属するユーザの場合はユーザ名の前に BUILTIN\
をつける。
BUILTIN\Administrators:x:500:
これで、Windows側から作成したファイルの所有者およびグループはec2-userになる。
問題点
- 構築がめんどい
- ディスク容量がEBSマターになる。S3をローカルに仮想マウントさせて、それをNFSのマウントポイントにすることってできるのかね
- 途中記述したが、convmvfsによって、Linux側で作成した ファイル名 はWindows上でも文字化けせずに見ることが可能だが、中身については、化け化けな点。もちろん逆の場合も同様となる。これについては、nkfとかで頑張るしかない?
- データ転送速度は、自検証環境ではプライベートサブネットでのNFSだったこともあり、レイテンシの問題があるように感じなかった。インターネット経由するとなったらどうなるかは知らん
- 保守性とか可用性を考えると憂鬱になるね。やはりマネージドはすごい
結論
めんどい!
おそらくみなさんは選ばれし人なので、非公式NFSクライアントを経由してEFSを使おう!
貴族はFSxやらStorageGatewayを使おう!