LoginSignup
55
60

More than 3 years have passed since last update.

AWSにおけるWeb系の鉄板構成をWordPressを題材にして理解しよう

Last updated at Posted at 2016-09-24

概要

現在、EC2シングルインスタンスでWordPresをホストしていると仮定します。
スクリーンショット 2016-05-23 19.31.26.png
これを可用性が高く、かつ運用フリーな構成に移行する方法を学びます。
WorPressはDBサーバ(MySQL)が必須ですので、ここで学ぶことはいわゆる一般的なLAMP(あるいは類似の)構成のWeb系アプリサーバに応用することができます。

前提条件

  • 本手順は、AMIMOTO AMI(Apache)の環境が前提となっていますので、他の環境では期待通りの動作をしない可能性があります
    AMIMOTO AMIでWordPressを立ち上げる
  • レコードを変更可能なドメインをもっている方が望ましいですが、もっていない場合の手順も記載しています
  • 本手順は、AWS Consoleの英語画面で説明しています。なぜなら、手順中のリンク先にAWS公式日本語ドキュメントが含まれていますが、英語画面で説明が記述されているためです。また、ネット上のナレッジなども英語画面で説明されていることが多く、AWS上級者に質問する際も日本語画面の用語では通じないことが多いです。AWS Consoleはデフォルトで日本語画面になりますので、画面左下の言語選択を[English]に変更して下さい
    AWS マネジメントコンソール 2016-09-22 15-49-56.png

シングルインスタンス構成の課題

現在はEC2シングルインスタンスであるため、下記のような課題を抱えています。
[課題1] バックアップの運用が大変(定期実行・実行確認・リストアの訓練など)
[課題2] サーバ障害が発生した場合、復旧までに時間がかかるし、夜間でも対応が必要な場合がある
[課題3] メンテナンス(OSのセキュリティパッチ適用など)時にサービス停止が発生する
[課題4] メンテナンスが原因で不具合が発生した場合に、ロールバックが容易ではない
[課題5] 性能不足となった場合、スケールアップだけでは限界がある

これらの課題をAWSのサービスを活用して解決してしまいましょう!

課題に対するソリューション

AWSアーキテクチャ図

EC2-RDSアーキ図 - PowerPoint 2016-05-30 17.41.26.png

各課題に対するソリューション

[課題1] バックアップの運用が大変(定期実行・実行確認・リストアの訓練など)
・EC2内のMySQLをRDSに切り出すことで、DBのバックアップをRDSにオフロードできる
 -RDSのバックアップ(過去7日分)+トランザクションログ(直近5分前まで)はRDSが自動的にS3に保存
 -RDSのリストアはマウスオペレーションで日時指定するだけと非常に簡単
・メディアファイル(画像等)をS3に保存することでバックアップ不要となる(S3上のデータは3箇所に複製され、さらにバージョニングも可能なため)
・EC2のバックアップはメンテナンス時(コード変更・パッチ適用)のみでOK
[課題2] サーバ障害が発生した場合、復旧までに時間がかかるし、夜間でも対応が必要な場合がある
・ELB(ロードバランサー)で冗長化しているため、片方のインスタンスに障害が発生してもサービスを継続
 -夜間に障害が発生しても対応は翌日でOK
・RDSをMulti AZ構成にしている場合は、RDSに障害が発生すると自動的にスレーブにフェイルオーバー
[課題3] メンテナンス(OSのセキュリティパッチ適用など)時にサービス停止が発生する
・EC2インスタンスを1台ずつELBから切り離してメンテナンスを行うことでサービス無停止を実現
[課題4] メンテナンスが原因で不具合が発生した場合に、ロールバックが容易ではない
・メンテナンス前にEC2のAMIを取得することで容易にロールバックが可能
 -ロールバックした場合でもWordPressの記事データはRDSに、メディアファイルはS3に格納されているため先祖返りは起こらない
[課題5] 性能不足となった場合、スケールアップだけでは限界がある
・スケールアウト(EC2インスタンスを増やす)でリニアに処理能力を増強可能。ピークが過ぎたら元の構成に戻すことも簡単
 -オートスケールも利用可能
