突然起動しなくなったWordPressサーバーをなんとか復旧した話
サイトを運営しているみなさん. バックアップは毎日とっているでしょうか?悪夢のようなサーバーインシデントは突然やってきます. 今回はGCP上に構築したWordPressサーバーが起動不能になった本当にあった怖い話しをしようと思います. 復旧方法やGoogle Cloud Platformを活用したお手軽バックアップ方法についても紹介していきます.
Contents
事件はメンテナンス中に発生

WordPressを運用しているLinuxサーバーのアップデートを行っていました. アップデートはベースとなるCentOS(Kusanagi)のパッケージアップデートが中心で中にはカーネルのアップデートも含まれていました.
通常Linux OSではカーネルのアップデートがある場合は再起動することによって新しいカーネルの適用を行ます。
ですから、TIPSTOCKのサーバーでも再起動をかけました。
しかし, 再起動してしばらく時間がたっても一向にサーバーにSSH接続ができません.

試しに, https://tipstock.net に接続してみると下のようなエラー521になりました. HTTPエラー521はTIPSTOCKが利用しているCloudfalre独自のエラー番号でサーバーがダウンしていることを示しています.

そこでGoogle Cloud Platfomの画面でVMがちゃんと起動しているかを確かめることにしました. 確認するとステータスは緑(起動した状態)になっており起動しているようです. SSHがつながらないのでシリアルコンソールで接続することにしました.

シリアルコンソールに接続すると、どうやらカーネルの読み込み&起動に失敗しているようです. 恐らくカーネルのアップデート時に生成するファイルができていなかったりブートローダーに設定するエントリの登録に失敗したなどの原因が想定できます。これでサーバー自体が起動不能になりました。

ダウンして初めて後悔….

このサーバーインシデントに遭遇して私は初めてある後悔をしました. それはバックアップを怠っていたことです.
このTIPSTOCKはWordPressを用いて運営をしていますが記事の内容は全てデーターベースに記録されており画像などのコンテンツはサーバー内のディレクトリにホストされています. これらのデータは万が一サーバーにトラブルがありデーター消失や起動不能などの自体に陥った場合に取り出せなくなる可能性があります.
このままでは、データーを復旧できずにTIPSTOCKを終了するしかなくなります.
復旧計画の作成

さてダウンしたままでは、本当にサイトを終了しなくてはいけません. ですから急いで復旧作業にかかることにしました.
そこで、いくつか復旧手法を考えました.
- 画像データ及, MySQLデータを抽出し新サーバーに適用する
- Google Web Cacheなどの内容を基に作り直す
- 既存VMのブートエントリを修正する方法
結論から述べると「既存VMのブートエントリを修正する方法」を選択したのですが、それに至った経緯を述べようと思います。
1. 画像データMySQLを抽出し新サーバーに適用する方法
まず、最初に画像データ及, MySQLデータを抽出し新サーバーに適用する方法について検討しました.
理由としてはKusanagiのベースはCentOSでありUbuntuを使ってきた私にとっては手慣れていないディストリビューションのため下手にコンフィグをいじるよりもクリーンな環境にデーターのみ引っ越した方が確実であると考えたからです。
この方法では画像などのファイルのコピーは簡単に行えましたが、MySQLのデーターベースのコピーは思うように行きませんでした.
WordPressで使われるMySQLは/var/lib/mysql配下にデーターファイルが作成されており、それを新しく立てたクリーンなVMインスタンスにコピーすることによって復旧できると考えたのですが様々なエラーを解決する必要があり時間的に適当でないと判断しました.
2.Web Cacheを基に作り直す方法
次に、Google Web Cacheなどの内容を基に作り直すことを検討しました.
実はサーバーが停止したり、サーバーからWebページのデーターが消失しても瞬時にインターネット上からコンテンツが消えることはまずありません. 例えば、あなたのWordPressサイトが適切にGoogleの検索エンジンにクローリングされているならばGoogleは定期的にあなたのWebサイトのキャッシュを作成しています. 事実、このTIPSTOCKもGoogle Web Cacheによってキャッシュされています. この内容を基に画像や文章を新しいWordPressサイトに貼り付けることで見かけ状のサーバーの引っ越しができます.
しかし、この方法は手作業により手間がかかるというポイントとSEO効果が悪い影響があるというポイントで採用しませんでした.
Web Cacheの文章は一個一個コピペするしかありません. 非常に手間がかかります.
それ以上に重要なのはパーマーリンク(記事のURL)変わることです. せっかく, Googleの検索順位をそこそこ獲得できた記事もURLが変わってしまったら, SEO的には最初からやり直しですし404エラーの数が増えてしまいます.
3.既存VMのブートエントリを修正する方法
最後に、今回採用した手法です. この手法はLinuxにある程度手慣れている必要があります. そうでない人が操作すると最悪データー消失や二度と復元できないようになってしまう可能性があるので注意して行ってください.
この手法は, 多くのLinuxディストリビューションでカーネルの上書きアップデートはあまり行われないという慣例を利用したものです. 具体的には, 新しいカーネルに不具合があった場合に既存の古いバージョンを残しておくことで起動しないなどの最悪の事態に対処できるようにしています.
以下に今回行った復旧方法に関した詳細に述べます.
サーバーの復旧作業
今回、選択した既存VMのブートエントリを修正する方法でサーバーの復旧を試みます.まず, Google Cloud PlatformのVMインスタンスの画面から該当VMインスタンスのスナップショットを作成します. これは万が一操作中にデーターを消失した場合のバックアップです.

