別記事にてVPC上に構築した各EC2に対して、Route53のPrivateHostedZoneで名前解決させる手順をご紹介しました。
今回は、Route53のPrivateHostedZoneにてDNSフェイルオーバー(Active-Passive)を設定する手順をご紹介していきたいと思います。
※Active-ActiveのDNSフェイルオーバーはこちらで手順をご紹介しています。
構成の確認
構成を確認する前に、DNSフェイルオーバーについて軽く復習します。
DNSフェイルオーバーとは、ドメインに紐づけたサーバーに障害が発生した場合に、
ドメイン名を変更せずに別サーバーへリダイレクトさせる機能です。
参考:フェイルオーバーとは
Rotute53の場合は、HostedZoneにてDNSフェイルオーバーの設定が可能となります。
今回は、Route53のフェイルオーバールーティングを利用し、Active-PassiveのDNSフェイルオーバー設定を行います。
現在の構成
まずは、現在の状況を確認します。
現在は、10.0.0.0/21のCIDRを割り当てたVPC上に、パブリックサブネット(10.0.0.0/24)、プライベートサブネット(10.0.1.0/24)を作成している状態です。
パブリックサブネットの上には踏み台サーバーが二つ、プライベートサブネットの上にはWEBサーバーが一つ配置されています。
VPCには、Route53のPrivateHostedZone(https-demo.com)を割り当て、各サーバーに対して名前解決を行える状態となっています。
今回の構成
今回は、ここにVPCもう一つのプライベートサブネット(10.0.5.0/24)を作成したうえで、WEBサーバーをもう一台配置します。
Route53のDNSフェイルオーバー機能を利用して、二台のWEBサーバーでDNSフェイルオーバー(Active-Passive)の設定を行います。
DNSフェイルオーバー(Active-Passive)について
「Active-Passive」と「Active-Active」の違い
今回は、PrivateHostedZone上のレコードに対して、Active-Passiveのフェイルオーバールーティングを設定していきます。
Route53のユーザーガイドには、フェイルオーバーの設定として下記二種類の記載があります。
・Active-Passive
・Active-Active
個人的に二つの違いが分かりづらかったため、下記表にて二つの違いについて整理します。
種類 | 挙動 | 設定方法 |
---|---|---|
Active-Passive | 平常時はプライマリのレコードのみにルーティング。 プライマリのサーバーに対するヘルスチェックが失敗した時のみ、セカンダリのレコードにフェイルオーバーする。 |
Route53のルーティングポリシーで「フェイルオーバー」を選択。 プライマリのレコードにのみヘルスチェックを設定する。 |
Active-Active | 平常時はプライマリ・セカンダリ両方のレコードにルーティング。 ヘルスチェックが失敗したレコードは名前解決対象から外し、正常に動作しているリソースのみルーティング対象にする。 |
Route53のルーティングポリシーを「フェイルオーバールーティング」以外で設定。そのうえで、各レコードに対してヘルスチェックを設定する。主に下記のようなルーティングポリシーを使用。 ・加重 ・レイテンシー |
Active-Passiveの挙動
今回はPrivateHostedZoneにてActive-PassiveのDNSフェイルオーバーを設定します。
具体的な設定内容について、構成図でもう少し確認していきます。
Route53のヘルスチェックについて
PublicHostedZoneの場合
Route53にてDNSフェイルオーバーを実装する場合は、レコードに対してHealthCheckを紐づける必要があります。
Route53のHealthChekerは、設定したIPアドレスやエンドポイントURLに対して、インターネット経由でリクエストを送信します。
参考:Amazon Route 53 ヘルスチェックの種類
参考:Route53ヘルスチェッッカーのIPアドレス範囲
PrivateHostedZoneの場合
しかし、今回はPrivateHostedZoneにて、プライベートサブネット上のリソースにDNSフェイルオーバーを設定しようとしています。
リソースはプライベートサブネット上に存在するため、インターネット経由でのヘルスチェックを受け付けることができません。
このような場合は、Route53のヘルスチェックにCloudWatchAlarmを紐づけることができます。
今回は、WEB1(10.0.1.4)をフェイルオーバールーティングのプライマリレコードに、WEB2(10.0.5.4)をフェイルオーバールーティングのセカンダリレコードに設定します。
今回はActive-PassiveのDNSフェイルオーバーを設定するため、ヘルスチェックはプライマリのレコードに対してのみ紐づけます。
具体的には、DNSフェイルオーバー(プライマリ)のレコードに対するRoute53のヘルスチェックとして、WEB1(10.0.1.4)の「StatusCheckFailed_System」メトリクスを監視するCloudWatchAlarmを紐づけます。
平常時の挙動(Active-Passive)
StatusCheckFailed_Systemは、EC2のステータスチェックが失敗すると「1」を記録します。
今回の構成だと、WEB1(10.0.1.4)の「StatusCheckFailed_System」メトリクスが「0」の間はRoute53のヘルスチェックが成功し、WEB1に対してルーティングが行われます。
異常検知時の挙動(Active-Passive)
WEB1(10.0.1.4)の「StatusCheckFailed_System」メトリクスが「1」を記録するとRoute53のヘルスチェックが失敗し、WEB2へのDNSフェイルオーバーが発生します。
WEB1(10.0.1.4)の「StatusCheckFailed_System」メトリクスが再び「0」へ戻ると、Route53のヘルスチェックは成功し、WEB1へのフェイルバックが発生します。
作業の流れ
作業は下記流れで行います。
今回はRoute53のDNSフェイルオーバー設定手順がメインとなるため、VPC・サブネットや踏み台サーバーの作成方法は割愛します。こちらの記事にて手順をご紹介しているため、作成方法が分からない場合はご参照ください。
1.Route53でPrivateHostedZoneを作成し、VPCに紐づける
2.EC2(WEB1/2)にApacheをインストールし、テスト用ページを配置する
3.フェイルオーバールーティングでプライマリに指定するWEB1に対してCloudWatchAlarmを設定
4.Route53のヘルスチェックを作成
5.Route53のフェイルオーバールーティング(Active-Passive)を設定
6.動作確認
構築手順
Route53でPrivateHostedZoneを作成し、VPCに紐づける
Route53PrivateHostedZoneの作成
こちらの手順について、別記事にてすでにご紹介している状態です。
しかし、この記事のみ参照される方もいるかもしれないので、軽く作成手順を記載します。
Route53のサービス画面に移動し、左メニューから「ホストゾーン」を押下します。
ホストゾーンの画面が表示されるので、「ホストゾーンの作成」を押下します。
ホストゾーンの作成ページが表示されます。ドメイン名を入力し、「タイプ」を「プライベートホストゾーン」に設定します。
スクロールし、「ホストゾーンに関連付けるVPC」セクションに移動します。
「VPCを追加」を押下します。
「リージョン」を指定し、PrivateHostedZoneを紐づけたいVPCのIDを選択します。
「ホストゾーンの作成」を押下すると、PrivateHostedZoneが作成できます。
現在、下記のように踏み台サーバー1/2のAレコードを登録している状態です。
※Aレコード・NSレコード・SOAレコードについては別記事にてご紹介しています。
VPC側でDNS解決・DNSホスト名を有効化
プライベートホストゾーンのレコードを名前解決させるためには、VPC側でDNS解決・DNSホスト名の有効化設定を行う必要があります。
VPCのサービス画面に移動し、左メニューから「お使いのVPC」を押下します。
VPCの一覧が表示されたら、ホストゾーンと紐づけたVPCのチェックボックスにチェックを入れます。左上の「アクション」メニューの中から、「VPCの設定を編集」を押下します。
VPCの詳細編集画面が表示されます。
「DNS解決を有効化」と「DNSホスト名を有効化」のチェックボックスにチェックを入れ、「保存」を押下します。
VPCの設定変更が完了した状態です。
画面上部に「設定が正常に変更されました」と表示されることを確認します。
EC2(WEB1/2)にApacheをインストールし、テスト用ページを配置する
EC2の詳細な構築手順・接続手順は別記事をご参照ください。
ここでは、既に構築済のEC2(AmazonLinux2)に対しApacheをインストールし、ServerName・indexページを配置する手順をご紹介します。
Apacheのインストール
まずはApacheをインストールします。
プライベートサブネット上のEC2に接続したら、apacheをインストールします。
下記コマンドを実行し、apacheをインストールします。
sudo yum -y install httpd
ServerNameの設定
Apacheのインストールが完了したら、httpd.confの設定にて、ServerNameの変更を行います。
ApacheはHTTPリクエストに含まれるhostヘッダーにより、どのページを表示させるかを決めます。
参考:バーチャルホストの例(Apache公式)
今回はWEB1(10.0.1.4)のサーバーに対し、「web-test. https-demo.com」というDNS名を設定します。
そのため、ApacheのVirtualHostのServerNameにも、「web-test. https-demo.com」を設定します。
まずはconfファイルが配置されているフォルダまで移動します。下記コマンドを実行し、「/var/www/html」ディレクトリまで移動します。
cd /etc/httpd/conf
pwd
ls -la
httpd.confを編集するため、初期状態のconfファイルをバックアップします。
下記コマンドを実行します。
sudo cp httpd.conf httpd.conf.org
ls -la
httpd.confとhttpd.conf.orgが存在することを確認します。
下記コマンドを実行し、httpd.confを編集します。
sudo vim httpd.conf
vimのエディタが開いたら、キーボードの[/]を押下して文字列モードに切り替えます。
[ServerName]と入力しエンターキーを押下すると、該当の記載に移動できます。
キーボードの[i]を押下してvimを編集モードに切り替え、「ServerName」と記載のある個所を下記のように編集します。
この際に、元の記載(ServerName www.example.com:80)はコメントアウトするようにしましょう。
ServerName web-test.https-demo.com:80
キーボードの[:wq]を押下してvimを終了します。
confファイルを編集したため、下記コマンドにてapacheの再起動を行います。
sudo systemctl restart httpd.service
さらに、下記コマンドを実行し、Apacheの状態を確認します。
sudo systemctl status httpd.service
サーバーを再起動してもApacheが自動起動するよう、下記コマンドを実行します。
sudo systemctl enable httpd.service
再度statusコマンドを実行すると、ApacheのサービスがEnable状態となっていることが確認できます。
sudo systemctl status httpd.service
index.htmlの配置
初期状態のApacheでは、DocumentRoot(ApacheがWebサーバーとして公開するファイルを配置するフォルダ)が「/var/www/html」に設定されています。
今回は、/var/www/html配下に「index.html」というテストページ用ファイルを配置します。
下記コマンドを実行し、/var/www/htmlに移動します。
cd /var/www/html
ls -la
下記コマンドを実行し、「index.html」ファイルを作成します。
sudo touch index.html
ls -la
index.htmlファイルが存在することを確認出来たら下記コマンドを実行し、index.htmlファイルを編集します。
sudo vim index.html
vimエディタが開いたら、キーボードで[:set paste]と入力します。
これで、文字列をきれいにペーストできる状態となります。
index.htmlファイルに下記のhtmlをペーストし、[:wq]を押下してvimエディタを閉じます。
WEB1用のindex.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WEB1</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
background-color: #f9f9f9;
}
h1 {
color: #333;
}
p {
color: #666;
}
a {
color: #007BFF;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<h1>ここはWEB1</h1>
<p>これはweb1。</p>
<p>これはWEB1のコンテンツ</p>
</body>
</html>
これで、プライマリとなるWEB1側の設定が完了します。
セカンダリとなるWEB2側にも、同様の手順でApacheのインストール・ServerNameの設定を行ってください。
設定完了したWEB1のAMIを取得し、WEB2を作成すると設定が楽です。
ServerNameについては、WEB1/WEB1ともに「ServerName web-test.https-demo.com:80」を設定します。
ただし、ブラウザから接続しているWEBサーバーがWEB1/WEB2のどちらなのか判別を付けるため、
WEB2のindex.htmlは背景の色コードや表示されている文面を変えたものを配置します。
WEB2用のindex.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WEB2</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
background-color: #d7f3e3;
}
h1 {
color: #006400;
}
p {
color: #228B22;
}
a {
color: #006400;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<h1>ここはWEB2</h1>
<p>これはweb2。</p>
<p>これはWEB2のコンテンツ</p>
</body>
</html>
フェイルオーバールーティングでプライマリに指定するWEB1に対してCloudWatchAlarmを設定
プライマリに指定するWEB1に対して、CloudWatchAlarmを設定します。
※SNSトピックの作成については別記事で紹介しています。手順が分からない場合はそちらをご参照ください。
CloudWatchのサービス画面に移動し、左メニューから「すべてのアラーム」を押下します。
CloudWatchAlarmの一覧が表示されます。「アラームの作成」を押下します。
メトリクスの選択画面が表示されます。
「メトリクスの選択」を押下します。
メトリクスの一覧が表示されます。「EC2」を押下し「インスタンス別メトリクス」を押下します。
EC2のメトリクス一覧から、メトリクス名が「StatusCheckFailed_system」かつ「インスタンス名」がWEB1(この画像ではHTTPS_DEMO_01)となっているものを見つけ、チェックボックスにチェックを入れます。
「メトリクスの選択」を押下します。
メトリクスの監視条件設定画面が表示されます。
「統計」を「最大」に設定し、「期間」を「1分」に設定します。
「条件」のセクションまでスクロールします。
しきい値の種類は「静的」を選択します。
アラーム条件には「以上(>=しきい値)」を設定し、しきい値には「1」を設定します。
「StatusCheckFailed_system」メトリクスは、EC2が停止している間は記録されない状態となります。
メトリクスが欠落(記録されない)している状態でもDNSフェイルオーバーとなるよう、
「欠落データの処理」を「欠落データを不正(しきい値を超えている)として処理」に設定します。
全ての設定を終えたら、「次へ」を押下します。
アクションの設定画面が表示されます。
「アラーム通知トリガー」を「アラーム状態」にします。
SNSトピックを「既存のSNSトピックを選択」に指定し、プルダウンからSNSトピックを選択します。
「名前と説明を追加」の画面が表示されます。
アラーム名を入力し、「次へ」を押下します。
プレビュー画面で設定内容を確認します。
Route53のヘルスチェックを作成
CloudWatchAlarmの設定が完了したら、Route53のヘルスチェックを作成します。
Route53のトップページに移動し、左メニューから「HealthCheck」を押下します。
ヘルスチェックのトップ画面が表示されたら、「ヘルスチェックの作成」を押下します。
ヘルスチェックの設定が表示されます。
ヘルスチェックの名前を入力します。
「モニタリングの対象」は「CloudWatchアラームの状態」を設定します。
「CloudWatchリージョン」を対象のサーバーが存在するリージョン(今回は東京リージョン)に設定します。
「CloudWatchAlarm」には、先ほど作成したCloudWatchAlarmを設定します。
下にスクロールします。
ヘルスチェックステータスについて、「アラームが不足状態にある場合、そのステータスは正常です」を選択します。
全ての設定を完了したら、「次へ」を押下します。
ヘルスチェックが失敗した際の通知についての設定画面が表示されます。
「アラームの作成」は「いいえ」を選択し、「ヘルスチェックの作成」を押下します。
「ヘルスチェックの作成に成功しました」と表示されます。
画面を更新すると、作成したヘルスチェックが確認できるようになります。
Route53のフェイルオーバールーティング(Active-Passive)を設定
Route53のフェイルオーバールーティングを設定します。
左メニューから「ホストゾーン」を押下します。
ホストゾーン一覧が表示されたら、対象のホストゾーンのリンクを押下します。
レコードの一覧画面が表示されます。
Active(WEB1)のレコード作成
まずはActiveとなるWEB1のレコードを作成します。
「レコードを作成」を押下します。
レコード画面が表示されます。
「レコード名」は「web-test」と入力します。
「レコードタイプ」は「A」に設定します。
「値」は10.0.1.4を設定します。
「TTL」は「60」を設定します。
「ルーティングポリシー」を「フェイルオーバー」に設定すると、フェイルオーバーレコードに関する設定項目が表示されます。
今はActive側のレコードを設定しているため、「フェイルオーバーレコードタイプ」を「プライマリ」に設定思案す。
「ヘルスチェックID」のプルダウンメニューから、先ほど作成したRoute53ヘルスチェックを選択します。
「レコードID」には「web-test-primary」を入力します。
全ての項目を設定し終えたら、「別のレコードを追加」を押下します。
Passive(WEB2)の設定
レコード追加画面が表示されます。
今度はWEB2の設定を入力します。
「レコード名」はActive側と同様に「web-test」を設定し、「レコードタイプ」は「A」を選択します。
「値」には「10.0.5.4」を入力します。
「TTL」は60秒、「ルーティングポリシー」は「フェイルオーバー」を設定します。
「フェイルオーバーレコードタイプ」は「セカンダリ」を設定し、ヘルスチェックは紐づけません。
「レコードID」に「web-test-secondary」と入力し、「レコードを作成」を押下します。
接続確認
平常時
接続確認を行ってみます。
踏み台サーバー(Windows)にログインし、ブラウザを立ち上げます。
ブラウザに「http://web-test.https-demo.com 」と入力すると、WEB1のテストページが表示されます。
コマンドプロンプトを立ち上げ、下記コマンドを実行してみます。
nslookup web-test.https-demo.com
すると、10.0.0.2のDNSサーバーから、「10.0.1.4(WEB1のIPアドレス)」が回答されます。
これで、平常時はWEB1にルーティングされていることが確認できました。
フェイルオーバーの確認
次はWEB1のサーバーの電源を落とし、DNSフェイルオーバーが発生することを確認します。
EC2の画面から、WEB1のサーバーを停止します。
CloudWatchAlarmの状態が「アラーム状態」となるまでしばらく待機します。
Route53のヘルスチェックも「異常」となっていることを確認します。
この状態で再度踏み台サーバーのブラウザから「http://web-test.https-demo.com 」を確認してみます。
WEB2のコンテンツが表示されることを確認します。
※うまく表示が切り替わらない場合は、ctrl+f5キーでブラウザを更新するか、コマンドプロンプトで「ipconfig /flushdns」コマンドを実行の上で確認してみてください。
再度サーバーを起動し、CloudWatchアラームが「OK」の状態になるまで待機します。
WEB1サーバーが起動し、CloudWatchアラームが「OK」の状態になると、「http://web-test.https-demo.com 」には再度WEB1のコンテンツが表示されます。
ここまでお読みいただきありがとうございました。
次回は、DNSフェイルオーバー(Active-Active)の設定手順をご紹介しようと思います。