mod_proxy を使ってサービスを止めずにサーバ移転
CPIのVPSサーバが使えるようになったので、以前から借りていた TextDrive を解約するためのサーバを移転した。 普通に移行すると、DNSを切り替えるタイミングでサービスを停止しないといけない。 サービスを止めずに移行したかったので、ちょっと考えてみた。
以下、 example.com 上のサービス(PHPを使って動作している)を old.example.com というサーバから new.example.com というサーバへ移転する例。
(1) 新しいサーバ (new.example.com) のセットアップ
新しいサーバでは複数のドメインを運用したいので、フロント (80番ポート) にドメイン振り分け用の Apache を構築している。 この Apache では mod_proxy モジュールを有効にしている。 構築手順は先日の日記の通り。 さらに、バックエンド (8001番ポート) にPHPを動作するための Apache を構築する。
この時点では、 Web ブラウザはまだ旧サーバ (old.example.com) に接続している。
(2) DNSの切り替えとmod_proxy経由での旧サーバへの接続
新サーバ (new.example.com) で動作する mod_proxy の接続先を旧サーバ (old.example.com:80) に設定する。 そして、DNSを変更して example.com の向かい先を old.example.com から new.example.com へ切り変える。 DNSが伝搬するとともに Web ブラウザは旧サーバではなく新サーバへアクセスするようになるけど、新サーバ経由で旧サーバにアクセスしている状態。
同時に、旧サーバ上のアプリを順次、新サーバへ移行していく。 テストのときは、 example.com:8000 にアクセスする。 もちろん、8000番ポートには特定のホストのみアクセスできるようにファイアウォールを設定しておく。
(3) 新サーバへの切り替え
DNSが十分に伝搬して新サーバのテストも終わったら、 mod_proxy の接続先を old.example.com:80 から localhost:8000 へ切り替える。 これで、 Web ブラウザからは気がつかない状態で、旧サーバから新サーバへの移行が完了する。
注意点
データベースを使っている場合は、データベースの移行も考える必要がある。 今回は PukiWiki だったので、 rsync で事前にデータをコピーしておいて、切り替え直前にもう一回 rsync を実行するだけにした。 それから、個人で運営するサービスのレベルなので、これくらいということで。
注意点2
mod_proxy を使う場合は、バックエンドの Web サーバのログにはフロントのサーバの IP アドレス (127.0.0.1) が記録される。 Web ブラウザの IP アドレスを記録するためには、環境変数 X-Forwarded-For をログに記録するように設定すればOK。
-LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined +LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined