s3fs を使って EC2 に S3 の Bucket をマウントする


お仕事の絡みで、タイトルの要件が必要になりそうだったので備忘録も兼ねて。

前提

  • EC2 の Distribution は Amazon Linux
  • インスタンスは AutoScale によって増えたり減ったりする

やること

  1. S3 Bucket の準備
  2. IAM の準備
    • IAM User で対応する場合
    • IAM Role で対応する場合
  3. s3fs のインストール
  4. s3fs の設定・起動

やりかた

S3 Bucket の準備

まぁ、普通に Management Console から追加するだけ。

ログとかはご随意に。

IAM の準備

二通りのやり方があるので、お好みで。

IAM User で対応する場合

このケースは、EC2 起動時のオプションとして IAM Role を 割り当てたくない(られない) 場合に使うと良いか?

  1. IAM Management Console で Create a New Group of Users をクリック ScreenShot 01
  2. グループ名を設定して Continue ScreenShot 02
  3. Select Policy Template の中にある Amazon S3 Full AccessSelect
    ※割と下の方にあるので、スクロールしないと出てこない。 ScreenShot 03
  4. テンプレートから生成された Policy 構文が表示されるので、そのまま Continue ScreenShot 04
  5. ユーザ名決めて Continue ScreenShot 05
  6. 内容に問題が無ければ Continue ScreenShot 06
  7. 作成に成功し、一番重要な Access Key IDSecret Access Key が表示されるので、控える。
    Download Credencials しとくと良い。 ScreenShot 07

IAM Role で対応する場合

鍵情報などを EC2 のインスタンス内に残したくない場合はコッチかな?

EC2 インスタンスの起動時に下記で作成した IAM Role を設定する必要がある。

  1. IAM Management Console の左ペインにある Roles から Create New Role をクリック ScreenShot 01
  2. ロール名を決めて Continue ScreenShot 02
  3. AWS Service Roles の Amazon EC2 を Select ScreenShot 03
  4. Select Policy Template の中にある Amazon S3 Full AccessSelect
    ※割と下の方にあるので、スクロールしないと出てこない。 ScreenShot 04
  5. テンプレートから生成された Policy 構文が表示されるので、そのまま Continue ScreenShot 05
  6. 内容に問題が無ければ Create Role ScreenShot 06

s3fs のインストール

2014年01月24日現在、最新版は 1.76 の様子。
Google Code にあるのが最新かと思いきや、 GitHub に移動しているようなので注意w

なお、RPM などは用意されていないので、自分で make する必要がある。
rpmbuild でもしとくと幸せになれるかも?w

先ずは、必要となるパッケージのインストール

Amazon のリポジトリにあるパッケージで賄える。

yum
sudo yum -y install gcc-c++ fuse fuse-devel libcurl-devel libxml2-devel openssl-devel

続いて、s3fs のソース取得

git
git clone https://github.com/s3fs-fuse/s3fs-fuse.git

configure, make, make install

/usr/bin/s3fs に置きたかったので --prefix=/usr./configure のオプションに食わせてます。

make
cd s3fs-fuse/
./autogen.sh
./configure --prefix=/usr
make
sudo make install

s3fs の設定・起動

作成した IAM の種類に応じて、若干設定内容が変わる。

マウント前の設定

マウントポイントとなるディレクトリを作る。
私は /mnt/s3fs にしてる。

mkdir
sudo mkdir <Mount Point>

IAM を User で作成した場合

s3fs を用いてマウントする際の認証用に、作成時に控えた Access Key IDSecret Access Key を設定する。

色々置き場があるっぽいが、ココでは /etc/passwd-s3fs に配置する。
※置き場については、マニュアル参照のこと。

passwd-s3fs設定
echo "<Access Key ID>:<Secret Access Key>" | sudo tee -a /etc/passwd-s3fs
sudo chmod 640 /etc/passwd-s3fs

IAM を Role で作成した場合

EC2 インスタンス起動時に IAM Role を正しく選択していれば、特に設定するコトはない。はず。

マウント

お待ちかねのマウント。

なお、デフォルトだと root:root でマウントされてしまって、読み書きが出来ない状態になってしまうので、
オプションに uid, gid を渡して、マウント時の Owner を変更する必要がある。
※uid, gid は id <User Name> コマンドで確認出来る。

下記の例では、default_acl=public-read としているが、これは外部に直接公開するケースが有り得たので、こうしている。
外部公開する必要が無いなら private にしておくのがオヌヌメ。
CloudFront 経由で配信したい場合でも Distribution を正しく設定すれば private で問題無かったはず。

IAM を User で作成した場合

s3fs
sudo /usr/bin/s3fs <Bucket Name> <Mount Point> -o rw,allow_other,uid=<UID>,gid=<GID>,default_acl=public-read

IAM を Role で作成した場合

s3fs
sudo /usr/bin/s3fs <Bucket Name> <Mount Point> -o rw,allow_other,uid=<UID>,gid=<GID>,default_acl=public-read,iam_role=<IAM Role Name>

確認

マウントポイントを ls するなり df するなりすれば良いんじゃないかな?

ちなみに、df した結果は以下。


$ df -kh
Filesystem            Size  Used Avail Use% マウント位置
/dev/xvda1             30G   16G   13G  55% /
tmpfs                 298M     0  298M   0% /dev/shm
s3fs                  256T     0  256T   0% /mnt/s3fs

256TB のファイルシステムがマウントされてますね!

起動時設定

このままだと、起動時に自動的にはマウントしてくれない。
ので、今回作ったインスタンスをベースにした AMI からの AutoScaling とか、普通にインスタンス再起動した時とかに、「あれ?S3 マウントしたディレクトリが見られない…!?」みたいなコトになる。
ので、起動時に自動的にマウントしてくれるように設定してしまう。

んで、このとき、一般的には /etc/fstab に記載して終わりにするんだろうけど、IAM を Role にした場合、fstab の設定が読まれる時点ではまだ Amazon の API を叩けないっぽいので、マウントに失敗する。
ので、以下のように IAM の種類によってやり方を変える

IAM を User で作成した場合

User の場合は API 叩く必要が無いので、素直に fstab に書く。

/etc/fstab
echo "/usr/bin/s3fs#<Bucket Name> <Mount Point> fuse rw,allow_other,uid=<UID>,gid=<GID>,default_acl=public-read 0 0" | sudo tee -a /etc/fstab

IAM を Role で作成した場合

Role の場合は、API が叩けるようになる 起動時スクリプトが走るタイミング でマウントする。

/etc/rc.d/rc.local とかでやると良いんじゃないかな?

/etc/rc.d/rc.local
echo "/usr/bin/s3fs <Bucket Name> <Mount Point> -o rw,allow_other,uid=<UID>,gid=<GID>,default_acl=public-read,iam_role=<IAM Role>" | sudo tee -a /etc/rc.d/rc.local

上記の例では、 /etc/rc.d/rc.local の最下部に追記してるけど、他にも何か処理してるなら、順番は気を付けた方が良いかも。

おわりに

と、偉そうなことを散々書いておきながら、まだ商用環境での稼働はしておりませんっ!w
※遠からず対応するとは思うが、まだ実験中だったりする :-P

導入して、運用安定したらレポしようかしら…。