最近お仕事でも AWS を使わざるを得ない状況になってきたので、ためしに AWS で WordPress を HA 構成にしてみました。
なお、RDS や S3 は使っていないのであまり AWS っぽくはありません(オンプレをできるだけそのまま AWS に移行する想定だったので)。
構成
次のような構成にします。
- APx2 DBx2 NASx2 で Multi-AZ
- すべて CentOS 6.5
- 東京リージョン
- AP は Apache/PHP
- 負荷分散に ELB を使用する
- DB は DRBD/Pacemaker/Heartbeat/MySQL
- MHA よりもこの構成の方がなれているから
- NAS は GlusterFS
- DRBD/Pacemaker/Heartbeat/NFS でもできるけど面倒なのと GlusterFS 使ってみたかった
- ドメインは既存のもののサブドメインを Route53 に委任
- 詳細は省略
IAM ユーザーを作成
aws cli を使うために IAM ユーザーを作成します。
本当は必要最小限のパーミッションにするべきなのでしょうが、お試しなので Power User Access で作成しました。
Access Key ID と Secret Access Key はあとで必要になるのでメモっておきます。
VPC を作成
VPC
次のように VPC を作成します。
Name tag wp-vpc CIDR block 10.1.0.0/16 Tenancy Default
Subnets
VPC に2つの AZ のサブネットを作成します。なぜか ap-northeast-1b だと作成できなかったので ap-northeast-1a と ap-northeast-1c で作りました。
Name tag wp-net-a VPC wp-vpc Availability Zone ap-northeast-1a CIDR block 10.1.1.0/24
Name tag wp-net-c VPC wp-vpc Availability Zone ap-northeast-1c CIDR block 10.1.2.0/24
Internet Gateways
Internet Gateway を追加します。
Name tag wp-gw
追加後に wp-vpc
にアタッチしておきます。
Route Tables
Route Tables で wp-vpc
のルーティングを追加します。
Destination 0.0.0.0/0 Target igw-xxxxx | wp-gw
Target には↑で作成した Internet Gateway を指定します。
Security Group
EC2 の Management Console を開いて wp-vpc
の Security Group を設定します。
VPC の Management Console でもできますが、そちらだと後述の MyIP が選択できなかったので。
VPC を新規作成したときにデフォルトの Security Group が作成されています。この Security Group は、同じ Security Group のインスタンス同士の通信をすべて許可するようになっています。
インスタンス間の通信はこの Security Group で通すことにして、これから作業するために SSH で繋げられる必要があるので次のように inbound Rules を追加します。
Type SSH(22) Source My IP
Type All ICMP Source My IP
Source に My IP を選択すると、今現在 Management Console に接続しているグローバルIPアドレスが設定されます。
ついでに Name tag も wp-default
などとわかりやすく変更しておきます。
さらに、最終的に ELB を HTTP で公開する必要があるので、次のように Security Group を新規作成します。
Security group name public Description public VPC wp-vpc inbound Rules Type HTTP Source Anywhere
Name tag も wp-public
などとわかりやすく変更しておきます。
ベースとなるインスタンスの作成
この後、インスタンスを合計6台起動して HA 構成にするのですが、いきなり6台起動して最初から構築するのは面倒なので、ベースとなる AMI を作成します。
EC2 の Management Console の Instances から Lunch Instance をクリックして、次のような Instance を1台だけ作成します。
Step 1: Choose an Amazon Machine Image (AMI)
AWS Marketplace を CentOS で検索して CentOS 6.5 の AMI を選択します。
Step 2: Choose an Instance Type
t1.micro を選択します。
本当は t2.micro が良いのですが、仮想化の種類が paravirtual なので t2.micro は選択できません。
Step 3: Configure Instance Details
下記のみ変更して、その他はデフォルトのままにします。
Network wp-vpc Auto-assign Public IP Enable
Step 4: Add Storage
Volume Type を General Purpose (SSD) に変更します。
Step 5: Tag Instance
Name に wp-base
などと判りやすい名前を付けます。
Step 6: Configure Security Group
Select an existing security group を選択して default と public を選択します。
Step 7: Review Instance Launch
ざっくり内容を確認して、Launch をクリックします。
しばらく待つと Instance が起動するので SSH でログインします。
ベースに必要なソフトウェアをインストール
作成したベースとなるインスタンスにいろいろインストールします。
SELinux と iptables
/etc/selinux/config を編集して SELinux を無効にします。
sed -i '/^SELINUX=/c SELINUX=disabled' /etc/selinux/config cat /etc/selinux/config
iptables を無効にします。
service iptables stop service ip6tables stop chkconfig iptables off chkconfig ip6tables off
再起動します。
reboot
yum
再起動が終わったら yum で update と base とかの基本的なものをインストールします。
yum update yum groupinstall base yum install bash-completion nc git
mysql と apache と php をインストールします。
yum install mysql-server httpd php php-pecl-zendopcache php-mysql chkconfig mysqld off chkconfig httpd off
サードパーティのリポジトリを追加して drbd と heartbeat と pacemaker をインストールします。
yum localinstall http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm yum localinstall http://www.elrepo.org/elrepo-release-6-6.el6.elrepo.noarch.rpm cd /usr/local/src wget "http://sourceforge.jp/frs/redir.php?m=iij&f=%2Flinux-ha%2F60151%2Fpacemaker-1.0.13-1.2.el6.x86_64.repo.tar.gz" \ -O pacemaker-1.0.13-1.2.el6.x86_64.repo.tar.gz tar xvzf pacemaker-1.0.13-1.2.el6.x86_64.repo.tar.gz mv pacemaker-1.0.13-1.2.el6.x86_64.repo /tmp cd /tmp/pacemaker-1.0.13-1.2.el6.x86_64.repo sed -i '/name=/a exclude=pacemaker pacemaker* clusterlib' \ /etc/yum.repos.d/CentOS-Base.repo yum install -c pacemaker.repo heartbeat pacemaker yum install kmod-drbd83 drbd83-utils chkconfig heartbeat off chkconfig drbd off
glusterfs をインストールします。
wget http://download.gluster.org/pub/gluster/glusterfs/LATEST/EPEL.repo/glusterfs-epel.repo \ -O /etc/yum.repos.d/glusterfs-epel.repo yum install glusterfs-server glusterfs-fuse chkconfig glusterd off chkconfig glusterfsd off
AWS Access Key ID と AWS Secret Access Key には↑の方で作成した IAM ユーザーのものを指定してください。
Default region name は東京リージョンである ap-northeast-1 を指定します。
Default output format はなんでもいいです。
yum install python-pip pip install awscli aws configure
ベースの各種設定
後の作業が楽になるように、ベースイメージに各種設定ファイルをあらかじめ作成しておきます。
hosts
/etc/hosts を編集します。
cat <<EOS> /etc/hosts 127.0.0.1 localhost.localdomain localhost ::1 localhost6.localdomain6 localhost6 10.1.1.11 db01.aws.example.net db01 10.1.2.11 db02.aws.example.net db02 10.1.1.22 ns01.aws.example.net ns01 10.1.2.22 ns02.aws.example.net ns02 EOS cat /etc/hosts
AP は固定の IP アドレスが必要ないので記述していません。
drbd
/etc/drbd.d/global_common.conf を編集します。
cp -a /etc/drbd.d/global_common.conf{,.orig} cat <<EOS> /etc/drbd.d/global_common.conf global { usage-count no; } common { protocol C; startup { wfc-timeout 60; } net { cram-hmac-alg sha1; shared-secret "drbd_no_himitu"; } syncer { rate 5M; } } EOS cat /etc/drbd.d/global_common.conf
/etc/drbd.d/r0.res を編集します。drbd のためのディスクはあとでアタッチするので、仮で /dev/xvdj
とします。
cat <<EOS> /etc/drbd.d/r0.res resource r0 { protocol C; device /dev/drbd0; meta-disk internal; on db01.aws.example.net { address 10.1.1.11:7791; disk /dev/xvdj; } on db02.aws.example.net { address 10.1.2.11:7791; disk /dev/xvdj; } } EOS cat /etc/drbd.d/r0.res
heartbeat
/etc/ha.d/ha.cf を編集します。AWS はブロードキャストやマルチキャストができないので ucast で設定します(そもそも Multi-AZ だと別セグメントなのでブロードキャストは届かないし)。
cat <<EOS> /etc/ha.d/ha.cf keepalive 5 deadtime 60 warntime 20 initdead 120 udpport 694 ucast eth0 10.1.1.11 ucast eth0 10.1.2.11 node db01.aws.example.net node db02.aws.example.net watchdog /dev/watchdog pacemaker on uuidfrom nodename debug 0 use_logd yes EOS cat /etc/ha.d/ha.cf
/etc/logd.cf を編集します。
cat <<EOS> /etc/logd.cf debugfile /var/log/ha-debug logfile /var/log/ha-log logfacility none EOS cat /etc/logd.cf
/etc/ha.d/authkeys を編集してパーミッションを変更します。
cat <<EOS> /etc/ha.d/authkeys auth 2 2 sha1 heartbeat_no_himitu EOS cat /etc/ha.d/authkeys chown root:root /etc/ha.d/authkeys chmod 600 /etc/ha.d/authkeys
/etc/logrotate.d/heartbeat を作成します。これはログローテートのためです。
cat <<EOS> /etc/logrotate.d/heartbeat /var/log/ha-debug { missingok daily rotate 10 ifempty } /var/log/ha-log { missingok daily rotate 10 ifempty } EOS cat /etc/logrotate.d/heartbeat
mysql
/etc/my.cnf を編集します。
ログや pid や socket のパスを変えているのは単なる好みですが、Pacemaker のリソース設定で必要なので、変更した値は覚えておきます。
その他のパラメータは適当です。
cat <<EOS> /etc/my.cnf [client] port = 3306 socket = /var/run/mysql/mysql.sock [mysqld_safe] log-error = /var/log/mysql/error.log pid-file = /var/run/mysql/mysqld.pid [mysqld] user = mysql port = 3306 log-error = /var/log/mysql/error.log pid-file = /var/run/mysql/mysqld.pid socket = /var/run/mysql/mysql.sock datadir = /var/lib/mysql general_log_file = /var/log/mysql/query.log slow_query_log_file = /var/log/mysql/slow.log log-warnings general_log slow_query_log query_cache_type = 0 symbolic-links = 0 skip-external-locking skip-name-resolve character-set-server = utf8 default-storage-engine = innodb key_buffer_size = 16M max_allowed_packet = 16M table_open_cache = 64 sort_buffer_size = 512K join_buffer_size = 512K thread_cache_size = 2 thread_concurrency = 2 net_buffer_length = 8K read_buffer_size = 256K read_rnd_buffer_size = 512K myisam_sort_buffer_size = 8M # innodb innodb_data_file_path = ibdata1:10M:autoextend innodb_buffer_pool_size = 128M innodb_additional_mem_pool_size = 8M innodb_log_buffer_size = 8M innodb_log_file_size = 16M innodb_file_per_table #innodb_file_format = Barracuda [mysqldump] quick max_allowed_packet = 16M [mysql] connect-timeout = 5 no-auto-rehash show-warnings [myisamchk] key_buffer_size = 20M sort_buffer_size = 20M read_buffer = 2M write_buffer = 2M [mysqlhotcopy] interactive-timeout EOS cat /etc/my.cnf
ログや pid や socket のためのディレクトリを準備します。
mv /var/run/mysqld /var/run/mysql mkdir /var/log/mysql chown -R mysql:mysql /var/log/mysql/ rm -f /var/log/mysqld.log
/etc/logrotate.d/mysql を作成します。これはログローテートのためです。
cat <<'EOS'> /etc/logrotate.d/mysql /var/log/mysql/*.log { missingok daily rotate 10 ifempty nocreate sharedscripts postrotate if test -x /usr/bin/mysqladmin && \ /usr/bin/mysqladmin ping &>/dev/null then /usr/bin/mysqladmin flush-logs fi endscript } EOS cat /etc/logrotate.d/mysql
/etc/cron.d/mysql を作成します。これは日次で Analyze するためですが、無くてもいいです。
cat <<EOS> /etc/cron.d/mysql 09 04 * * * root /usr/bin/mysqladmin ping 1>/dev/null 2>&1 && /usr/bin/mysqlcheck -a --all-databases 1> /dev/null EOS cat /etc/cron.d/mysql
apache
apache の welcome.conf を無効にします。削除すると yum update で復活することがあるので空にするのがオススメです。
echo -n "" > /etc/httpd/conf.d/welcome.conf
php
php の設定ファイルを作ります。
/etc/php.ini を直接編集せずに /etc/php.d/ に変更分を作成します。
cat <<EOS> /etc/php.d/_default_.ini expose_php = Off error_reporting = E_ALL display_errors = Off display_startup_errors = Off log_errors = On error_log = /var/log/php/php.log date.timezone = Asia/Tokyo post_max_size = 500M upload_max_filesize = 500M memory_limit = 1G EOS cat /etc/php.d/_default_.ini
ログディレクトリを準備します。
mkdir /var/log/php/ chmod 777 /var/log/php/ touch /var/log/php/php.log chmod 666 /var/log/php/php.log
ログローテートの設定を作成します。
cat <<EOS> /etc/logrotate.d/php /var/log/php/*.log { missingok daily rotate 10 ifempty create 0666 root root } EOS cat /etc/logrotate.d/php
wordpress
WordPress をダウンロードして /var/www/html に展開します。
cd /usr/local/src/ wget http://ja.wordpress.org/wordpress-3.9.2-ja.zip unzip wordpress-3.9.2-ja.zip rm -fr /var/www/html/ mv wordpress /var/www/html/
wp-config.php を作ります。
DB サーバとして指定している 192.168.0.10 は Routing-Based HA のためのものです。
cd /var/www/html mv wp-config-sample.php wp-config.php sed wp-config.php -e " /^define('DB_NAME'/c define('DB_NAME', 'wordpress'); /^define('DB_USER'/c define('DB_USER', 'wordpress'); /^define('DB_PASSWORD'/c define('DB_PASSWORD', 'wordpress'); /^define('DB_HOST'/c define('DB_HOST', '192.168.0.10'); " -i curl https://api.wordpress.org/secret-key/1.1/salt/ > /tmp/secret sed wp-config.php -e " /^define('AUTH_KEY'/r /tmp/secret /^define('AUTH_KEY'/d /^define('SECURE_AUTH_KEY'/d /^define('LOGGED_IN_KEY'/d /^define('NONCE_KEY'/d /^define('AUTH_SALT'/d /^define('SECURE_AUTH_SALT'/d /^define('LOGGED_IN_SALT'/d /^define('NONCE_SALT'/d " -i cat wp-config.php
ec2-route lsb
後で Pacemakedr で Routing-Based HA をするので、そのための lsb のスクリプトを作成します。
まずは Management Console の VPC の画面で Route Table の ID を調べます。
もしくはインスタンス内で次のように調べることもできます。
mac=$(curl -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/ | head -1) vpc=$(curl -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/$mac/vpc-id) route_table_id=$(aws ec2 describe-route-tables --output text --query "RouteTables[?VpcId==\`$vpc\`].[RouteTableId][]") echo $route_table_id
Route Table を変更するための lsb を作成します。rtb-xxxxxxxx
の部分は↑で調べた ID に読み替えてください。
cat <<'EOS'> /etc/rc.d/init.d/ec2-route #!/bin/sh # # chkconfig: 12345 01 99 # description: EC2 route change . /etc/rc.d/init.d/functions route_table_id=rtb-xxxxxxxx destination_cidr_block=192.168.0.10/32 instance_id=$(curl -s http://169.254.169.254/latest/meta-data/instance-id) function start () { if status > /dev/null; then echo -n "already create" else echo -n "create route ..." aws ec2 delete-route --output text \ --route-table-id $route_table_id \ --destination-cidr-block $destination_cidr_block \ 2>&1 | logger -t ec2-route-delete aws ec2 create-route --output text \ --route-table-id $route_table_id \ --instance-id $instance_id \ --destination-cidr-block $destination_cidr_block \ 2>&1 | logger -t ec2-route-create fi success; echo return 0 } function stop() { if ! status > /dev/null; then echo -n "already delete" else echo -n "delete route ..." aws ec2 delete-route --output text \ --route-table-id $route_table_id \ --destination-cidr-block $destination_cidr_block \ 2>&1 | logger -t ec2-route-delete fi success; echo return 0 } function status() { cnt=$(aws ec2 describe-route-tables --output text \ --filters Name=route.instance-id,Values=$instance_id | wc -l) if [ "$cnt" -gt 0 ]; then echo "ok" return 0 else echo "ng" return 3 fi } case "$1" in start) start exit $? ;; status) status exit $? ;; stop) stop exit $? ;; *) echo "Usage: ec2-route {start|stop|status}" exit 2 esac EOS
バーミッションを変更して chkconfig --add
します。
chmod +x /etc/rc.d/init.d/ec2-route chkconfig --add ec2-route chkconfig ec2-route off chkconfig --list | grep ec2-route
なお、このスクリプトだと結構な頻度で aws cli を実行するし、失敗時の例外処理も無いので、よろしくありません。実運用で使うためには修正が必要です。
ベースの AMI 化
ここまでできたらベースとなるインスタンスを AMI にします。
Marketprice の CentOS 6.5 は起動時に /root/firstrun があれば root のパスワードが自動設定されるので作成します。
touch /root/firstrun
SSH の公開鍵認証の設定も、未作成なら自動的に作成設定されるので削除します。
rm -f /root/.ssh/authorized_keys
MAC アドレスが変わってもインタフェース名が変わらないように 70-persistent-net.rules を削除します。
rm -f /etc/udev/rules.d/70-persistent-net.rules
SSH のホスト鍵が全部同じになるのは好ましくないので削除します。
rm -f /etc/ssh/ssh_host_dsa_key rm -f /etc/ssh/ssh_host_dsa_key.pub rm -f /etc/ssh/ssh_host_key rm -f /etc/ssh/ssh_host_key.pub rm -f /etc/ssh/ssh_host_rsa_key rm -f /etc/ssh/ssh_host_rsa_key.pub
ログはいらないので削除します。
find /var/log -type f | xargs rm -fv
最後に root の .bash_history も削除してシャットダウンします。
rm -f /root/.bash_history shutdown -h now
シャットダウンが終わったら(Instance State が stopped になったら)、インスタンスから AMI を作成します。
名前はわかりやすく wp-base-20140809
などとしておきます。
AMI の作成が終わったら、元になったインスタンスは削除して構いません。
AMI からインスタンスを作成
↑で作成した AMI から AZ ap-northeast-1a と ap-northeast-1c でそれぞれ3台ずつ、合計6台起動します。
- VPC は作成済の
wp-vpc
を指定 - サブネットは各 AZ に作成済の
wp-net-a
とwp-net-c
を指定 - Auto-assign Public IP を Enable にする
- セキュリティグループは Select an existing security group を選択して default を指定
- ストレージや NIC はデフォルトのまま
作成後にインスタンスの名前をわかりやすくするための次のように変更します。
- ap-northeast-1a
- wp-ap01
- wp-db01
- wp-ns01
- ap-northeast-1c
- wp-ap02
- wp-db02
- wp-ns02
セカンダリ IP アドレスをインスタンスに指定
Management Console で DB と NAS にそれぞれセカンダリ IP アドレスを設定します。
- db01 10.1.1.11
- ns01 10.1.1.22
- db02 10.1.2.11
- ns02 10.1.2.22
DB サーバの Source/Dest チェックを無効 にする
Management Console で DB サーバのインスタンスの Source/Dest チェックを無効にします。
これは Routing-Based HA のために必要な設定です。
DB と NAS のボリュームを作成してアタッチ
Management Console で DB と NAS 用にボリュームを作成してアタッチします。AZ の異なるボリュームはアタッチできないので ap-northeast-1a と ap-northeast-1c でそれぞれ2つずつ作成します。
作成できたら DB と NAS のインスタンスに1つずつアタッチします。
NAS に関しては ルートボリュームをそのまま使っても良いのですが・・・なんとなくです。
インスタンスの IP アドレスとホスト名を設定
DB と NAS にログインしてセカンダリ IP アドレスを設定します。
次のようにメタデータから設定すると楽です。
cat <<EOS> /etc/sysconfig/network-scripts/ifcfg-eth0:0 DEVICE=eth0:0 BOOTPROTO=none ONBOOT=yes IPADDR=$(curl -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/$( curl -s http://169.254.169.254/latest/meta-data/mac/ )/local-ipv4s | tail -1) PREFIX=24 EOS cat /etc/sysconfig/network-scripts/ifcfg-eth0:0 ifup eth0:0
ホスト名を設定します。
hostname $(hostname -A) hostname sed -i "/^HOSTNAME=/c HOSTNAME=$(hostname)" /etc/sysconfig/network cat /etc/sysconfig/network
ホスト名を変更したあとは再起動するのがマイルールです。
reboot
再起動後に IP アドレスとホスト名が意図通りになっているか確認しておきます。
hostname ip addr
drbd
DB サーバで drbd のセットアップをします。
まずはアタッチされた EBS のデバイス名を調べます。
fdisk -l
/etc/drbd.d/r0.res のデバイス名を修正します。デバイス名が /dev/xvdj なら修正の必要はありません。
vi /etc/drbd.d/r0.res
メタデータを作成して drbd を開始します。
drbdadm create-md r0 service drbd start service drbd status
db01 を Primary として同期します(db01 のみ)。
drbdadm -- --overwrite-data-of-peer primary r0 watch -n 1 service drbd status
同期が終わったらフォーマットしてファイルシステムを作ります(db01 のみ)。
mkfs.ext4 /dev/drbd/by-res/r0 tune2fs -c 0 /dev/drbd/by-res/r0
マウントして MySQL のデータディレクトリを初期化します(db01 のみ)。
mkdir -p /drbd/r0 mount -t ext4 /dev/drbd/by-res/r0 /drbd/r0 mkdir /drbd/r0/mysql chown mysql:mysql /drbd/r0/mysql rm -fr /var/lib/mysql ln -s /drbd/r0/mysql /var/lib/mysql service mysqld start mysql -e 'select 1' service mysqld stop
db02 にもマウントポイントと mysql のデータディレクトリのシンボリックリンクを作成します(db02 のみ)。
mkdir -p /drbd/r0 rm -fr /var/lib/mysql ln -s /drbd/r0/mysql /var/lib/mysql
動作確認のために db01 を Secondary に戻します(db01 のみ)。
umount /drbd/r0 drbdadm secondary r0 service drbd status
動作確認のために db02 を Primary にして MySQL を起動します(db02 のみ)。
drbdadm primary r0 service drbd status mount -t ext4 /dev/drbd/by-res/r0 /drbd/r0 service mysqld start mysql -e 'select 1' service mysqld stop
動作確認が終わったら db02 も Secondary に戻します。
umount /drbd/r0 drbdadm secondary r0 service drbd status
drbd を停止しておきます(db01 と db02 の両方)。
service drbd stop service drbd status lsmod | grep drbd
pacemaker
次に DB サーバで pacemaker/heartbeat の設定をします。
logd は常時起動していても問題ないので常時起動にします。
chkconfig logd on service logd start service logd status tail /var/log/messages
heartbeat を起動します。
rm -fr /var/lib/heartbeat/crm/* service heartbeat start service heartbeat status ps auxw | grep heartbeat watch crm_mon -1
crm_mon
でお互いを認識していることを確認できたら、どちらが DC になっているかを確認します。
これから crm を用いた pacemaker の設定を行いますが、この作業は DC で行います。
まずは基本設定。
crm configure property stonith-enabled="false" property start-failure-is-fatal="false" rsc_defaults migration-threshold="5" rsc_defaults resource-stickiness="INFINITY" rsc_defaults failure-timeout="3600s" verify commit quit
続いてリソース設定。
crm configure primitive drbd \ ocf:linbit:drbd \ params drbd_resource="r0" drbdconf="/etc/drbd.conf" \ op start timeout="240s" on-fail="restart" \ op stop timeout="100s" on-fail="block" \ op monitor interval="20s" role="Slave" timeout="20s" start-delay="1m" on-fail="restart" \ op monitor interval="10s" role="Master" timeout="20s" start-delay="1m" on-fail="restart" ms ms_drbd \ drbd \ meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" primitive vip ocf:heartbeat:IPaddr2 \ params ip="192.168.0.10" cidr_netmask="32" nic="lo" primitive fs \ ocf:heartbeat:Filesystem \ params device="/dev/drbd/by-res/r0" directory="/drbd/r0" fstype="ext4" \ op start interval="0s" timeout="60s" on-fail="restart" \ op monitor interval="10s" timeout="60s" on-fail="restart" \ op stop interval="0s" timeout="60s" on-fail="block" primitive mysql \ ocf:heartbeat:mysql \ params binary="/usr/bin/mysqld_safe" \ log="/var/log/mysql/error.log" \ pid=/var/run/mysql/mysqld.pid \ socket=/var/run/mysql/mysql.sock \ op monitor interval="10s" timeout="30s" on-fail="restart" start-delay="30" OCF_CHECK_LEVEL="20" \ op start interval="0s" timeout="120s" on-fail="restart" \ op stop interval="0s" timeout="120s" on-fail="block" primitive route lsb:ec2-route \ op start interval="0s" timeout="60s" on-fail="restart" \ op monitor interval="60s" timeout="60s" on-fail="restart" \ op stop interval="0s" timeout="60s" on-fail="block" group group_db \ fs mysql vip route colocation colocation_db_drbd \ inf: group_db ms_drbd:Master order order_drbd_db \ inf: ms_drbd:promote group_db:start verify commit quit
設定内容が正しいことを確認し、mysql が起動するのを待ちます。
crm configure show watch crm_mon -1n
mysql
crm_mon
で db01 と db02 のどちらで mysql が起動しているか調べて、起動している方で mysql に接続します。
crm_mon -1n mysql mysql
いらない権限を削除して wordpress 用のデータベースを作成します。
delete from user; delete from host; delete from db; grant all on *.* TO root@localhost with grant option; grant all on *.* TO root@127.0.0.1 with grant option; flush privileges; create database wordpress; create user wordpress@'%'; set password for wordpress@'%' = password('wordpress'); grant all on wordpress.* to wordpress@'%';
mysql が起動していない方のインスタンスから接続できることを確認します。
mysql -h 192.168.0.10 -u wordpress -p wordpress
glusterfs
NAS サーバで glusterfs の設定を行います。
まずは ns01 と ns02 にアタッチされたディスクのデバイス名を調べます。
fdisk -l
パーティションを切ります。
fdisk /dev/xvdj n p 1 w
フォーマットします。
mkfs.ext4 /dev/xvdj1 e2label /dev/xvdj1 glfs
/etc/fstab に追記します。
cat <<EOS>> /etc/fstab LABEL=glfs /glfs/vols ext4 defaults 0 0 EOS cat /etc/fstab
マウントします。
mkdir -p /glfs/vols mount -a df
ns01 と ns02 間の通信はセカンダリ IP アドレスで指定した固定アドレスがソースアドレスになる必要があるようなので、ルーティングを変更します。
ip route add 10.1.0.0/16 \ via $(ip -4 -o route get 8.8.8.8 | grep -Eo 'via [.0-9]+' | cut -d' ' -f2) \ src $(ip -4 -o addr show secondary | grep -Eo 'inet [.0-9]+' | cut -d' ' -f2) \ dev eth0 ip route list
glusterfs を開始します。
service glusterd start
ns01 を作業ノードとして ns02 を peer に登録します(ns01 のみ)
gluster peer probe ns02
ns01 と ns02 で互いに認識していることを確認します。
gluster peer status
次のように表示されます。
Number of Peers: 1 Hostname: ns02 Uuid: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx State: Peer in Cluster (Connected)
ns01 と ns02 でブリックを作成します。
mkdir /glfs/vols/data
ns01 でボリュームを作成・開始します(db01 のみ)。
gluster volume create data replica 2 transport tcp ns01:/glfs/vols/data ns02:/glfs/vols/data gluster volume start data
ns01 と ns02 でボリュームが作成されていることを確認します。
gluster volume info data
次のように表示されます。
Volume Name: data Type: Replicate Volume ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Status: Started Number of Bricks: 1 x 2 = 2 Transport-type: tcp Bricks: Brick1: ns01:/glfs/vols/data Brick2: ns02:/glfs/vols/data
ns01 と ns02 でマウントします。
mkdir -p /glfs/data mount -t glusterfs localhost:/data /glfs/data
AP で glusterfs をマウント
ap01 と ap02 で glusterfs をマウントします。
mkdir -p /glfs/data mount -t glusterfs ns01:/data /glfs/data
ap01 で wordpress の wp-content の中身をごっそり移動します(ap01 のみ)。
rsync -av /var/www/html/wp-content/ /glfs/data/wp-content/ chown -R apache:apache /glfs/data/wp-content/
ap01 と ap02 で wordpress の wp-content をシンボリックリンクにします。
rm -fr /var/www/html/wp-content/ ln -sf /glfs/data/wp-content /var/www/html/wp-content ll /var/www/html/wp-content/
ap01 と ap02 から mysql に接続できることを確認します。
mysql -h 192.168.0.10 -u wordpress -p wordpress -e "select 1"
Apache を起動します。
service httpd start chkconfig httpd on
ELB の作成
ELB を作成します。
1. Define Load Balancer
- Load Balancer name は
wp-lb
- Create LB Inside は
wp-vpc
を選択 - その他はデフォルト
2. Configure Health Check
- Ping Path は
/readme.html
に変更 - その他はデフォルト
3. Select Subnets
- ap-northeast-1a と ap-northeast-1c を追加
4. Assign Security Groups
- default と wp-public を選択
5. Add EC2 Instances
- なにも選択せずに次へ(あとで cli で追加する)
ELB に AP を追加
ap01 と ap02 にログインして awc cli で ELB に自分自身を追加します。
aws elb register-instances-with-load-balancer \ --load-balancer-name wp-lb \ --instances "$(curl -s http://169.254.169.254/latest/meta-data/instance-id)"
ELB の DNS 名を登録
Route53 で ALIAS レコードで ELB を登録します。
ブラウザで閲覧
↑で登録したDNS名でブラウザで閲覧して、wordpress のインストール画面が表示されたら成功です。
・・・この時点で全世界にインストール画面が公開されているのでよくありませんね・・・
インストール画面で必要な項目を入力し、適当な投稿を POST できることを確認します。
フェイルオーバー
wordpress で適当に何件か投稿したあと、EC2 の Management Console で mysql が起動している側の AZ のインスタンスを皆殺しにします。
しばらくは閲覧できなくなりますが、フェイルオーバーが完了すれば wordpress が再び閲覧できるようになります。
さいごに
そのまま放置しておくと凄い勢いでチャリンチャリンと課金されていくので、いらないものは削除しておきましょう。
特にインスタンスと ELB がお高いです、EBS はそこそこです、AMI とスナップショットはお安いので記念に残しておいても良いでしょう。