・RDSはスケールアップで対応する

料金

各サービスの料金

無料利用枠

AWS Simple Monthly Calculator

各サービスを組み合わせた時の月額料金を試算できます
https://calculator.s3.amazonaws.com/index.html?lng=ja_JP#

移行手順

※ コマンド等に含まれる「xxxxxx」は各ユーザー固有の値ですので、書き換えて入力して下さい
※ ハンズオン中にRDSのフェールオーバーテストは行わないため、今回はMulti-AZではなくシングル構成としますが、あとでMulti-AZに変更することもできます(ただし料金は2倍)

[0]WordPressを立ち上げる

次のコンテンツを参考にしてAWS上にWordPressサーバを立ち上げてください。
AMIMOTO AMIでWordPressを立ち上げる
立ち上げが完了したら、記事を投稿してください。写真入りの記事が望ましいです。スマホからも投稿できます。

[1]MySQLをRDSに切り出す

EC2-RDSアーキ図 - PowerPoint 2016-05-30 17.59.12.png

[1-1]現行のMySQLの設定を調べる

  • WordPressインスタンスにSSH接続する
    i-xxxxxxxxは、AMIMOTO AMIインストール時に指定したインスタンスID。i-まで入力してTabキーで補完してもよい
$ cd /var/www/vhosts/i-xxxxxxxx
$ cat local-config.php

緑線の囲みの部分がEC2内のMySQLへのアクセス情報。後で使うので控えておく
ICHIRO — ec2-user@ip-172-31-9-192:var:www:vhosts:i-88b02917 — ssh wp-test — 90×40 2016-05-25 19-39-43.png

[1-2]Security Groupの設定を行う

Security Groupを作成する

  • AWS ConsoleでEC2を開く
  • 左ペインの[Instances]をクリックして、立ち上げ済みのWordPressインスタンスが存在することを確かめる
    (存在しなければリージョンが間違っている可能性がある)
  • 左ペインの[Security Groups]をクリックする
  • [Create Security Group]をクリックする
  • Security group nameとDescriptionに[My-default-sg]を入力する
  • [Create]をクリックする スクリーンショット 2020-05-27 11.25.00.png

  • [Edit Inbound rules]をクリックする スクリーンショット 2020-05-27 11.25.37.png

  • [Add Rule]をクリックする
  • Type = [All traffic]を選択する
  • Souceに[my]と入力すると[My-default-sg]が表示されるので選択する
  • [Save rules]をクリックする スクリーンショット 2020-05-29 10.45.24.png
=本設定の意味=
今回作成した「My-default-sg」がアタッチされている各種インスタンス(EC2、ELB、RDSなど)どうしは、無制限に通信が可能となります。
外部からの通信は別のSecurity groupで制御することでファイアウォールのルールがシンプルに記述できます。

WordPressインスタンスに作成したセキュリティグループを当てる

  • 左ペインの[Instances]をクリックする
  • WordPressインスタンスを選択し右クリックする
  • [Networking] -> [Change Security Groups]の順に選択する スクリーンショット 2016-05-20 11.29.16.png

  • [My-default-sg]にチェックを入れて[Asign Security Groups]をクリックする EC2 Management Console 2016-05-21 12-37-38.png

[1-3]RDSを立ち上げる

  • AWS ConsoleでRDSを開く
  • 左ペインの[Databases]をクリックする
  • [Create database]をクリックする
  • [Standard Create]が選択されていることを確認する
  • [MySQL]を選択し[Select]をクリックする
  • [Free tier]をクリックする
  • 下表の通り入力する
