想ひ出のへっぽこBlogⅡ from35

~ 自身の備忘録および学習促進のためにブログります。~

想ひ出3: NFS ReplicaパターンでWordpressを構築する

はじめに

このところ、AWS(GCPも)触りたい病に患っているmoqrinです。
ということで、NFS Replicaパターンを構築します。
なお、以下、比較的よくある場面を想定して取り組みます。

Wordpress1~3の課題をNFS Replicaパターンでもって対応する。

1. 大事な記事を紛失しない冗長性が考慮されていること
2. 時間によってはそれなりのアクセス数が見込まれるため、そのタイミングでスケールアウトしたい
3. 頻繁に記事をアップするサイトのため、出来るだけリアルタイムで記事更新したい

NFS Replicaパターンについて

できること

  • 直接記事を追加したり、更新するNFSサーバー上のファイルを共有して、それ以降にAutoScalingなどで新たに起動されたEC2でもそのファイルが利用できる。
  • 上記の通り、本体のNFSサーバーが仮にダウンしたとしても、各EBSにコンテンツがあるのでSPOFにならない。
  • 各EC2のEBS上に、NFSサーバーの共有ファイルが存在するので、NFSサーバーにアクセスする必要がなく、レイテンシーが低くなり、パフォーマンスが問題になりにくい。

詳細はここに書いてありますが、概略は下図のようになります。

f:id:moqrin3:20181130233301p:plain
NFS Replica

それでは実際に構築します。
ちなみに環境は、CentOS 7(x86_64),PHP7.0です。

設定の概要手順

設定の概要となる手順は以下1~3です。
1. マスターとなるWordpressEC2を作成。
2. マスターEC2のイメージで調整用AMIを作成。調整用AMIからクローンEC2作成。
3. クローンEC2のイメージでAMIを作成。ELB,AutoScalingGroupに登録。
(詳細は割愛しますー)

マスターEC2の作成

まずは記事を更新するための本体サーバーを構成します。
なお、Wordpress設定の記事については山ほどあるので割愛します。

注意点だけ列挙します。

・PHP7.0以上におけるwp-exec-phpの修正

# /wp-content/plugins/wp-exec-php/wp-exec-php.php
- && $blog_user =& new WP_User($blog_user->ID)
+ && $blog_user = new WP_User($blog_user->ID)

ドメイン名を取得してWP_SITEURL(HOME) を動的に定義する

define('WP_SITEURL','http://'. $_SERVER['HTTP_HOST']);
define('WP_HOME','http://'. $_SERVER['HTTP_HOST']);

マスターEC2のNFS設定

nfs-utilsパッケージはインストールされているものとして進めます。

NFSのエクスポート設定をします。 どのディレクトリをクローンからアクセスできるかの設定をします。

※ 下記は本体とクローンEC2は共に同一VPC内におり、またそのときに限りすべてのトラフィック許可する設定、が前提です。

# vi /etc/exports
/var/www/html  *(rw,no_root_squash)

NFSデーモンを起動します。

systemctl start rpcbind && systemctl start nfs
systemctl enable rpcbind && systemctl enable nfs

以上で本体は完了です。

クローンEC2の作成

本体サーバーから調整を施してクローンEC2インスタンスを作成していきます。
まずは本体サーバーのAMIを作成して、それからインスタンスを起動します

f:id:moqrin3:20181130234636p:plain

f:id:moqrin3:20181130234640p:plain

NFSマウントするためのデーモンを開始。

systemctl start rpcbind && systemctl start nfslock

NFSサーバーのマウントポイントを定義します。
まずはディレクトリを作成します。

mkdir -p /mnt/nfs/wordpress-master/var/www/html

次にマウント設定を/etc/fstabに記述します。
XXXは本体サーバーのプライベートIPです

XX.XXX.XXXX:/var/www/html /mnt/nfs/wordpress-master/var/www/html nfs defaults 0 0

マウントします。

mount /mnt/nfs/wordpress-master/var/www/html

以上で、本体のディレクトリがクローンEC2のマウントポイントに共有されました。
後は、定期的にマウントポイントから1分ごとに同期します。

crontabで「rsyncコマンドを実行」を記述する。

crontab -e
*/1 * * * * rsync -avx /mnt/nfs/wordpress-master/var/www/html/ /var/www/html/ >> /var/log/rsync.log 2>&1

なお、crontabでなく、マウントポイントからlsyncdしようと考えたのですが、
NFSでマウントしたディレクトリからはlsyncdの対応はできなくて、上記設定に至りました(泣)。

ELB,AutoScalingGroupの設定

ELB,ASGの設定についても情報は多いため、詳細は割愛します。
要点としては、起動設定のAMI選択時に、先ほど作成したクローンEC2のAMIを選択することです。

f:id:moqrin3:20181130234853p:plain

まとめ

以上で、冒頭の1~3の課題に対応するシステム構築が容易にできました。
とはいえ、まだまだ考慮して改善した方が良さそうなことはパッと浮かべるだけでもいくつもあります。
俺たちの冒険はまだまだこれからだ。
ということで、引き続き精進致します。

・リアルタイム性を重視したため、S3の利用を見送ったが、今のままでは転送量が高額になりそうなこと。(CloudFrontの利用だけではそこまで転送量は変わらない。)
・AutoScalingに破棄されるインスタンスのログをS3などにアップロードする

参考


大澤文孝(2013)『Amazon Web Services クラウドデザインパターン実装ガイド』日経BP
CDP:NFS Replicaパターン
default.direct and nfs mounts
Exec-PHP using PHP Version 7.1 fails