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

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

タグ:object

みんな大好き WordPress 。自分もローカルコンテナやクラウド、ホスティングなど色々な形態で活用しています。最近は k8s などのパブリックなコンテナ環境下で使われることも珍しくなくなってきました。

実際に環境構築した経験のある人はわかると思いますが、この WordPress はシングルサーバーのシングルテナント構成(サーバーもインスタンスも1台で、1つの WordPress サイトを作る構成)であれば構築手順は簡単なのですが、負荷分散を考慮して複数サーバーインスタンス化した構成を考慮に入れるととたんにややこしくなります。理由もシンプルではないのですが、最大の問題はメディアストレージと呼ばれる画像などのファイルアップロード空間がファイルシステムを前提としている点にあります。簡単に説明すると、コンテンツ内で使う画像をアップロードすると、その画像はサーバーのファイルシステム上に保存されます。表示される際も当然サーバーのファイルシステム上の画像を参照することになります。サーバーが1台であればこれで問題ないのですが、サーバーが複数台(例えばAとBの2台)あった場合、サーバーAのファイルシステムに画像を保存して、サーバーAから画像を参照すると画像が見えますが、サーバーBのファイルシステムには画像は存在していないので、参照しても見つからない、という結果になってしまいます。負荷分散の仕組みが存在している以上、サーバーAを使うかサーバーBを使うかは毎回変わる可能性があるので、アクセスするたびに画像が見えたり見えなかったりすることになります。サーバーが3台、4台と増えていくと、画像が見える確率はどんどん下がっていきます。これでは使い物になりません。

そのため、WordPress では一般的にメディアストレージには全サーバーから参照可能な共有ストレージをマウントして指定します。こうすることで全サーバーが同じストレージにメディアファイルをアップロードすることになり、全てのサーバーから参照可能になる、というわけです。WordPress 環境構築時によく使う典型的な作業でもあり、この機能に関連した多くのプラグインも提供されています。

で、この WordPress の共有メディアストレージに IBM Cloud の Object Storage を指定する方法を調べたので、自分用メモの意味も込めてまとめました。IBM Cloud の Object Storage はいわゆる「S3互換」のオブジェクトストレージで、一定の条件下で無料利用(しかもクレジットカード不要!)できます。詳しくは後述の説明を参照いただきたいのですが、無料枠でも容量としては 25GB まで使えるので、WordPress の規模としてはそこそこ大きなものでもまかなえる共有ストレージだと思っています。


【WordPress 環境の準備】
まずは WordPress 環境を用意します。具体的には MySQL データベースサーバーと、WordPress が展開された HTTP サーバー。複数サーバーでなければ localhost で構築してもいいですし、ローカルの docker/docker Compose で用意してもいいし、有料/無料のクラウド/ホスティングサーバーを使っても構いません。管理者権限でログイン可能な WordPress 環境を1つ用意してください。この時点ではメディアストレージに特別な設定は不要で、デフォルトのファイルシステムをそのまま使う設定であると仮定します。


【IBM Cloud Object Storage(IBM COS) の準備】
次に上述環境のメディアストレージとなる IBM COS を用意します。IBM Cloud アカウントを所有していない場合はこちらから作成してください(作成後にクレジットカードを登録することでより多くのサービスを利用できるようになりますが、今回紹介している内容をそのまま実行するだけであれば登録しないアカウントでも可能です):
https://cloud.ibm.com/registration


IBM Cloud アカウントでログイン後、ダッシュボード画面から「リソースの作成」ボタンをクリックします:
2021092101


検索ボックスに "object storage" と入力し、見つかった "Object Storage" を選択します:
2021092102


次の画面で料金プランを選択します。料金体系が "Free" と表示されたライトプランが選択されていることを確認してください(ライトプランは無料ですが、Standard プランは有料です)。そして画面右下の「作成」ボタンをクリックします:
2021092103



なお、このライトプランの制約事項は以下のようなものです。ストレージ容量としては 25GB ですが、リクエストの回数やパブリックアウトバウンド容量などに一か月単位の上限が設定されています。また30日間非アクティブな状態が続くと削除されます(このプランのままこの制約を超えて使うことはできませんが、有料プランにアップグレードすることで制約を超えて使うことは可能です)。ご注意ください:
2021092104


