2026年6月16日

2026年6月16日

ヘルスチェック型DNS を導入する手順|Route 53 で監視だけを先に動かし、様子を見てからレコードに結び付ける

ヘルスチェック型DNS は、DNS サービスが定期的にサーバーへ接続して状態を確かめ、異常と判断したサーバーのアドレスを応答から外す仕組みです。導入でつまずきやすいのは設定そのものより、「何を正常とみなすか」が曖昧なまま本番のレコードに結び付けてしまい、誤判定で正常なサーバーが外れることです。この記事では Amazon Route 53 を例に、確認用 URL の用意、ヘルスチェックを監視だけで動かす期間、通知の設定、レコードへの結び付け、本番前の試験までを順番に説明します。

導入の全体の流れ

一度にすべてを切り替えず、次の順で段階的に進めます。

  1. 「正常」の定義を決める
  2. WordPress に確認用の URL を用意する
  3. ヘルスチェックを作り、レコードには結び付けずに動かす
  4. 通知を設定し、数日間の判定結果を見る
  5. TTL を下げてから、レコードにヘルスチェックを結び付ける
  6. 本番の切り替えが起きる前に、わざと異常にして試す

手順3と4で「監視だけの期間」を挟むのがこの記事の要点です。ヘルスチェックは作っただけではレコードに影響しないため、誤判定が起きないかを本番の応答に触れずに観察できます。

手順1:何をもって「正常」とするかを決める

Route 53 のヘルスチェックには、接続先を直接確かめるもの、ほかのヘルスチェックの結果をまとめるもの(算出されたヘルスチェック)、CloudWatch のアラームの状態を見るものがあります。最初に検討するのは接続先を直接確かめる方式で、確認の深さを次の中から選びます。

  • TCP:ポートに接続できれば正常。Web サーバーが動いているかは分かりますが、PHP やデータベースの障害は見逃します。
  • HTTP / HTTPS:決まった時間内に 2xx または 3xx の応答が返れば正常。
  • HTTP / HTTPS の文字列一致:上に加えて、応答本文の先頭部分に指定した文字列が含まれるかも見ます。

WordPress では、文字列一致を使い、データベースまで確かめる軽い URL を対象にするのがおすすめです。トップページを対象にすると、ページキャッシュだけが返っている状態を正常と判断してしまうことがあります。

もう一つ決めておくのが、確認の経路です。CDN を経由させると CDN の応答を見ることになるため、ヘルスチェックは拠点のロードバランサーやサーバーの IP アドレスに直接向けます。複数のサーバーがある場合は、サーバーごとにヘルスチェックを作ると、どれが悪いかを見分けやすくなります。

手順2:WordPress に確認用の URL を用意する

データベースへの接続を確かめて ok か ng だけを返す URL を、mu-plugin で用意します。wp-content/mu-plugins/ に置いたファイルは有効化の操作なしで読み込まれ、テーマの切り替えにも影響されません。作業はステージングで試してから本番に入れてください。

<?php
/**
 * Plugin Name: DNS Health Check
 * Description: ヘルスチェック型DNS 用の確認 URL(例)
 */

defined( 'ABSPATH' ) || exit;

add_action( 'rest_api_init', function () {
	register_rest_route(
		'dnshc/v1',
		'/ping',
		array(
			'methods'             => 'GET',
			'callback'            => 'dnshc_ping',
			// 返すのは ok / ng だけなので認証は求めない
			'permission_callback' => '__return_true',
		)
	);
} );

function dnshc_ping() {
	global $wpdb;

	$ok = ( '1' === (string) $wpdb->get_var( 'SELECT 1' ) );

	$response = new WP_REST_Response(
		array( 'status' => $ok ? 'ok' : 'ng' ),
		$ok ? 200 : 503
	);
	$response->header( 'Cache-Control', 'no-store' );

	return $response;
}

URL は https://www.example.com/wp-json/dnshc/v1/ping です。応答にはバージョンやエラーの内容を含めず、外部から見られても困らない情報だけにしています。

用意したら、次の三点を確認します。

  • サーバー上のページキャッシュ(プラグインや Nginx の FastCGI キャッシュなど)の対象から外れているか
  • セキュリティ系のプラグインや WAF が REST API への匿名アクセスを止めていないか
  • ヘルスチェックの送信元を遮断していないか。送信元のアドレスの範囲は、AWS が公開している IP アドレス範囲の一覧で確認できます

手順3:ヘルスチェックを作り、まずは監視だけで動かす

設定内容を JSON ファイルにまとめます。IPAddress にサーバーのアドレスを、FullyQualifiedDomainName にサイトのホスト名を入れると、Route 53 はそのアドレスへ接続し、ホスト名を Host ヘッダー(HTTPS では SNI)に使います。WordPress が正しいサイトとして応答するために必要な指定です。

