まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

タグ:s3

PiTop を購入して依頼、ラズベリーパイ(以下「ラズパイ」)をデスクトップ環境として使うことが多くなりました:

2016080702


さて PiTop に限りませんが、ラズパイをデスクトップ環境として使う場合の問題点はアプリケーションの充実度と、ストレージの少なさです。前者は少しずつ充実しつつあるのですが、そもそもマイクロ SD カードを挿して、そこに OS を導入して使うという手法を取る以上は、このマイクロ SD カードの容量が全空間なわけです。これはどうにもならない。。

・・・と諦めかけていた中で思いつきました。そもそも IoT 機器として使うことも多いラズパイは常に給電状態であることも多く、ネットワークもONの前提で使うことができます。であればクラウドなどの外部ストレージをネットワークマウントしてしまえば、この容量の問題を解決できるのではないか!? と。

実際に試したみた時の様子を以下に記載します。今回はいわゆる S3 互換(Swift互換)のオブジェクトストレージをラズパイにマウントする、という方法に挑戦してみました。具体的には IBM Bluemix のオブジェクトストレージサービスを使って実現してみました:

Swift のオブジェクトストレージをマウントするために CloudFuse を使うことにします。CloudFuse に関しては(前提環境が異なりますが)以前にもこのブログで何度か紹介したことがあります。興味のある方、特に CentOS でマウントさせることに興味ある方はこちらも参考にしてみてください:
SoftLayer の Object Storage をサーバーインスタンスにマウントする


話を戻して、まずはラズパイに CloudFuse を導入しましょう。まずは root になって apt-get のリポジトリを更新します(これをしないとエラーになったので):
$ sudo su
# apt-get update
# apt-get upgrade

次に CloudFuse の実行やビルドに必要なライブラリをまとめて導入しておきます:
# apt-get install build-essential libcurl4-openssl-dev libxml2-dev libssl-dev libfuse-dev libjson-c-dev

ここまで準備できれば CloudFuse のビルドが可能になります。GitHub からソースコードをダウンロードして、展開して、ビルドして、インストールします:
# cd /usr/local/src
# git clone https://github.com/redbo/cloudfuse
# cd cloudfuse
# ./configure
# make
# make install

これで CloudFuse の準備ができました。後はオブジェクトストレージの環境に合わせた設定をしてマウントするだけです。既にオブジェクトストレージ環境をお持ちの方はその環境に合わせた情報を使ってください。

以下はまだオブジェクトストレージ環境をお持ちでない場合の方向けに、IBM Bluemix のオブジェクトストレージ環境を入手する方法から紹介します。IBM Bluemix のオブジェクトストレージのインスタンスを利用するにはこちらの手順を参照ください(無料で 5GB まで使えるオブジェクトストレージ環境が入手できます):


上記手順の、オブジェクトストレージサービスの接続情報を取得するところまでができていればOKです。以下、ここで取得したオブジェクトストレージのファイルシステムをラズパイにマウントしてみます。
2016080701


この Bluemix 環境のオブジェクトストレージを利用する場合は、上記画面の環境変数内の auth_url, userId, password の3つの値(下記の赤字部分)が必要になります。この3つの値をメモしておきましょう:

{
  "credentials": {
    "auth_url": "https://identity.open.softlayer.com",
    "project": "object_storage_**************************",
    "projectId": "******************************",
    "region": "******",
    "userId": "(userId)",
    "username": "Admin_*************************************",
    "password": "(password)",
    "domainId": "**********************************************",
    "domainName": "******"
  }
}


改めてラズパイ環境に戻ります。ラズパイに導入した CloudFuse を使って、このオブジェクトストレージ環境をマウントするにはホームディレクトリ以下に .cloudfuse というテキストファイルを以下の3行の内容で作成します:
username=(userId)
api_key=(password)
authurl=https://identity.open.softlayer.com/v3/

最初の username の値は環境変数内のuserId の値、api_key の値は同 password の値、そして authurl の値には同 auth_url の値に "/v3/" をつけたものを指定します。Bluemix のオブジェクトストレージ以外の環境を使っている場合はその環境に合った相当する値を取り出して指定してください。

これで準備完了です。最後にマウントポイント(この例では /mnt)を指定して CloudFuse を実行します:
# cloudfuse /mnt

