【30分でできる】AWSのEC2にgoofysを入れてS3をマウント

【30分でできる】AWSのEC2にgoofysを入れてS3をマウント

記事一覧【30分でできる】AWSのEC2にgoofysを入れてS3をマウント

過去に携わったプロジェクトで、S3FS の通信状態が悪い時があるので、アプリ側のプログラムを AWS SDK を使ったものに置き換えていこうという施策がありました。

S3FS の導入には関わっていなかったので、導入の経緯や不安定さは知らなかったのですが、確かにファイルのアップロード(特にこっちの書き込み系)やダウンロードで時々 20 秒くらい待たされる時がありました。

また、ターミナルでマウントしているディレクトリ上で ls コマンドを叩いてもレスポンスが遅い時が何度も見受けられました。

AWS のコマンドラインツール(awscli)で S3 に繋いだ方が確実で速いという、何ともマウントの意味のない状態だったことは確かです。CLI の使い方は過去に書いているので、興味のある方はどうぞ。

CentOS7でawscliをセットアップしてS3に接続する


目次

goofysを使うかLaravelのライブラリで対応するか

そんな中、S3FS と同じように、S3 をマウントできる goofys というものがあることを知りました。

実際に導入実績もあるということで、今回はそれを採用しようということで半ば決定となりました。

アプリ側は Laravel のフレームワークを使うので、今回は filesystem パッケージを利用したファイルストレージライブラリを採用して、ローカルと S3 を切り替えようと思っていましたが、マウントできるのであれば、その辺も意識はしなくてもよくなります。

Laravel 5.4 ファイルストレージ

goofysのインストール手順

goofys は初めて聞く名前でしたが、1 年以上前に既に流行がきていたようで、手順書的なものはいくつかのサイトで紹介されていました。

現在の AmazonLinux でも大きく変わらないと思いますが、最新バージョンを使ってインストールとマウントを試してみたいと思います。

当然、goofys の GitHub 上の README.md を見るのが確実です。

kahing/goofys

そう言えば、go で動くアプリを実際にインストールするのは初めての経験かもしれません。周りでは使っている人も何人かいて、オススメはよくされるのですけどね。

$ yum install golang fuse

fuse  : 2.9.4-1.17
golang: 1.7.5-2.39

冒頭でも話題に出した AWS CLI の設定がここで必要となるのですが、AWS の IAM Role を使って接続の設定も可能です。こちらは、お好きな方を採用してください。

IAM Role で参考になるのは下記のサイトです。

s3fsよりも高速に使えるgoofysを試してみた

では、AWS CLI の設定をします。もちろん、ここまでに S3 に接続するための IMA ユーザーの作成をして、「Access key ID」と「Secret access key」は取得しておいてください。

バケットも先に作っておいて問題ありません。

では、AWS CLI の設定をします。IAM Role は今回は使いません。

$ aws configure

AWS Access Key ID [None]: [アクセスキー]
AWS Secret Access Key [None]: [シークレットキー]
Default region name [None]: ap-northeast-1 ※東京リージョン
Default output format [None]: 

バケットへの接続確認をします。何も置いていなければ結果はないですし、何かファイルを置いていたら直下のファイルの一覧が表示されます。

$ aws s3 ls s3://[バケット名]

ようやく、goofys のインストールに入ります。パッケージをダウンロードしようとしたら、GOPATH の環境変数を設定しろとのことだったので設定します。

$ go get github.com/kahing/goofys

package github.com/kahing/goofys: cannot download, $GOPATH not set. For more details see: go help gopath

which go をコマンド実行すると go コマンドのパスが返ってくるのになっと思っていたら、goofys のインストール先のことだったのですね・・・。

$ export GOPATH=/root/tmp/go

$ echo $GOPATH

/root/tmp/go

再度チャレンジです。

$ go get github.com/kahing/goofys

# github.com/kahing/goofys/internal
tmp/go/src/github.com/kahing/goofys/internal/handles.go:450: undefined: url.PathUnescape

あれっ、エラーが出た。go のバージョンは 1.7.5 です。

$ go version

go version go1.7.5 linux/amd64

go をソースから入れた方が良かったのかな。ってことで、CentOS や RHEL 向けの手順で golang を入れ直します。

How to Install Go 1.8 on Fedora 26/25/24 & CentOS/RHEL 7/6

$ yum remove golang

$ wget https://storage.googleapis.com/golang/go1.8.3.linux-amd64.tar.gz

$ tar -xzf go1.8.3.linux-amd64.tar.gz

$ mv go /usr/local

$ vi .bash_profile

export GOROOT=/usr/local/go
export GOPATH=/root/tmp/go
PATH=$PATH:$HOME/bin:$GOPATH/bin:$GOROOT/bin

$ source .bash_profile 

$ go version

go version go1.8.3 linux/amd64

では、気を取り直して goofys のインストールです。何も標準出力されないので、インストールできたのか不安ですが・・・。

$ go get github.com/kahing/goofys

$ go install github.com/kahing/goofys

早速、マウントしてみます。成功しても何も標準出力されないので、df コマンドで確認します。