次に、VMインスタンスのプロパティを編集します. ここではインスタンスを削除時にディスクの削除を行わないように設定をします. 通常VMインスタンスは一つのブートディスクを持っておりデフォルトではこのディスクはVMインスタンスが削除されると同時に削除されてしまします. Google Cloud PlatformのVMインスタンス画面でインスタンス名をクリックしてVMインスタンスの詳細に入ります.

ディスクの項目のインスタンスを削除したときの動作を, ディスクを維持に変更してください.

ディスクの設定が終わったら、該当VMのインスタンスを削除します. ただし、先ほどの設定が完了していることを確認してください. ディスクごと削除されると復旧ができなくなります.
VMインスタンスを削除したら、復旧用のVMインスタンスを作成します. 基本的にLinux OSであれば問題ないですが、ここでは念のためKusanagiのベースとなっているCentOSを選択しました.
VMを作成する時の注意点としては先ほどのディスクが存在するリージョンと同一のリージョンで作成しましょう.

また、VMのブートディスクの他に先ほど設定したディスクも外部ディスクとして追加します.

次に、作成したVMを起動します.
以下の順にコマンドラインの操作を行ます.
$ sudo su - # スーパーユーザーに変更
また、ここではコンフィグファイルを編集するのでお好みのエディタをインストールしましょう. 筆者はEmacsやVimなどのこだわりは特にないのでシンプルなnanoを選択しました.
$ yum install nano # エディタのインストール
次に、外部ディスクをマウントします.
# マウントポイントの作成
$ sudo mkdir /mnt/sdb
# マウントの実行
$ sudo mount /dev/sdb1 /mnt/sdb/ -t xfs
次にGRUBのブートエントリを変更します.
nano /mnt/sdb/boot/grub2/grub.cfg
いじるポイントは起動エントリです. 通常はこのエントリの最初が自動的に選択されます. つまり、最初のエントリの起動に失敗しているので先頭のエントリを丸ごと削除します.
### BEGIN /etc/grub.d/10_linux ###
enuentry 'CentOS Linux (3.10.0-1062.1.2.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestric
ted $menuentry_id_option 'gnulinux-3.10.0-514.26.2.el7.x86_64-advanced-63eec43b-cebd-4fd0-b92f-5518d45cfb00' {
load_video
set gfxpayload=keep
insmod gzio
insmod part_msdos
insmod xfs
set root='hd1,msdos1'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hin
t='hd1,msdos1' 63eec43b-cebd-4fd0-b92f-5518d45cfb00
else
search --no-floppy --fs-uuid --set=root 63eec43b-cebd-4fd0-b92f-5518d45cfb00
fi
linux16 /boot/vmlinuz-3.10.0-1062.1.2.el7.x86_64 root=UUID=63eec43b-cebd-4fd0-b92f-5518d45cfb00 ro crashkernel=auto consol
e=ttyS0,38400n8 LANG=ja_JP.UTF-8
initrd16 /boot/initramfs-3.10.0-1062.1.2.el7.x86_64.img
}
menuentry 'CentOS Linux (3.10.0-1062.1.1.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestric
ted $menuentry_id_option 'gnulinux-3.10.0-514.26.2.el7.x86_64-advanced-63eec43b-cebd-4fd0-b92f-5518d45cfb00' {
load_video
set gfxpayload=keep
insmod gzio
insmod part_msdos
insmod xfs
set root='hd1,msdos1'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hin
t='hd1,msdos1' 63eec43b-cebd-4fd0-b92f-5518d45cfb00
else
search --no-floppy --fs-uuid --set=root 63eec43b-cebd-4fd0-b92f-5518d45cfb00
fi
linux16 /boot/vmlinuz-3.10.0-1062.1.1.el7.x86_64 root=UUID=63eec43b-cebd-4fd0-b92f-5518d45cfb00 ro crashkernel=auto consol
e=ttyS0,38400n8 LANG=ja_JP.UTF-8
initrd16 /boot/initramfs-3.10.0-1062.1.1.el7.x86_64.img
}
...
最後に, 新規VMインスタンスの作成を行ます. 先ほどブートエントリを編集したディスクからVMインスタンスうを作成してください. 通常通りサーバーが立ち上がるはずです.
万が一に備える ~ インシデントから学んだこと
簡単です. バックアップをとりましょう. 最初は軽い気持ちで作ったサイトなどは、あまり手を混んでセットアップしていないためかバックアップの設定を怠りがちです. しかし、そのサイトが成長してから事故は起こります. 大切な情報資産を守るためにもバックアップは毎日とりましょう.
おすすめはGCPのスナップショットスケジュール
WordPressには定期的にバックアップを作成してくれるプラグインがあります.もちろん、それを利用しても構わないのですがバックアップを復元する操作が少々面倒です. そこでおすすめしたいのがGoogle Cloud Platformのスナップショットスケジュールを利用したバックアップです.

まとめ
WordPressに限らずWebサイトを運営している人は例え商用などの目的がないとしてもバックアップを怠らないようにしましょう. 万が一サーバーインシデントが発生した時のために復旧マニュアルを自分で作成することもおすすめします.
また、Linuxの操作が難しい人はロリポップ!
やエックスサーバー
などのレンタルサーバーや環境構築が容易なロリポップ!マネージドクラウド
やConoha
などのVPSサービスの利用をおすすめします.