このコマンドが成功すると、オブジェクトストレージの内容を /mnt 以下にマウントすることができます:
# df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/root         30G  4.6G   24G   17% /
devtmpfs         459M     0  459M    0% /dev
tmpfs            463M     0  463M    0% /dev/shm
tmpfs            463M  6.4M  457M    2% /run
tmpfs            5.0M  4.0K  5.0M    1% /run/lock
tmpfs            463M     0  463M    0% /sys/fs/cgroup
/dev/mmcblk0p1    60M   20M   41M   34% /boot
tmpfs             93M  8.0K   93M    1% /run/user/1000
cloudfuse        8.0T  7.5M  8.0T    1% /mnt
  ↑最大 8TB までのストレージがラズパイ上で使えるようになりました!


ちなみに、マウントしたオブジェクトストレージを解除するには umount コマンドでアンマウントするだけです:
# umount /mnt


このエントリが特定の個人を揶揄する目的で作ったものではないことを最初にお断りしておきます。


ちょうど今(2016/Mar/24)話題になっている某氏の謝罪ウェブサイトを見ていて、あることに気付きました:
2016032400


このページの内容自体にどうこう言うつもりはありません。問題はこのページの URL です。http://ototake.com/ にアクセスするとこのページが表示されるようになっています。もともとはこの人のウェブページ用のサーバーだったはずだけど、トップページだけ作り変えたのでしょうか?


ではプロフィール紹介用のページ http://ototake.com/profile/ はどうなっているのか、と思ってアクセスすると、404 エラー(ページが見つからない)になりました:
2016032402


ちなみに(グーグルのキャッシュによると)以前はこんなページだったはず:
2016032403


トップページを変えただけでなく、プロフィールページも消したのか・・・ いや違う。このエラーページの内容は単なる「ページが見つからない」ではなく、"Code: NoSuchKey" とか、 "Key: profile" とか、何かをシステマチックに探した上で見つからない、というエラーに見えます。単にページ内容を入れ替えたものではなさそうです。


この謎はアドレスを逆引きして分かりました:
2016032401


なるほど、Amazon S3静的ウェブホスティング機能を使って作られたページだったようです。ということはどこかに元のページも残しつつ、DNS の切り替えだけでこの謝罪ページに飛ぶよう設定されていた、ということです。

なかなかうまい方法だと思いました。まず今回のような謝罪ページは一時的にアクセスが集中する可能性があるので、今まで使っていたウェブサーバーの中身を置き換えただけではアクセスを捌ききれる保証はありません。そこを S3 の静的ウェブホスティングにすれば比較的安価に(アカウントを新規に作れば1年間は無料で)それなりの可用性が保証されたこのページを作ることができます。 そして DNS の切り替えでこの新ページを運用しているとすれば、謝罪終了(?)後に元のページへ戻す作業も DNS を切り替え直すだけで簡単に済みますし、その後は謝罪ページも消してしまえば、それ以降の料金はかかりません。 ということは現在のサーバーを落とす必要もないので、再切り替え時の手間やトラブルも少なく済みそう、と推測されます。


このやり方はうまいなあ、と思いました。DNS の切り替えにかかるタイムラグや、各種キャッシュの切り替わりを意識する必要はあるにせよ、コスパのいい謝罪ページ運用だと感心してしまいました。もちろん謝罪用だけでなく、何らかの事情で一時的に異なるページを表示する必要が生じた場合の方策と考えても使えると思います。

S3 互換のオブジェクトストレージサービスを運用している会社にとってはビジネスの参考になります(苦笑)。


先週、IBM BluemixObject Storage サービスがベータを卒業して正式サービスになりました:
2015022101


SoftLayer 上に用意された Swift と呼ばれる標準的なオブジェクトストレージ機能を Bluemix を通じて提供するものです。5GB であれば無料サービスとして利用できます:
2015022102


では、この Bluemix 上の Object Storage サービスをクライアントから使う方法を紹介します。


1. Swift ツールの導入

このサービスを Linux(CentOS) から実際に利用するまでの手順を紹介します。このサービスを使うには swift と呼ばれるツール(swiftclient)が必要です。まずはこのツールを導入しましょう。

swift の導入は pip を使って行います。最初にこの pip を導入する必要がありますが、pip の導入に必要なライブラリをあらかじめまとめて導入しておきます:
# yum install fuse fuse-libs fuse-devel libattr-devel gcc gcc-c++ kernel-devel libxslt-devel

