プログラマーのメモ書き

伊勢在住のプログラマーが気になることを気ままにメモったブログです

s3 をファイルシステムとしてマウントする

EC2を使っていると、EC2のインスタンスのディスク容量はインスタンス作成時に決めていることもあり、s3 をストレージとして利用したくなります。S3上のファイルやフォルダがEC2インスタンス側からファイルシステムとして扱えれば、こんなに嬉しいことはありません。今回、これを実現するために、 s3fs-fuse を導入し、その設定を行ったので、メモ書きとして残しておきます。この記事では、ローカルPC(VM)上に導入したときの手順を元に書いてますが、EC2上でも変わりありません。

 

OS:Ubuntu 14.04.1 LTS, 64bit

s3fs-fuse:v1.78

 

まあ、将来的には、EFSが導入されれば、こんなことしなくても良いのかもしれませんが。

【AWS発表】Amazon Elastic File System (EFS) - Amazon EC2 のための共有ファイルストレージ

 

s3fs-fuseのインストール

s3fs-fuse はFUSE (Filesystem in Userspace) の機能を利用して、s3をファイルシステムのように扱うためのものです。FUSEそのものについては参考記事などを参照してください。

s3をファイルシステムとして使うにはこれをインストールします。

インストール方法は、特に難しいわけでもなく、 Tested on Ubuntu 14.04 LTS に記載されているとおりに実行すればOKです。ただし、今回は、最後の

sudo make install

 の代わりに

sudo checkinstall

 として、パッケージ化してインストールを行いました。

checkinstall はソースコードからmake, make install などとしてインストールする場合に、一旦パッケージを作成して、それをインストールするというものです。これ便利ですよね。詳しくは、 Wikipediaの記事などを参考にしてください。

 

s3fsの設定

では早速設定してみましょう。設定もそんなに難しい話ではありません。最初は、AWS側での作業です。

 

AWSでの作業

S3へのアクセスのみを許可したIAM ユーザーを作成します。

IAM の理解としては、個別に操作権限を割り当てたユーザーを作成し、それを使ってアクセスすることで、仮に不正アクセスが発生しても、権限を与えられた範囲外へ被害が及ぶのを防ぐという仕組みだと思っています(違っていたらごめんなさい)。余計な料金もかからないし、積極的に利用したいところです。まあ、そんな大仰なこと言い出さなくても、必要最小限の権限で処理を行うというのはなんにでも通用する考えですしね。

IAMユーザーを作成したら、アクセスキーIDとシークレットアクセスキーを控えておきます。

あと、S3上にバケットを作成しておきます。必要があればフォルダも作っておきます。

 

PC側での作業

次は、S3をマウントするPC側での作業になります。

 

まず、S3にアクセスする際の認証情報を、/etc/passwd-s3fs に記述しておきます。ここなどを参考にしてください。

https://github.com/s3fs-fuse/s3fs-fuse/wiki/Fuse-Over-Amazon

書式は、バケット名:アクセスキー:シークレットキー となります(バケット名はなくてもかまいません)。

mor@ubuntu:~$ sudo cat /etc/passwd-s3fs 
バケット名:アクセスキーID:シークレットアクセスキー
mor@ubuntu:~$ 

このファイルのパーミッションを変更しておきます。

sudo chmod 640 /etc/passwd-s3fs

マウントポイントを作成します。

sudo mkdir /mnt/s3fs

 コマンドラインからマウントしてみます。

sudo s3fs バケット名:/フォルダ名 /mnt/s3fs -o allow_other -o use_cache=/tmp

 ここで、オプションは、

  • allow_other: root 以外(マウントしたユーザー以外)も利用可能とする
  • use_cache: 指定したフォルダを読み出し用のキャッシュフォルダとして使用

のような意味です。

マウントできたことを確認します。

mor@ubuntu:~$ mount
/dev/sda1 on / type ext4 (rw,errors=remount-ro)

s3fs on /mnt/s3fs type fuse.s3fs (rw,nosuid,nodev,allow_other)

mor@ubuntu:~$ 

のようにマウントできていることが分かります(df -hでも確認できると思います)。

 

実際にマウントポイントを見てみると、