Cloud Object Storage サービスが作成され、以下のような画面が表示されます:
2021092105


ではこの Object Storage にデータ(今回は画像)を格納するバケットを作成します。左メニューから「バケット」を選び、「バケットの作成」ボタンをクリックします:
2021092101


バケットの属性を選択したり、カスタマイズできたりするのですが、今回は定義済みのバケットを使うことにします。「すぐに始める」と書かれたカードの→印部分をクリック:
2021092102


ここでは3ステップでバケットを定義しますが、実質的に最初のここだけがカスタマイズ部分となります。これから作成するバケットの名称を適当に入力します。以下の例では WordPress のメディアストレージ向けということで、自分の名前も使って "kkimura-wordpress-media" と入力しています。ここは皆さんがわかりやすい名前を入力してください。そして「次へ」:
2021092103


次の画面ではそのまま「次へ」:
2021092104


最後の画面も特に変更する必要はありません。そのまま「バケット構成の表示」ボタンをクリックします:
2021092105


すると入力した名称でバケットが作成されます。この時に「ロケーション」欄に表示されている内容は後で使うのでメモしておきます(下図の例だと "jp-tok"):
2021092106


バケットが作成できたら、次はこのバケットを外部から(今回の例だと WordPress から)利用できるようにするための情報を取得します。画面左のメニューで「サービス資格情報」を選択し、「新規資格情報」ボタンをクリックします:
2021092107


資格情報の作成ダイアログが表示されたら「詳細オプション」を開き、役割が「ライター」になっていることを確認した上で、「HMAC 資格情報を含める」をオンにしてから「追加」ボタンをクリックします:
2021092108


いま追加した資格情報が一覧に表示されるので、名称部分をクリックして展開します:
2021092109


以下のように追加したサービス資格情報が表示されます:
2021092110


サービス資格情報は以下のようなフォーマットになっているので、"cos_hmac_keys" の中の "access_key_id" の値と、"secret_access_key" の値をメモしておいてください:
{
  "apikey": "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "cos_hmac_keys": {
    "access_key_id": "xxxxxxxxxxxxxxxxxxxxxxxx",
    "secret_access_key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  },
  "endpoints": "https://control.cloud-object-storage.cloud.ibm.com/v2/endpoints"
    :
    :
}

※ サービス資格情報に cos_hmac_keys というキーそのものが存在していない場合は、資格情報を作成する際に「HMAC 資格情報を含める」オプションをオンにしていない可能性があります。上述の手順を再度確認してもう一度実行してみてください。


最後にエンドポイントを確認します。画面左メニューから「エンドポイント」を選択し、バケットを作成した時に確認したロケーション情報( Regional の jp-tok)に合わせて「回復力」と「ロケーション」を設定し、そこで表示されるパブリック URL の内容をメモしておきます:
2021092111


これで IBM COS 側の設定と準備も完了です。改めて、この時点で  IBM COS に関する以下の情報が入手できていることを確認してください。これらがすべてわかっていれば WordPress のメディアストレージとしてマウントできるようになります(手順は後述します):
取得・確認方法
バケット名バケット作成時に指定した名前
access_key_idサービス資格情報内
secret_access_keyサービス資格情報内
エンドポイント作成したバケットのロケーション情報に合わせて取得したパブリック URL


【Media Cloud プラグインのインストールと設定】
ここまでの手順が正しく実施できて、上述の4つの情報が取得できていれば WordPress に IBM COS のバケットをメディアストレージとしてマウントできる準備が整ったことになります。以下では実際にマウントする手順を紹介します。

まず WordPress の管理機能にアクセスできるアカウントでログインし、管理画面に移動します。まずObject Storage をメディアストレージとしてマウントするための Media Cloud プラグインをインストールします。画面左のメニューから「プラグイン」を選び、「新規追加」ボタンをクリックします:
2021092201


キーワード検索ボックスに "Media Cloud" と入力します:
2021092202


