CloudflareとCloudFrontを活用して激安で最強のアーキテクチャを構築する
はじめに:
初めまして、DELTAの馬場です。クラウドエンジニアをしています。
この記事はCloudflare Advent Calendar 2023 の 20日目 です。
概要:
弊社では自社サービスでCloudflareを使っていて、社内勉強会等を開催したりもしていました。
(そのレポートをnoteの記事にしているのでよかったらご覧ください。)
勉強会で得た知識から、もしかしてRoute53とCloudflareを組み合わせることで
より安価で高可用性なアーキテクチャを実現できるのではないか?という妄想が出てきたので
それが本当なのかどうかを確かめていきます。
Route53とCloudflareを組み合わせようという発想が出たきっかけは
CloudflareのSLAが100%なことを信用しきれないといったお話が出たので、問題が発生した時は
フェイルオーバーできるようなアーキテクチャがありますよ。と説明するための検証を行う必要が
あったからでした。
今回検証するアーキテクチャ
AWSで構築したサービスの前にCloudflareを配置します。
Cloudflareの障害があった際に備えてCloudflareをプライマリのCDNとし、障害が起きたときには
CloudFrontに切り替わるようにします。
構築していく
AWS上にwebサイト等の既存リソースがすでに構築されている前提で話を進めます。
私の環境では下記で簡単に構築しています。
Route53+CloudFront+S3
プライマリCDN(Cloudflare)の設定
Cloudflareの設定
まずはプライマリのCDNとするためにCloudflare側の設定を行います。
Cloudflareのサイトを追加します。
サイトを追加をクリックし、Zone Apexを入力します。
"Add a site / サイトを追加" をクリック
Zone Apexを入力して, "Add a site / サイトを追加" をクリック
ビジネスプランを選択します。
年間払いにして絶望を味わったので、支払いプランはお気をつけて、、、
ちょっとの検証にも$250かかる。。。
画面右下からPartial Setupモードにします。モード変更をするとTXTレコードが払い出されるのでメモっときます。次のステップでRoute53に登録します。
Convert to CNAME DNS Setup / フルDNSセットアップに変更 をクリックします。
cloudflare-verify.ドメイン に、払い出された値をTXTタイプとして登録し
レコードを作成します。
数字の塊が”-”で連結された値を”値”に入力し、 "レコードを作成" をクリックします。
Cloudflareの画面から下記のエラーが消えていることを確認する。
CDNの設定
プライマリとして利用するCloudflareのCDNを登録します。
ここからが難しいのですが、検証開始時はNSがRoute53にあります。
権威NSはRoute53にあるものの、Cloudflare側にもDNSのコンソールがあります。
Cloudflare側のDNSコンソールはDNSだけではなくCDNのエッジ・オリジンの関係を
登録する画面を兼ねています。
ここで、Cloudflare側のDNS兼CDNコンソールに、もともとやりたかった
CNAMEレコード(=オリジン)が登録されている必要があります。
例えば、www.sample.jp ⇒ XXX.cloudfront.net というレコードです。
Cloudflare上ではZone Apexが省略されるので,この例だと名前が
"www"でコンテンツがCloudFrontのディストリビューションが設定されることになります。
これ自体は、もともとRoute53に設定があれば、読み込みのステップで入っているはずなので
基本的にはそれを探してもらえば大丈夫です。なければ作成し、その上でそれが
「Proxied」と設定されているかを確認してください。
Route53にCloudflare CDNを登録する
先ほど作成したプライマリになるCloudflareのCDNにルーティングするように
Route53の設定を行います。
もともとのドメインのCNAMEは "そのドメイン.cdn.cloudflare.net" に向けてください。
ここで指示されているようにもともとのドメイン+Cloudflareのサフィックスの値を登録します。
sample.domainと変えてしまっていますが元のドメインに適宜読み替えてください。
流れのイメージとしては
(Route53)
ターゲットとなるドメイン ⇒ そのドメイン.cdn.cloudflare.net
(Cloudflare)
ターゲットとなるドメイン(実体としてはそのドメイン.cdn.cloudflare.net) ⇒
オリジンサーバーのドメイン名(or IP)
となります。
検証しているアーキテクチャで言えば
Route53 -> Cloudflare CDN -> CloudFront
という経路を通ります。
ここまでで、プライマリのCDNの設定作業は完了です!
フェイルオーバーをするための設定
先にRoute53にフェイルオーバーを行うための設定を行っていきます。
この後の流れとしてはRoute53のヘルスチェックの作成
↓
Route53で対象サービス/サイト用のフェイルオーバールーティングのプライマリレコードの設定
↓
セカンダリレコードの設定
となります。
Route53のヘルスチェックの作成
プライマリが利用できない状態を判断するためのヘルスチェックを作成。
Route53 > ヘルスチェック > ヘルスチェックの作成をクリック
自身の管理している対象サービス等のヘルスチェック用の設定を入力して「次へ」
通知について聞かれるので好きに答える。今回はわざと失敗させたりして挙動を試したいので
通知は切っておきます。
設定を終えたら「ヘルスチェックの作成」をクリック
プライマリレコードの設定を行う
Route53のホストゾーンに戻って、CloudflareのCDNに向けていたレコードを編集します。
”ルーティングポリシー”を”フェイルオーバー”に設定。”フェイルオーバーレコードタイプ”を
”プライマリ”に”ヘルスチェックID”は先ほど作成したヘルスチェックを設定し”レコードID”は
好きな値を入れていいらしいのでCloudflare用という意味を込めてrecord-for-Cfとしました。
(後続のセカンダリと被らなければなんでもいいっぽい)
セカンダリレコードの設定を行う
あるあるな使い方だとソーリーページ等を表示したりする物だと思いますが
今回はCloudflareが落ちたときにCloudFrontにフェイルオーバーさせるために利用します。
そのためCloudflare側で設定したCloudFrontを値に持つレコードをプライマリと同名で登録します。
- ”レコード名”はプライマリとそろえる。
普通だと一意制約違反で怒られるがセカンダリとして登録する場合は怒られない。 - ”値”は最初の方の手順でCloudflareに登録したものと同じものを登録。
- ”ルーティングポリシー”を”フェイルオーバー”に設定。
- ”フェイルオーバーレコードタイプ”を”セカンダリ”に”ヘルスチェックID”は設定しませんでした。
- ”レコードID”は好きな値を入れていいらしいのでAWS用という意味を込めてrecord-for-awsとしてます。
設定完了!!
動作検証
ここまでの構成で動くのか?を見ていきます。
意図通り動きます!
Cloudflareからの通信である
ちゃんとCloudflareのIPレンジの中に入ってます。
フェイルオーバーの挙動を確認する
本題のフェイルオーバーさせたときの挙動を確認します。
エラーを起こすのに手っ取り早いのでCloudflareのDNSレコードを消します。
消えました。
Route53のヘルスチェックの方を見てみます。
しばらく放置しておくと、ヘルスチェックで落ちたり正常になったりするため
フェイルオーバーしたときにヘルスチェックが成功していると判断できます。
設定してすぐの場合は”ヘルスチェッカー”のタブから確認してもらうのが良いと思います。
一方でサイトには変わらず接続できます。
切り替わってるはずなので再度digってみます
CloudFrontを見てる=セカンダリに切り替わっている!
一応Cloudflare側のDNSからだと動かないことも確認
Cloudflare側からは確認できなかったのでCloudflareのCDNが使えなくなったとしても、CloudFrontに自動で切り替わってサービスが止まらない挙動になるはず!!
追記
ERR_SSL_VERSION_OR_CIPHER_MISMATCH が発生する際の対応
SSL/TLS 暗号化モードをフル(厳密)
にすることで解消できたことを確認しています。
まとめ
当初の予想通り、通常時はCloudflareの安いCDNを利用しCloudflareで障害が起きた場合には自動でCloudFrontに切り替わるアーキテクチャが実現可能なことが分かりました。
これによって、少ない追加コストで管理が不要な、より可用性の高いアーキテクチャを実現できることが分かりました。
We're hiring!
最後までお読みいただきありがとうございます。
現在DELTA では一緒に働いてくださる仲間を大募集中です!
ご興味をお持ちいただけましたら、お気軽にフォームからご連絡ください。
Discussion