項目名 選択/入力内容
DB Instance Identifier (任意のインスタンス名)
Master Username (先ほど調べたMySQLの'username')
Master/Confirm Password (先ほど調べたMySQLの'password'を2回入力)
Initial database name (先ほど調べたMySQLの'database')
  • [create database]をクリックする screencapture-ap-northeast-1-console-aws-amazon-rd1.png

  • 作成したインスタンスが[Avallable]に変わった(数分かかる)ことを確認して、インスタンスを選択して[Modify]をクリックするスクリーンショット 2020-05-28 10.50.51.png

  • Network & Securityセクションで下図の通り[Security group]の検索窓に[my]と入力し、[My-default-sg]を選択する
  • 画面最下部の[Continue]をクリックする Continue.png

  • [My-default-sg]が追加されていることを確認し[Modfy DB Instance]をクリックするスクリーンショット 2020-05-28 10.59.32.png

  • インスタンス名をクリックする
    スクリーンショット 2020-05-28 13.38.48.png

  • あとで使うのでEndpointを控えておく
    スクリーンショット 2020-05-28 13.39.19.png

[1-4]EC2内のMySQLをRDSに移行する

今回は移行元(EC2)からWP-CLIでdumpを書き出し、移行先(RDS)にはMySQL Clientでdumpを書き込みます。

  • WordPressインスタンスにSSH接続する
  • WP-CLIでMySQLのdumpを書き出す
$ cd /var/www/vhosts/i-xxxxxxxx
$ wp db export
  • i_xxxxxxxx.sqlが作成されていることを確認する
$ ll

スクリーンショット 2020-05-28 14.39.26.png

  • MySQLの設定中の'host'の値をRDSのエンドポイントに書き換える(:3306は不要)
$ sudo cp local-config.php local-config.php.org
$ sudo vim local-config.php
local-config.php
                'database' => 'i_xxxxxxxx',
                'username' => 'wp_db46xxxxxxxxx',
                'password' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxx',
                //'host'     => 'localhost',
                'host'     => 'wp-db.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com',
  • この時点でブログページにアクセスすると、RDSにデータを移行していないため、インストール画面が表示されてしまう(害はないので、アクセスして確かめよう)。表示される画面は下図と異なる場合がある

    スクリーンショット 2016-05-22 10.01.21.png


    ※ 設定が間違っていると下図のようなエラーが表示される
    スクリーンショット 2020-05-29 9.00.16.png


  • MySQL ClientでdumpをRDSに書き込む(エンドポイントの:3306は不要)

$ mysql -h {RDS_endpoint} -P 3306 -u {username} -p {databasename} < {dump_data}
Enter password: {password}

<実行例>
$ mysql -h wp-db.xxxxx.ap-northeast-1.rds.amazonaws.com -P 3306 -u wp_db46xxxxxxxxx -p i_xxxxxxxx < i_xxxxxxxx.sql 
  • ブログページにアクセスして元と同じように表示されることを確かめる

[2]uploadsディレクトリのメディアファイルの保存先をS3に変更する

【注意】2020年5月現在、絡新婦プラグインは公開が終了しています

したがって、手軽に冗長構成下でメディアファイルを同期することはできなくなりました。本ハンズオンにおいては、画像や動画を含まない投稿に限定することで鉄板構成を学んでいただくことができます。

EC2-RDSアーキ図 - PowerPoint 2016-05-30 18.02.18.png
記事の投稿時にアップロードしたメディアファイル(画像等)は、WordPressサーバのuploadsディレクトリに保存され、MySQLにはそのURLが書き込まれます。したがってWordPressサーバをスケールアウト構成とする場合、全てのサーバのuploadsディレクトリが同期されていないと、接続したサーバによってメディアファイルのリンク切れを起こしてしまうことになります。
通常はrsyncやlsyncd等を使って各サーバのuploadsディレクトリ間で双方向の同期をかけます。
今回はより簡易な方法として「絡新婦(じょろうぐも)プラグイン」を利用します。「絡新婦プラグイン」を使うと、uploadsディレクトリ内のファイルを自動的にS3に転送し、ソース内のURLも自動的にS3のエンドポイントに書き換えてくれます。Webページのメディアファイルは常にS3を参照しますので、サーバ間の同期を気にする必要がなくなります。
※ StaticPress S3プラグインとの同時利用はできません

[2-1]S3バケットを作成し、IAMキーを取得する

独自ドメインを使ってAmazon S3で静的Webサイトをホストするを参考にして、画像を保存するS3バケットの作成、Web公開、IAMキーの取得を行って下さい。

  • 上記手順ではバケット名とFQDNを一致させていますが、絡新婦に使うバケットにドメイン(FQDN)を割り当てる必要はないので、任意の分かりやすい名前をつけてOKです
  • StaticPress S3用のバケットと共用可能です