候補がいくつか見つかりますが、その中に以下のような "Media Cloud for Amazon S3, ..." というプラグインが見つかります。ここの「今すぐインストール」をクリックしてインストールします:
2021092203


インストールに成功すると「有効化」というボタンに変わります。このボタンもクリックしてプラグインを有効にします:
2021092204


更新通知機能をオプトインするかどうかを聞かれます。オプトインする場合は「許可して続ける」、したくない場合は「スキップ」のいずれかを選んで先へ進みます:
2021092205


Media Cloud のセットアップウィザードが起動します。まずは Next をクリック:
2021092206


最初に Object Storage のプロバイダーを選択します。IBM COS の場合は "S3 Compatible" を選択します:
2021092207


S3 互換ストレージの設定が開始されます。"Next" をクリック:
2021092201


次の画面で先程準備した IBM COS の情報を入力します。入力内容は以下のようにします:
項目名入力する値
ACCESS KEYaccess_key_id の値
SECRETsecret_access_key の値
BUCKET作成したバケット名
REGION(Automatic のまま)
CUSTOM ENDPOINTエンドポイント URL

最後に "Next" をクリック:
2021092202


入力した値が正しく利用できるかどうかを確認するいくつかのテストを行います。"START TESTS" をクリック:
2021092203


実際にバケットに対してファイルをアップロードして、アップロードできていることを確認して、削除して・・・といったテストが行われます。すべて成功すると下図のように5つのグリーンでチェックマークが表示され、正しく利用できる状態であることが確認されました。"Next" をクリック:
2021092204


これで Media Cloud を利用できる状態になりました。"FINISH & EXIT WIZARD" をクリックして設定ウィザードを終了します:
2021092205


WordPress の管理画面に戻り、"Media Cloud" メニュー内の "Enable Cloud Storage" がオンに設定されていることを確認します:
2021092206


ちなみに、ここで設定した値は MySQL データベースの wp_options テーブル内に格納されているようです。なので、この状態で(データベースへの接続情報が含まれた状態で)サーバーの内容をコンテナイメージ化すれば、コンテナ環境でも動く状態が作れる、と思います:
2021092201



最後にメディアストレージが Object Storage に切り替わっていることを WordPress 内からも確認しておきましょう。管理画面の「メディア」を選択し、メディアライブラリの「新規追加」で適当な画像ファイルを選択して追加します:
2021092207


試しにこんな感じで1つ画像をアップロードしてみました(この画像は WordPress のコンテンツとして利用することができず状態になっています):
2021092208


改めて IBM Cloud のダッシュボードに戻り、IBM Cloud Object Storage のバケット内を表示してみると、画像ファイルが追加されているはずです(2つ追加されているのは、1つのアップロードに対して元画像とサムネイル用の2つの画像が追加されているからのようです):
2021092209


画像を1つ選択すると右にウィンドウが表示され、ここからダウンロードすることができます:
2021092201


実際にダウンロードして表示し、WordPress 画面からアップロードした画像が Object Storage に格納されていることを確認します:
2021092202


WordPress のメディアストレージとして IBM Cloud の Object Storage を利用できることが確認できました。IBM Cloud の Cloud Object Storage を使うことである程度の規模まで無料でこの環境での運用ができるので、バケットを複数用意して使うケースも含めて、実運用前の構築段階ではとても便利に使うことができそうです。

2013 年を最後に SoftLayer の記事を書いていませんでした。久しぶりで緊張します。。

2年以上 SoftLayer から離れていましたが、その間に大きな変化を遂げていました。もちろん知ってはいたのですが、自分が使う立場ではなかったため、変化を具体的に実感する機会がありませんでした。

最近、業務にかこつけて仕事で SoftLayer インスタンスを利用してシステムを構築する、という機会がありました。普段 PaaS (と個人環境の仮想 Linux)ばかり触っていたので、久しぶりの IaaS でした。その業務の中で SoftLayer 上の Linux サーバーインスタンスのファイルシステム上に Object Storage のフォルダをマウントする、という環境を構築する機会があったので、作業内容をまとめておきました。