ここで導入した fuse ライブラリを読み込んでおきます:
# modprobe fuse

次に pip の導入に必要な Python 3 を導入します。Python 3 は yum ではインストールできないため、PUIAS から導入します。まずはそのための GPG Key をインストールします:
# cd /etc/pki/rpm-gpg/
# wget -q http://springdale.math.ias.edu/data/puias/6/x86_64/os/RPM-GPG-KEY-puias
# rpm --import RPM-GPG-KEY-puias

次に /etc/yum.repos.d/puias-computational.repo ファイルを以下の内容で作成します:
# vi /etc/yum.repos.d/puias-computational.repo

(以下を作成して保存)
[PUIAS_6_computational] name=PUIAS Computational Base mirrorlist=http://puias.math.ias.edu/data/puias/computational/$releasever/$basearch/mirrorlist gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-puias

作成したリポジトリファイルを使って yum で Python 3 一式をインストールします:
# yum install python3 python3-devel python3-libs python3-setuptools

Python 3 がインストールできていれば pip がインストールできます:
# wget -O - https://bootstrap.pypa.io/get-pip.py | python3

これでやっと pip の導入ができました。ではこの pip を使って keystoneclient と swiftclient をインストールします:
# pip install python-swiftclient
# pip install python-keystoneclient

ここまでの手順で swift コマンドが使えるようになっているはずです。


2. Object Storage サービスの追加と、環境変数の設定

Bluemix 上で Object Storage サービスを追加し、その資格情報を確認します:
2015022103


環境変数 VCAP_SERVICES の内容は以下の様な JSON 形式のテキストになっているはずです。これらのうち、赤字部分をメモしておきます(後で使います):
{
  "Object-Storage": [
    {
      "name": "Object Storage-7d",
      "label": "Object-Storage",
      "plan": "Free",
      "credentials": {
        "auth_url": "https://identity.open.softlayer.com",
        "project": "object_storage_(project)",
        "projectId": "(projectId)",
        "region": "dallas",
        "userId": "(userId)",
        "username": "Admin_(username)",
        "password": "(password)",
        "domainId": "(domainId)",
        "domainName": "(domainName)"
      }
    }
  ]
}

ここで取得した接続情報を Swift クライアント(Linux)の環境変数に(例えば /etc/bashrc などに)設定します:
export OS_USER_ID=(userId)
export OS_PASSWORD=(password)
export OS_PROJECT_ID=(projectId)
export OS_AUTH_URL=https://identity.open.softlayer.com/v3
export OS_REGION_NAME=dallas
export OS_IDENTITY_API_VERSION=3
export OS_AUTH_VERSION=3

↑上の赤字部分は接続情報のものを使い、青字部分は接続情報には含まれていないのですが、上記のように書き足してください。/etc/bashrc に書いた場合は再ログインするなどして、この環境変数が有効になった状態にしてください。これで swift を使う準備が整いました。


3. swift コマンドを実際に使ってみる

Object Storage はコンテナと呼ばれるフォルダ単位で利用します。現在のコンテナ一覧を確認してみましょう。以下のコマンドを実行します:
# swift list

初めて実行した時には(コンテナが存在していないので)何も表示されないはずです。コンテナを作成するにはコンテナ名を指定して post コマンドを実行します。以下の例では dotnsf-container というコンテナを作成しています:
# swift post dotnsf-container

このコマンド実行後に再度コンテナ一覧を確認すると、作成した dotnsf-container が表示されるはずです(緑字が出力結果):
# swift list
dotnsf-container

次にコンテナの中身を確認します:
# swift list dotnsf-container