[2-2]「絡新婦(じょろうぐも)プラグイン」を有効にして設定する

  • WordPressダッシュボードを開く
  • [プラグイン] -> [Nephila clavata(絡新婦)] -> [有効化]
    ※ StaticPress S3プラグインが有効になっている場合は「停止」する プラグイン ‹ カレーは飲み物です — WordPress 2016-05-23 11-59-07.png

  • [設定]をクリックする
    プラグイン ‹ カレーは最強の飲み物 — WordPress 2016-07-22 16-35-19.png

  • S3バケットのIAMキーを入力し、AWSリージョンを選択する
  • Stogage Classは[STANDARD]を選択する
  • [変更を保存]をクリックする
    Nephila clavata ‹ カレーは飲み物ですが麻婆豆腐は食べ物です — WordPress 2016-09-24 17-54-08.png

  • S3バケットを選択し[変更を保存]をクリックすると、S3 URLが自動的に入力される Nephila clavata (絡新婦) ‹ カレーは飲み物です — WordPress 2016-05-23 13-37-37.png

  • ブログページにアクセスして画像の参照先(画像を右クリックして新しいタブで開けば分かる)がS3エンドポイントに変わっていることを確認する。S3エンドポイントに変わらない場合は、新規で画像を含む記事を投稿してから確かめてみる

[3]EC2をELBにぶら下げる

EC2-RDSアーキ図 - PowerPoint 2016-05-30 18.03.22.png

[3-1]EC2をELBにぶら下げる

  • AWS ConsoleでEC2を開く
  • 左ペインの[Load Balancers]をクリックする
  • [Create Load Balancer]をクリックする
  • [Classic Load Balancer]を選択し[Create]をクリックする
  • Load Balancer Nameに適当な名前を入力し[Next: Asign Security Groups]をクリックする EC2 Management Console 2016-05-20 16-43-21.png

  • WordPressインスタンスにあたっているのと同じもの(厳密にはSSHは不要)を選択し[Next: Asign Security Settings]をクリックする EC2 Management Console 2016-09-24 18-04-47.png

  • [Next: Configure Health Check]をクリックする EC2 Management Console 2016-05-20 17-03-03.png

  • Ping Pathを[/wp-content/index.php]に変更し[Next: Add EC2 Instances]をクリックする EC2 Management Console 2016-05-20 17-47-48.png

  • WordPressインスタンスを選択し[Next: Add Tags]をクリックする EC2 Management Console 2016-05-20 21-19-43.png

  • [Review and Create]をクリックする(タグの設定は任意)
  • [Create]をクリックする
  • [Close]をクリックする
  • 作成したELBを選択する
  • [Edit stickiness]をクリックする
  • [Enable Load Balancer Generated Cookie Stickiness]を選択しExpiration Period:にセッション維持の制限時間を秒単位で入力する(3600秒もあれば充分)
  • [Save]をクリックする EC2 Management Console 2016-09-24 18-10-14.png

  • [Instances]タブをクリックする
  • しばらく待ってStatusが[OutOfService]から[InService]に変わっていることを確認する EC2 Management Console 2016-05-20 21-27-01.png

[3-2]DNSをELBに向ける

elb.{独自ドメイン}のようなサブドメインを作成し、ELBを向くようにします。独自ドメインをもっていない場合は本項を飛ばしてください。

独自ドメインをRoute 53でホストしている場合

AレコードAliasを登録する
http://qiita.com/Ichiro_Tsuji/items/8471fe0b3d4d17cde146#aレコードaliasの登録

独自ドメインをRoute 53 以外のDNSでホストしている場合

DNSにCNAMEレコードを作成し、ELBのDNS name(下図黄緑の囲み)を登録する
EC2 Management Console 2016-05-23 13-58-36.png