{
  "Type": "HTTPS_STR_MATCH",
  "IPAddress": "192.0.2.10",
  "Port": 443,
  "FullyQualifiedDomainName": "www.example.com",
  "ResourcePath": "/wp-json/dnshc/v1/ping",
  "SearchString": "\"status\":\"ok\"",
  "RequestInterval": 30,
  "FailureThreshold": 3,
  "EnableSNI": true
}
aws route53 create-health-check \
  --caller-reference "site-a-$(date +%Y%m%d%H%M%S)" \
  --health-check-config file://hc-site-a.json

# 画面で見分けやすいように名前を付ける
aws route53 change-tags-for-resource \
  --resource-type healthcheck \
  --resource-id your-health-check-id \
  --add-tags Key=Name,Value=site-a

--caller-reference は重複できない文字列で、同じ値で再実行すると作り直しになりません。日時を含めておくと扱いやすくなります。

作成後、少し待ってから判定の状況を見ます。

aws route53 get-health-check-status --health-check-id your-health-check-id

複数の地域にあるチェッカーごとの結果が返ります。一部の地域だけが失敗している場合は、その地域からの経路やファイアウォールの設定を疑います。この時点ではまだどのレコードにも結び付けていないため、判定が揺れても利用者には影響しません。

手順4:通知を設定して数日様子を見る

ヘルスチェックの結果は CloudWatch の AWS/Route53 名前空間の HealthCheckStatus という指標で見られます(正常で 1、異常で 0)。Route 53 の指標は米国東部(バージニア北部)リージョンに記録されるため、アラームもそのリージョンで作ります。

aws cloudwatch put-metric-alarm --region us-east-1 \
  --alarm-name "site-a-health" \
  --namespace AWS/Route53 --metric-name HealthCheckStatus \
  --dimensions Name=HealthCheckId,Value=your-health-check-id \
  --statistic Minimum --period 60 --evaluation-periods 1 \
  --threshold 1 --comparison-operator LessThanThreshold \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:your-topic

この状態で数日間、深夜のバックアップ、プラグインの自動更新、アクセスが集中する時間帯を経験させます。その間に通知が来たら、原因を一つずつ確かめます。よくあるのは、バックアップ中にデータベースの応答が遅れて時間内に返らない、更新中のメンテナンス表示が 503 を返す、といったものです。後者は本来外れてよい場面なので、どこまでを異常とみなすかをここで決め直します。

手順5:TTL を下げ、レコードにヘルスチェックを結び付ける

結び付ける前に、現在のレコードを書き出して保存します。

aws route53 list-resource-record-sets --hosted-zone-id your-zone-id > records-backup.json

次に、対象レコードの TTL を短く(例: 60秒)します。元の TTL が長い場合は、その時間が過ぎるまで待ってから次へ進みます。TTL を下げると問い合わせの数が増えるため、短くしすぎないようにします。

そのうえで、主と副の2行をフェイルオーバーのルーティングポリシーで作り、それぞれにヘルスチェックの ID を指定します。主のレコードにヘルスチェックを付けないと、Route 53 は主を常に正常とみなし、切り替えが起きません。ルーティングポリシーの名称や画面の表記は変わることがあるため、作業時は AWS のドキュメントで確認してください(2026年10月現在)。

手順6:本番の切り替えが起きる前に一度試す

導入の最後に、わざと異常な状態を作ります。たとえば上のコードに一時的に $ok = false; を加えた版をステージングで用意する、または対象サーバーの Web サーバーを短時間止めます。そのうえで次を確かめます。

  • 通知が届くまでの時間
  • dig @権威サーバー www.example.com +short の応答が副のアドレスに変わるまでの時間
  • 元に戻したあと、主のアドレスに戻るまでの時間

確認の間隔 30秒、失敗の回数 3回、TTL 60秒の設定なら、切り替わりまで数分程度が目安です。試験の記録は、障害時の判断材料として残しておきます。

自前の DNS サーバーで導入する場合

マネージドの DNS を使わない場合、PowerDNS の LUA レコード(ifurlup() など)のように、権威サーバー自身が接続先を確かめて応答を変える機能を使う方法があります。設定ファイルで LUA レコードを有効にする必要があり、確認はネームサーバーの台数ぶん行われます。書式や挙動は版によって異なるため、使っている版のドキュメントで確認してから導入してください。ネームサーバーと Web サーバーが同じ場所にあると、両方が同時に止まって切り替えられないため、置き場所も分けて考えます。

まとめ

  • 導入は「正常の定義 → 確認用 URL → 監視だけで運用 → 通知 → レコードへ結び付け → 試験」の順に進めると、誤判定を本番の前に見つけられます。
  • WordPress ではデータベースまで確かめる軽い URL を mu-plugin で用意し、キャッシュと遮断の対象から外します。
  • ヘルスチェックは作っただけではレコードに影響しないため、数日の観察期間を取れます。
  • 結び付ける前にレコードを保存し、TTL を下げて元の TTL が切れるのを待ちます。主のレコードにもヘルスチェックを付けます。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