失敗しないDNS切り替えによるサーバ移転

by

@wapa5pow

Webエンジニアをしていれば経験したことがある人も少なくはない作業にDNSのレコード切り替えによるサーバ移転作業があります。

以下のように旧サーバがIPアドレスAで、新サーバがIPアドレスBで、DNSのレコードの向き先をAからBにするという作業です。

DNSのレコードを切り替えるだけなら簡単ではないかと思うかもしれませんが、自分は過去3回中2回失敗して再度挑戦して成功した経験がありなかなかあなどれません。
そのような経験の中で振り返りどのようにしていたら失敗しないで成功していたかを書こうかと思います。

失敗しないために

失敗しにくくするためには、以下の作業が必要です。

  1. 切り戻ししやすくする
  2. 切り替え前に実機でアクセスしてテストする
  3. 切り替え前にTLS証明書をテストする

切り戻ししやすくする

DNSのレコードを切り替えたあとに障害などが見つかり元のサーバに切り戻すということがあるかもしれません。DNSレコードの設定をもとにもどしただけで、ユーザから見えるサーバは元のサーバを参照するでしょうか。

これは設定によります。DNSのレコードにはTTL(Time To Live)が設定されています。この設定期間はクライアントがレコードをキャッシュして再度参照することがありません。
つまり、TTLが例えば1時間だと、新サーバにかえてから旧サーバに戻そうとしても最大1時間はクライアントから新サーバを見続けてしまいます。

切り戻しをしやすくするためにこのTTLを短く(具体的には60秒とか)してから、切り替える前のTTLの時間分の十分時間が立ってからDNSレコードの切り替えをするようにします。

このようにすれば切り替えに失敗しても安心して旧サーバに戻すことができ再挑戦できます。このTTLを修正せずに切り替えたばかりに切り戻しに1時間ほどまった苦い記憶があります。

切り替え前に実機でアクセスしてテストする

何を当たり前なことと思うかもしれませんが、DNS切り替え前の新サーバへのテストは結構面倒です。
なにが面倒かというと、例えばexample.comはいまIPアドレスAをみているのに、example.comにアクセスしたときにIPアドレスBを見ているというふうにアクセスするブラウザやアプリで偽装しなければなりません。

この切り替え前のテストは、現在旧サーバにアクセスしているすべてのクライアントの種類でテストするのがいいです。たとえば以下のようなものがあると思います。

  • ブラウザ
  • モバイル(iOS/Andorid)ブラウザ・アプリ
  • クローラなどのバッチ処理

各種やり方があると思いますが、よくつかっている方法を説明します。

ブラウザ

/etc/hostsに該当のレコードを追加します。例えば、example.comのIPアドレスを192.168.1.1としたかったら以下のようにします。

192.168.1.1 example.com

モバイル(iOS/Andorid)ブラウザ・アプリ

モバイルからはdnsmasqを使うと楽です。Macにdnsmqsqをいれて、モバイルのDNS設定から参照するようにします。

Macにdnsmasqをインストールするには以下のようにします。

$ brew install dnsmasq

設定ファイルを以下のように変更します。

/usr/local/etc/dnsmasq.conf
...
addn-hosts=/usr/local/etc/my_hosts
...

my_hostsには以下のように記載します。

/usr/local/etc/my_hosts
192.168.1.1 example.com

dnsmasqを起動します。

# 起動
$ sudo brew services restart dnsmasq

# 確認
$ sudo brew services

# 設定を変更した場合は以下で反映できます。
$ sudo killall -HUP mDNSResponder

# 停止
sudo brew services stop dnsmasq

ただしく反映されているかは以下で確認できます。

$ nslookup example.com 127.0.0.1
Server:		127.0.0.1
Address:	127.0.0.1#53

Name:	example.com
Address: 192.168.1.1

次にiOS/Androidの設定を行いdnsmasqを参照するようにします。

事前にMacのIPアドレスを調べておきます。今回は以下のように192.168.86.84でした。

iOSのDNSでdnsmasqを参照するには以下のようにします。

https://mobilelaby.com/blog-entry-5531.html

Androidでdnsmasqを参照するには以下のようにします。

https://mobilelaby.com/blog-entry-5530.html

切り替えたあと、実際にアクセスしてみると切り替わったことが確認できます。

クローラなどのバッチ処理

これも/etc/hostsを切り替えればできますが、Kubernetesでは以下のようにhostAliasesの値を追加することで/etc/hostsに値をかきこむことができます。

https://kubernetes.io/docs/tasks/network/customize-hosts-file-for-pods/

切り替え前にTLS証明書をテストする

昨今のWebサイトは必ずといっていいほどHTTPSで通信していますが、サーバ切り替え時も証明書を載せ替える場合もあるのでその証明書が正しいかどうかテストする必要があります。
以下などで旧サーバへのテストはできますが新サーバの証明書のテストはまだIPが切り替わっていないのでできません。

https://www.ssllabs.com/ssltest/

このような場合は testssl.sh を使うといいです。
Macにインストールして/etc/hostsを新サーバに向けてから以下のように実行できます。

$ testssl.sh example.com

証明書の正当性など多数の項目をチェックしてくれます。色分けで危険度を表してくれるのですが赤があった場合は要修正です。
以下のように赤で異常を知らせてくれます。

別のツールとしてはcheck-tls-certも有効です。

まとめ

DNS切り替えによるサーバ移転はDNSレコードを切り替えるという単純な作業なのですが、安全に行うためには多くの確認が必要です。
今後作業をする予定のある方は今回のような確認作業を行うとより安心して作業できると思います。