これもコンテナ作成直後に実行した段階では(中身がないので)何も表示されないはずです。 ではこのコンテナにローカルファイル(以下の例ではカレントディレクトリの abc.txt を指定してアップロードしてみます:
# swift upload dotnsf-container abc.txt

この後に再度コンテナの中身を確認すると、アップロードしたファイルが追加されていることが確認できます:
# swift list dotnsf-container
abc.txt

コンテナ内のファイルは以下のコマンドでカレントディレクトリにダウンロードできます:
# swift download dotnsf-container abc.txt

コンテナ内のファイルが不要になった場合、以下のコマンドでコンテナから削除できます:
# swift delete dotnsf-container abc.txt
abc.txt

一通りのコンテナ/ファイル操作コマンドが利用できそうです。



(参考)
https://www.ng.bluemix.net/docs/services/ObjectStorage/index.html





AWS(Amazon Web Services) のストレージサービスである S3。特定条件の中で利用する限りは無料になるし、容量1GBに付き月10円弱で使えるし、これ単体で静的なウェブホスティングにも使えるので、ちょっとしたファイル置き場以上の便利さがあります。

最近、この S3 をバケット単位でマウントできるという s3fs というツールの存在を知りました。その紹介です。

そもそも S3 をマウントできると何がうれしいのか?単なるファイル置き場というだけでなく、自分が最近使う機会の多い WordPress をクラスタリング環境にする際にネットワークマウントは必須になっている、という背景もあり、自分の場合にはそういったネットワークマウントのできるパブリックなクラウドストレージは WordPress と併用する環境としても魅力的なのでした。


ここでちょっとだけ脱線を。WordPress 自体はデータを RDB(一般的には MySQL)内に格納するので、クラスタリング環境を構築する上で特別意識することはないように思えます。ただし、ファイルをアップロードして利用する場合だけは注意が必要です。WordPress のファイルアップロード(メディアアップロード)では、アップロードされたファイルはファイルシステム上に移動されて、WordPress 自身はそのファイルパスの情報だけを格li納します(つまりバイナリの情報はDBには格納しません)。

この挙動は WordPress が1台の HTTP サーバー環境で稼働する場合は大きな問題にはなりにくいと思っていますが、例えば2台の HTTP サーバー(A, B) でクラスタリング環境を構成していた場合で考えると問題が浮き彫りになります。

仮に2台のうちのサーバーA上で、このメディアアップロードが実行されたと仮定します。サーバーA はアップロードされたファイルを自分自身の /var/www/html/wordpress/wp-content/uploads/ 以下に移動します。仮にそのファイル名が /var/www/html/wordpress/wp-content/uploads/aaa.jpg となったとします。

上記のように WordPress ではバイナリの情報は DB に格納せず、そのファイルパス情報だけを DB に格納します。つまりアップロードされたファイルは /var/www/html/wordpress/wp-content/uploads/aaa.jpg に存在する、という情報だけを DB に記憶することになります。サーバーA 内ではこれで問題になることはありません。

ところがクラスタリングのもう一台であるサーバーBも同じDBを参照しているので、サーバーBからも「該当ファイルは /var/www/html/wordpress/wp-content/uploads/aaa.jpg に存在する」と見えてしまします。このファイルはサーバーA のファイルシステムには保存されていますが、サーバーB には存在していません。したがって例えばサーバーB 上の処理でこの画像を表示させようとすると「ファイルが存在しない」ことになってしまいます。クラスタリングの振り分けはユーザーがコントロールできるわけではないので、ユーザーによってファイルが見えたり見えなかったり、ということが起きてしまいます。

これを解決するにはディレクトリを共有するしかありません。上記例であれば /var/www/html/wordpress/wp-content/uploads/ 以下が実際にはネットワークフォルダになっていて、その同じ箇所をサーバーA/B 双方からマウントして参照する、という構成になっている必要があるのでした。そしてそのようなネットワークフォルダをどうやって用意・調達するか、という問題に直面することになるのでした。


少し脱線しましたが、こんな背景の中で「無料でも使える AWS S3 がマウントできる」というのはかなり魅力的な情報なのでした。早速試してみたので以下にその手順を紹介します:

まずは S3 側の準備をします。仮に "awsuser1" という名前のバケットが S3 上に作成済みであると仮定し、このバケットを共有する前提で紹介します:
2014031201


必要な設定は、このバケットに接続するための認証ユーザーの作成です。既に別の AWS サービス用などにユーザーを作成済みであればそのユーザーを流用しても構いませんが、ここでは S3 アクセス用のフル権限を持ったユーザーを新規に作成することにします。

AWS のサービス一覧から IAM を選択します:
2014031202


左ペインで Users を選択し、"Create New Users" ボタンをクリックします:
2014031203


(名前自体はあまり重要ではないので)適当な名前のユーザーを作成します:
2014031204


作成直後のダイアログの "Show User Security Credentials" をクリックして展開します:
2014031205


展開後に表示される "Access Key ID" と "Secret Access Key" 両方の値をメモするかダウンロードして、後から参照できるようにしておきます。記録できたら "Close Window" でこのダイアログを閉じます:
2014031206


次にこのユーザーに S3 へのアクセス権を付与します。左ペインで Users が選択された状態に戻ります。ここで作成したユーザーを選択し、右下のユーザー詳細情報ペインでは "Permissions" タブを選択します。その中の "Attach User Policy" ボタンをクリックします:
2014031207


アクセス権指定のダイアログが表示されます。Select Policy Template と書かれたリストの下の方に "Amazon S3 Full Access" という列があるので、この右の "Select" ボタンをクリックします:
2014031208


確認画面になるので "Apply Policy" をクリックします。これでこのユーザーは S3 へのフルアクセス権を持ったことになります:
2014031209




次はマウント元側の設定です。今作成した(S3 へのフルアクセス権を持った)ユーザーでマウントするための設定を行います。まずインターネットに接続された Linux を用意します。以下 CentOS を使っている前提で紹介しますが、ディストリビューションによる可不可は特にないと思っています(AWS のインスタンスでも、そうでなくてもできます)。

まず事前準備として必要そうなライブラリを導入しておきます:
# yum groupinstall "Development Tools"  (C/C++ コンパイル環境を導入)
# yum install openssl-devel (libcrypt 0.9 を導入) # yum install libcurl-devel (libcurl 7.0 を導入) # yum install libxml2-devel (libxml-2.0.2.6 を導入)

上記3ライブラリに加えて fuse 2.8.5 が必要になります。AWS の EC2 インスタンスからは普通に yum でインストールすることもできます(yum install fuse fuse-devel)が、yum でインストールできないケースも多いのでビルド手順を紹介します。
# cd /usr/local/src
# wget http://sourceforge.net/projects/fuse/files/fuse-2.X/2.8.5/fuse-2.8.5.tar.gz
# tar xzvf fuse-2.8.5.tar.gz
# cd fuse-2.8.5
# ./configure --prefix=/usr
# make
# make install
# ldconfig
# modprobe fuse

fuse までが導入できると s3fs のビルド条件がそろったことになります。以下の手順で s3fs をビルドします:
# cd /usr/local/src
# wget http://s3fs.googlecode.com/files/s3fs-1.61.tar.gz
# tar xzvf s3fs-1.61.tar.gz
# cd s3fs-1.61
# export PKG_CONFIG_PATH=/usr/lib/pkgconfig:/usr/lib64/pkgconfig/
# ./configure --prefix=/usr
# make
# make install

これで s3fs のインストールが完了しました。最後に S3 へアクセスするためのユーザーの設定を行います。/etc/passwd-s3fs というファイルを、上記ユーザー作成時にメモした Access Key ID と Secret Access Key を使って、以下のような内容で新規に作成します(カッコは不要です):
# echo '(Access Key ID):(Secret Access Key)' > /etc/passwd-s3fs

仮に Access Key ID が ABCD で Secret Access Key が wxyz だった場合、/etc/passwd-s3fs の中身は以下の一行になります:
ABCD:wxyz

このファイルは他者から参照できないようにする必要があるため、ファイルパーミッションを変更します:
# chmod 640 /etc/passwd-s3fs

マウント先のディレクトリを用意します。ここでは /mnt/s3 というディレクトリに S3 をマウントすることにします:
# mkdir /mnt/s3

これで全ての準備が整いました。S3 の awsuser1 というバケットを /mnt/s3/ にマウントするには以下のようなコマンドを実行します。バケット名やマウント先は環境に合わせて適宜変更してください:
# s3fs awsuser1 /mnt/s3/ -o allow_other,default_acl=public_read

結果はこんな感じになりました。S3 って容量としては 256TB も用意されてるんですねw:
2014031210


再起動時にもこのマウントを有効にするには、同じコマンドを手動で再発行するのではなく、 /etc/fstab に以下の1行を追加記述するのがいいと思います。これもバケット名やマウント先は環境に合わせて適宜変更してください:
s3fs#awsuser1 /mnt/s3 fuse allow_other,default_acl=public-read 0 0


こんな感じで S3 をファイルシステムにマウントできることがわかりました。後は WordPress をクラスタ環境で使う場合は、メディアアップロードのディレクトリをこのマウント先にしておけば、同じイメージをクローンしてもクローン先でも同じ S3 を参照することになるので上述のような問題を回避できることになります、たぶん。





 

このページのトップヘ