# マウントポイントの作成
$ mkdir -p /tmp/cdn                                                                              

# goofysインストール時に設定したパスでマウント実行
$ /root/tmp/go/bin/goofys --region ap-northeast-1 [バケット名] /tmp/cdn

$ df

Filesystem 1K-blocks Used Available Use% Mounted on

(途中省略)

[バケット名] 1099511627776 0 1099511627776 0% /tmp/cdn

試しに、images というディレクトリを作成し、aws s3 コマンドから確認してみます。

$ mkdir /tmp/cdn/images

$ aws s3 ls s3://[バケット名]

PRE images/

あとは、EC2 のインスタンスや OS 再起動時にも自動的にマウントされることを確認できたら OK ですね。

goofysでマウントした設定を自動マウントする

この時点では、/etc/fstab に何も設定していないので、OS 再起動のタイミングでマウントされていない状態になります。

よって、/etc/fstab に goofys のマウント設定をします。

また、Web アプリからファイルアップロードをさせたい場合もあると思いますので、apache や nginx の実行ユーザを主体にパーミッション設定してもいいと思います。

下記の例では、ec2-user とは別に作成したユーザ(uid=501, gid=501)で、作成されるディレクトリが 777、ファイルが 666、また、その他ユーザにもファイルの参照や書き込みを許可しています。

$ vi /etc/fstab

/root/tmp/go/bin/goofys#[バケット名] /tmp/cdn fuse _netdev,allow_other,--dir-mode=0777,--file-mode=0666,--uid=501,--gid=501 0 0

手動でアンマウントとマウントを実際にやっておけば、EC2 のインスタンス再起動時もほぼほぼ大丈夫だと思います。

$ unmount /tmp/cdn

$ mount -a

参考カテゴリ

オススメ記事

最新の投稿やよく見られているのオススメ記事一覧です。

AmazonLinuxでEC2起動時にスワップ領域の割り当てに失敗

EC2 起動時のスワップ領域割り当てですが、これまでは以下の記事を参考に、/etc/rc.local を使って行っていました。 ・ Amazon EC2(Linux)のswap領域ベストプラクティス しかし、最近になって、EC2 イン...

>>記事を確認する

【5分でできる】Laravel5.4から5.5へバージョンアップ

Laravel5.5 がついにリリースされたので、5.4 ベースで作っていたものをバージョンアップしてみました。 composer.json の以下の部分を 5.5.* に変更するだけですが、依存関係のパッケージも問題なくアップデ...

>>記事を確認する

【30分でできる】AWSのEC2にgoofysを入れてS3をマウント

過去に携わったプロジェクトで、S3FS の通信状態が悪い時があるので、アプリ側のプログラムを AWS SDK を使ったものに置き換えていこうという施策がありました。 S3FS の導入には関わっていなかったので、導...

>>記事を確認する

【30分でできる】ぐるなびAPIで飲食店の店舗情報取得

過去に作成した「ぐるなびAPI」のプログラムや、ぐるなびの Web Service が新しくなったこともあり、API からの情報取得プログラムを書き換えてみました。 以前の記事は下記になります。 ・ ぐるなびAPIで...

>>記事を確認する

NginxのFastCGIキャッシュで白い画面がキャッシュされる

以前から、トップページにアクセスすると、レスポンスステータスは 200 で返ってくるのに、画面に何も表示されない現象が稀に見受けられたので調査してみました。 さすがに機会損失にも繋がるということで、...

>>記事を確認する

Laravel5.4の認証ユーザーのパスワードハッシュについて

Laravel で用意されている認証モジュールを利用する際、ユーザーモデル(User.php)経由で登録されるパスワードのハッシュ方法について調べてみました。 Laravel 上ではパスワード文字列を bcrypt() のヘルパー...

>>記事を確認する

Laravel5.4のコントローラコンストラクタでAuth::user()が取得できない

Laravel5.4 で認証を通したアクセスに対して、コントローラのコンストラクタでユーザモデルの値を取得しようと思ったら、なぜか Auth::user() の値が取得できなくて悩みました。 public function __construc...

>>記事を確認する

NginxのHSTS(HTTP Strict-Transport-Security)の設定

「Let's Encrypt」のおかげで、全サイト SSL 化していますが、これまで nginx の設定では、http のアクセスがあった場合に https に 301 リダイレクトさせていました。 この場合、Googlebot に http のアク...

>>記事を確認する

GoogleMapのAPIキーの認証情報にリファラURL設定

昔は API キーを指定することで、JavaScript で GoogleMap が表示できていましたが、何年か前に、そのキーに対して認証情報の追加が推奨されました。 新規で発行する場合は必須になっているかもしれませんが...

>>記事を確認する

【30分でできる】AmazonLinuxでApache2.4+php7.1+Laravel5.5

先日、「 VagrantでCentOS6.9のイメージを使う 」の通り、CentOS6.9 には Apache2.4 と PHP7.1 で Laravel のフレームワークが使える環境を構築しました。 ただ、将来的には AWS かつ Amazon Linux 上で動か...

>>記事を確認する