ちなみに今回の作業の参考にしたのはこちらのサイトです:
https://www.change-makers.jp/post/10362

ただ、この作業そのままでは自分の環境では動かなかったので、あくまで自分の環境で動かした時の作業内容を記載しておきます。自分の環境は CentOS 6.7 64bit です。


まず、Swift 互換の Object Storage を Linux のファイルシステムにマウントするには CloudFuse というオープンソースのライブラリ/ツールを使います。

というわけで CloudFuse を導入します。CloudFuse はソースからビルドして導入するので、まずはビルドをするために必要な前提ライブラリを導入します:
# yum install gcc make fuse fuse-devel curl-devel libxml2-devel openssl-devel git

※上記の Change Makers のサイトではこれで前提ライブラリが導入されることになっていましたが、自分の環境ではビルドに失敗してしまいました。結果として以下のこの処理が足りませんでした:
# yum install json-c-devel

前提ライブラリが準備できたら CloudFuse (のコマンドラインツール)をダウンロードしてビルドします。ダウンロードは GitHub から最新ソースをクローンします:
# cd /usr/local/src
# git clone https://github.com/redbo/cloudfuse

そして configure して、make して、make install します。これで cloudfuse コマンドが使えるようになります:
# cd cloudfuse
# ./configure
# make
# make install

cloudfuse コマンドを使って Object Storage を利用するには、目的の Object Storage にアクセスするための情報(url, username, password)が必要です。SoftLayer の場合は次の方法で取得します。 SoftLayer のコントロール画面のメニューから Storage - Object Storage を選び、利用中の Object Storage を選択し、その画面内の "View Credentials" と書かれた箇所をクリックします:
2016040201


すると以下のようなアカウントクレデンシャル情報が表示されます。この値を後で使うのでメモしておきます:
2016040202


SoftLayer のインスタンス画面に戻り、ホームディレクトリ上に ~/.cloudfuse というファイルを新規に作成します。その内容は先程確認したクレデンシャル情報を使って、以下の内容にして保存します:
# vi ~/.cloudfuse

username=(Username の値)
api_key=(API Key の値)
authurl=(Authentication Endpoint の値。SoftLayer 以外から使う場合は Public 、SoftLayer のサーバーから使う場合は Private の値にする)

なお authurl に指定する値ですが、この Object Storage のマウント自体は SoftLayer ではないクラウドサーバーやオンプレミスサーバーから行うことができます。その場合は Public と指定されていた方の URL を記載してください。一方 SoftLayer のサーバーからマウントする場合は Private と指定されていた方の URL を記載すると、プライベートネットワークを使った高速接続が出来、かつ SoftLayer 内のインバウンド転送なので追加料金がかかりません。

ここまでできたらマウントします。cloudfuse コマンドを使って、Object Storage のフォルダを SoftLayer インスタンスの /mnt ディレクトリにマウントしてみます:
# cloudfuse /mnt

これでマウントは完了しているはずです。df コマンドで確認してみます:
# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda2       25G  7.4G   16G  32% /
tmpfs           935M     0  935M   0% /dev/shm
/dev/xvda1      248M   94M  142M  40% /boot
cloudfuse       8.0T  4.2G  8.0T   1% /mnt
↑Object Storage って最大 8TB も使えるのね。。


ちゃんとマウントできています。これで Object Storage が SoftLayer インスタンス上のファイルシステムとして読み書き可能になりました!

画像などメディアファイルを多く扱うようなシステムを構築する場合、パフォーマンスのためにメディアデータはデータベースではなくファイルシステムに格納することも珍しくありません(WordPress とかもそうです)。この場合、アプリケーションサーバーをスケールさせてもメディアを保存するファイルシステムがバラバラになってしまっては意味ないので、メディアを保存する先は Object Storage をマウントした先に指定する方法が一般的です(そうするとマウント情報ごとスケールするので、メディアも共有できるようになる)。 そんなシステム構築ではこんな手法を使う、というサンプルでした。特に SoftLayer + Object Storage 環境であれば、ネットワークも高速で、かつマウントした Object Storage への転送時の追加料金もかからずに構築できるというメリットがあります。


このページのトップヘ