[3-3]WordPressアドレスを変更する

  • 先ほどDNSに登録したhttp://elb.{独自ドメイン}(独自ドメインをもっていない場合は、ELBのDNS name)にアクセスして、トップページが表示されることを確認する(このままでは記事等のリンク先がELB経由とならない)
  • [設定]をクリックする
  • WordPress アドレス (URL)とサイトアドレス (URL)を、先ほどDNSに登録したELBのURL(独自ドメインをもっていない場合は、http://{ELBのDNS name})に変更する
    ※ ここの設定を誤るとWordPress管理画面にアクセスできなくなるので慎重に!!設定を誤って管理画面にアクセスできなくなった場合は次項参照
  • [変更を保存]をクリックする 一般設定 ‹ カレーは飲み物です — WordPress 2016-05-23 14-14-08.png

  • 変更後の「WordPress アドレス (URL)」でブログページと管理画面にアクセスできることを確かめる

もし、管理画面にアクセスできなくなったら・・・

本来であればDBのレコードを直接修正して復旧する必要がありますが、暫定的にwp-config.phpを修正することで管理画面にアクセスできるようになります。

  • WordPressサーバにSSHでアクセスし、下記コマンドを実行する
    http://elb.iot.kyotoは、ELBのURL
$ cd /var/www/vhosts/i-xxxxxxxx
$ sudo cp wp-config.php wp-config.php.org
$ sudo vim wp-config.php
wp-config.php
/*53行目あたり、//define('WP_DEBUG_DISPLAY', false);の後に追記する*/

define('WP_HOME','http://elb.iot.kyoto');
define('WP_SITEURL','http://elb.iot.kyoto');

【注意】2020年5月現在、[3-4][3-6]の手順によるAMIMOTO AMIインスタンスのクローニングができなくなっています。クローニング自体はWebサーバの冗長化において一般的に行われることですので、当該の記事は修正しません。下記にAMIMOTO AMIインスタンスを冗長化したい場合の手順を記します。

local-config.php
                'database' => 'i_xxxxxxxx',
                'username' => 'wp_db46xxxxxxxxx',
                'password' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxx',
                'host'     => 'wp-db.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com',
  • [3-5]→[3-7]の順に進める

[3-4]EC2のクローンを作成する ※AMIMOTO AMIでは実行できなくなりました

  • AWS ConsoleでEC2を開く
  • 左ペインの[Instances]をクリックする
  • WordPressインスタンスの上で右クリックし、[Image] -> [Create Image]の順に選択する
  • このとき併せてAvailabillity Zoneを確認しておく
    b6f1e359-c197-81f9-09a5-d2e711e453fd.png

  • 任意のImage nameを入力する
  • No Rebootにチェックを入れ[Create Image]をクリックする
    EC2 Management Console 2016-05-23 14-22-32.png

  • 左ペインの[AMIs]をクリックする
  • Statusがavailableに変わったら、作成されたイメージの上で右クリックして[Launch]を選択する
    スクリーンショット 2016-05-23 14.39.04.png

  • 下記以外は全てクローン元と同じ設定でインスタンスを作成する
    ・Availabillity Zoneを先ほど確認した値と違う方を選ぶ
    ・[Name]Tagに見分けられる名前をつける EC2 Management Console 2016-05-23 14-46-32.png

    EC2 Management Console 2016-05-23 14-53-11.png

[3-5]クローンインスタンスをELBにぶら下げる

  • 左ペインの[Load Balancers]をクリックする
  • Load Balancerを選択する
  • [Instances]タブを開く
  • [Edit Instances]をクリックする
  • 先ほど作成したインスタンスを選択する EC2 Management Console 2016-05-23 14-59-10.png

  • [Save]をクリックする
  • しばらく待ってからリロードして、追加したインスタンスのStatusが[InService]に変わっていることを確認する
    EC2 Management Console 2016-05-23 15-02-55.png

[3-6]クローンインスタンスの新しいコンテンツディレクトリにコンテンツをコピーする ※AMIMOTO AMIでは実行できなくなりました

クローン元と先とではEC2のインスタンスIDが変わるので、それにともなってコンテンツディレクトリ名が変わります(AMIMOTO独特の現象)。そこで、旧ディレクトリから新ディレクトリにコンテンツをコピーします。

  • クローンインスタンスのインスタンスIDとPublic DNSを確認する
    EC2 Management Console 2016-10-07 17-26-03.png

  • クローンインスタンスにSSH接続する
$ cd /var/www/vhosts
$ ll
  • ディレクトリが新旧2つあるのが分かる。コンテンツは旧ディレクトリにしか入っていない
    ※ まれにディレクトリが1つしかない場合がある(原因不明)。この場合、コンテンツコピー作業は不要
    ec2-user@ip-172-31-14-54:var:www:vhosts — ssh wp-2 — 90×30 2016-10-07 17-08-31.png

  • コンテンツをコピーする

$ sudo cp -r {旧ディレクトリ}/* {新ディレクトリ}
<実行例>
$ sudo cp -r i-faxxxxxx/* i-fexxxxxx/
  • WebブラウザでクローンインスタンスのPublic DNSにアクセスしてブログページが表示されることを確認する

[3-7]片肺状態にしてみる

片方のインスタンスを停止するなどして、わざと片肺状態にしてもブログページや管理画面へのアクセスに問題がないことを確かめる。とくに、メディアファイルはブラウザにキャッシュされるので、他のブラウザで開いてリンク切れしていないか確かめる

  • どちらか片方のWordPressサーバを停止する
    ※ Elastic IPの設定をしていない場合、次の起動時はグローバルIPが変わる
    スクリーンショット 2016-09-24 19.02.13.png

[3-8]メンテナンス時の注意

テーマの修正やプラグインの追加/アップデート、WordPress本体のアップデートなど、ソースコードの変更を伴うメンテナンスを行う場合は、インスタンス間でソースコードの不一致が起こらないよう下記手順でクローン作成を行うことをおすすめします。

  1. 片方のインスタンスをELBから切り離し、停止する
  2. 残ったインスタンスでメンテナンスを行う
  3. メンテナンス済みインスタンスのクローンを作成し、ELBにぶら下げる

[4]RDSをリストアしてみる(時間が余った人向け)

RDSは5分前までの任意の時刻を指定して簡単にリストアすることができます。おおまかな手順を記しますのでリストアにチャレンジしてみましょう。

RDSのリストアとは

現在稼働しているRDSインスタンスのバックアップおよびトランザクションログから5分前までの任意の時刻を指定してリストアします

  • リストアの際に新しいインスタンスが作成されます
  • 新しく作成されたインスタンスは、リストア元のインスタンスとは違うインスタンス名にする必要があります

大まかな手順

  • リストアが正しく行われたか確認するために新しい記事を投稿し、投稿時刻を控える
  • AWS ConsoleでRDSを開く
  • RDSのインスタンス名を変更する(例:wp-db -> wp-db-old)。変更した時点でブログページにはアクセスできなくなる
【RDSインスタンスの名前を変更する手順】
・名前を変更するRDSインスタンスを選択し、[Instance Actions] -> [Modify]
・[DB Instance Identifier] テキストボックスに新しい名前を入力する
・[Apply Immediately] チェックボックスをオンにし、[Continue] をクリックする
・[Modify DB Instance] をクリックして変更を完了する
  • RDSインスタンスを選択し、[Instance Actions] -> [Restore to Point in Time]
  • 記事を投稿した時刻より前の時刻を指定し、[DB Instance Identifier]で変更前のインスタンス名(例:wp-db)を指定する
  • リストアしたインスタンスがavailableになったら、ブログページにアクセスして記事投稿前の状態になっていることを確認する
  • リストア元のインスタンスを削除する

あとかたづけ

今回使用したAWSのサービスのうち、Route 53以外は通常の使い方であれば1年間の無料利用枠に収まります。
無料利用枠は下記で確認して下さい。
http://aws.amazon.com/jp/free/
AMIMOTO AMIは起動後14日を過ぎると自動的にソフトウェア料金の課金が始まります。
触りたおして気が済んだら、下記の手順であとかたづけをしましょう。

EC2インスタンスの削除方法

ELBの削除手順

RDSの削除手順

S3の削除方法

Route 53の削除方法

55
60
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
55
60