CentOS 版からマーケットプレース版網元へのインスタンスの移行方法

網元 AMI は、当初提供されていた CentOS 版から、現在マーケットプレースで提供している Amazon Linux / RedHat Linux Enterprise 版への変更に伴い、細かい箇所で設定が変更されています。
CentOS 版と、最新の網元 AMI の違いは以下の通りです。

マーケットプレース版網元 AMI (Amazon Linux / RedHat Linux Enterprise) の特長

  • PHP 5.4, Nginx 1.4, Percona MySQL 5.5 のマイナーバージョンアップ
    (Amazon Linux 版の網元では、インスタンス作成時点で提供されている最新のバージョンがインストールされます)
  • プロセス監視ソフト monit の導入
    php-fpm, nginx, mysql のプロセスが終了したことを監視して、自動で再起動してくれます
  • t1.micro インスタンスの場合、スワップ領域を2GB確保
    これにより、メモリ不足で yum update が終了しなかった問題を解決できます
  • インスタンスタイプ別によるパラメータの最適化
    インスタンス作成時に選択されたインスタンスタイプのリソースにあわせて、Nginx、PHP、MySQL のパラメータが適切に設定されます

このようにメリットが大きいのですが、一度作成したインスタンスを変更して再度設定し直したり、サーバ上に溜まっているデータを移行するのが億劫だったりして、新バージョンに移行できていない人も多いでしょう。
そこで、ここでは新しくインスタンスを起動して、現行のサーバからデータを移行する手順を解説します。

前提条件として、すでにマーケットプレース版の網元 AMI から、まっさらなインスタンスが起動しているものとします。

スナップショットの作成

まず、現行インスタンスのボリュームからスナップショットを作成します。

AWS マネージメントコンソールにログインし EC2 Dashbord に移動します。
サイドメニューから Volumes を選択してください。
現行インスタンスが使用しているボリュームを選択して、[Actions] – [Create Snapshot] を選択します。
Create Snapshot

[Name] [Description] を適当に入力して [Yes Create] をクリックします。
Create Snapshot

サイドメニューから Snapshots を選択すると、スナップショットの作成状況がわかります。
完了になるまで、待ってください。

スナップショットからボリュームの作成

スナップショットの作成が終わったら、そこから新しいボリュームを作成しましょう。

サイドメニューから Snapshots を選択してください。
先ほど作成したスナップショットをチェックした後で [Create Volume] をクリックします。
Create Volume

[Volume Type] は Standard を選択します。
[Size] はデフォルトのままでかまいません。
[Availability Zone] の選択は慎重に行ってください。
新しく起動したインスタンスと同じ Availability Zone を選択しないと、この後の作業ができません。
新しく起動したインスタンスが、どの Availability Zone に存在するかわからないときは Instances で確認してください。
Create Volume

サイドメニューから Volumes を選択すると、ボリュームの作成状況がわかります。

作成したボリュームを新インスタンスにアタッチする

次に先ほど作成したボリュームを新インスタンスにアタッチして、新インスタンスからマウントできるようにします。

サイドメニューから Volumes を選択してください。
先ほど作成したボリュームを選択して、[Actions] – [Attach Volume] を選択します。
ボリュームを作成した Availability Zone が間違っていなければ [Instannces] のリストボックスに、新インスタンスが表示されているはずですので、そちらを選択してください。
[Device] には /dev/sda2 と入力して、[Yes Attach] をクリックします。
Attach Volume

続いて、新インスタンスに ssh 接続してください。
ここからは root 権限で作業するので su - で root になっておいてください。
su する際に必要な root のパスワードは sudo passwd で変更できます。

まずは、アタッチしたボリュームがちゃんと接続されているか確認します。
問題なければ /dev/xvda2 として認識されているはずですので、以下のコマンドで確認してください。

# ls /dev/xvda*
/dev/xvda1 /dev/xvda2

問題なければ /mnt/vol に mount します。

# mkdir /mnt/vol
# mount /dev/xvda2 /mnt/vol

これで、現行サーバのスナップショットから作成したボリュームに /mnt/vol からアクセスできるようになりました。

データを移行する

続いてデータを移行します。

まずは、移行時に MySQL や Nginx のプロセスが起動していると面倒なので、これらを停止します。
なお monit を先に停止しておかないと、monit により MySQL, Nginx のプロセスが再起動されてしまうので注意してください。

# service monit stop
# service php-fpm stop
# service nginx stop
# service mysql stop

MySQL のデータを移行するには、以下のコマンドを実行してください。

# mv /var/lib/mysql /var/lib/mysql.bak
# rsync -avz --delete /mnt/vol/var/lib/mysql/ /var/lib/mysql/
# chown -R mysql:mysql /var/lib/mysql
# rm /var/lib/mysql/ib_logfile*
# service mysql start

MySQL が無事起動し mysql -u root でログインできることが確認できたら /var/lib/mysql.bak は削除してしまっても問題ないです。

次に Nginx のデータを移行します。

# mv /var/www/vhosts /var/www/vhosts.bak
# rsync -avz --delete /mnt/vol/var/www/vhosts/ /var/www/vhosts/
# chown -R nginx:nginx /var/www/vhosts

続いて Nginx の設定ファイルとログを移行して、Nginx を起動します。

# mv /etc/nginx/conf.d /etc/nginx/conf.d.bak
# rsync -avz --delete /mnt/vol/etc/nginx/conf.d/ /etc/nginx/conf.d/
# rsync -avz --delete /mnt/vol/var/log/nginx/ /var/log/nginx/
# chown -R nginx:nginx /etc/nginx/conf.d/
# chown -R nginx:nginx /var/log/nginx/
# service nginx start

Nginx が無事起動したら /var/www/vhosts.bak, /etc/nginx/conf.d.bak は削除してしまっても問題ないです。

最後に停止していた php-fpm, monit のサービスを起動します。

# service php-fpm start
# service monit start

ここまででデータ移行は終了です。

新インスタンスにアタッチしていたボリュームをデタッチする

まず umount でマウントしていたボリュームをアンマウントしてください。

# umount /dev/xvda2

次に AWS マネージメントコンソールにログインし EC2 Dashbord に移動します。
サイドメニューから Volumes を選択して、先ほどアタッチしたボリュームを選択して [Actions] – [Force Dettach] を選択します。
このとき /dev/sda1 にアタッチされているボリュームをデタッチしてしまわないように注意してください。

データ移行は完了したので、すでにこのボリュームは不要です。
[Actions] – [Delete Volume] で削除しておきましょう。
Delete Volume

新インスタンスに EIP を付け替える

ここまでの作業が終わったら、現行インスタンスに設定されていた EIP を外して、新インスタンスに割り当てましょう。
EIP ではなく ELB を前段に置いている場合は、そちらの設定を変更してください。
一通り確認作業が終わったら、現行インスタンスはお役御免です。Stop してやってください。
しばらく運用していて問題ないようであれば Terminate しても良いでしょう。