mor@ubuntu:~$ ls -l /mnt/
合計 8
drwxr-xr-x 2 root root 4096  94  2014 hgfs
drwxr-xr-x 2 root root 4096  69 00:29 s3fs
mor@ubuntu:~$ 

 だったのが、

mor@ubuntu:~$ ls -l /mnt
合計 5
drwxr-xr-x 2 root root 4096  94  2014 hgfs
drwxrwxrwx 1 root root    0  11  1970 s3fs
mor@ubuntu:~$ ls -l /mnt/s3fs/
合計 1
drwxrwxr-x 1 mor mor 0  428 22:40 store
mor@ubuntu:~$ 

 のように見えてます(storeというフォルダはs3上に作ってあるフォルダです)。

 

起動時にマウントするための設定

これで問題なくマウントできるようになったので、起動時に自動的にマウントする設定にしてみます。ググると、/etc/fstab に記述すればよいというのが多かったのですが、なぜか手元の環境ではうまくマウントできませんでした。

そこで、今回は、/etc/rc.localにマウントするためのコマンドを記入することで対応しました。

mor@ubuntu:~$ cat /etc/rc.local
#!/bin/sh -e
#
# rc.local

# s3fs mount
#umount /mnt/s3fs
s3fs omikujips:/test /mnt/s3fs -o allow_other -o use_cache=/tmp

exit 0
mor@ubuntu:~$ 

これで、再起動しても、s3がマウントされるようになりました。便利ですねー。

 

参考

FUSEについて

FUSE Wikipedia

FUSEとはIT Pro

 

S3FSよりAPIのほうがよい?

S3FSよりもAPIでアクセスするほうがよいとの指摘もあります。

http://blog.genies.jp/2011/08/amazon-ec2-amazon-linux-s3.html

 

今回はS3から読み出したファイルをPC上でローカルファイルとして扱いたかったので、s3fsを使ってみました。

これをAPIでやろうとすると、s3から読み出したファイルを一旦ローカルに作成しないといけないかと思います。で、今回の目的のものでは、s3上のファイルサイズが大きく、またアクセスする必要があるファイル数も多いので、これを自前でやろうとするとファイルキャッシュを自分で用意する必要が出てきそうで、今回はやめました。

一方、s3fsの場合だと、use_cacheオプションを有効にしておいて、あとは適当なタイミングでキャッシュをクリアするようにすれば済みそうです。

(もろもろ理解が違ってたら、すいません)

実際のところはどうなんでしょうか?

 

s3fsの速度について

ローカルのPC上にs3fsを設定して、読み書きしてみると、まあ遅いこと遅いこと。ネットワーク経由なので、仕方ないですね。

同じリージョン内で、EC2のインスタンスからs3fs経由でs3にアクセスするとこちらは、まあ、耐えられなくはない速度でした。とはいうものの、目的次第ではやはり遅いかと思いますので、一度自分で試してみることが大事そうだなと感じてます。

 

fstabへの記述でうまく起動時にマウントできない現象について

リブート前にアンマウントしていない場合、マウントできないことがあるという記事がありました。
http://kumachan.biz/2014/11/10_2258/4228/
https://angelndxp.wordpress.com/2014/03/06/%E3%80%90aws%E3%80%91-s3fs%E3%83%9E%E3%82%A6%E3%83%B3%E3%83%88%E6%99%82%E3%81%AB%E8%B5%B7%E3%81%93%E3%82%8B%E5%95%8F%E9%A1%8C%E3%81%A8%E3%80%81%E3%81%9D%E3%81%AE%E5%9B%9E%E9%81%BF%E6%96%B9%E6%B3%95/

でも、残念ながら、事前にアンマウントしていても同じことが発生していたので、ちょっと真の原因はアンマウントではないかも。

ちなみに、これらの記事の方法を試そうとしたら、この場合、fstabとrc.localの両方に記述する必要がありました。
(rc.local への記述だけだとマウントがなくて、umountコマンドを呼び出すと、失敗になるため正しくマウントされませんでした)


似たようなissueもあるそうだ。
https://code.google.com/p/s3fs/issues/detail?id=300
https://code.google.com/p/s3fs/issues/detail?id=317

これらに記載の対応方法を取れば良さそうですが、今回は見送りました。