本記事では、EKSクラスターを災害対策(DR)リージョンへ自動フェイルオーバーさせる手順を解説します。まずはEKSとRoute 53について簡単に紹介します。
Amazon Elastic Kubernetes Service (EKS) は、AWS上でKubernetesを実行できるフルマネージドサービスです。Kubernetesのコントロールプレーンやワーカーノードを自前でインストール・運用・保守する必要がありません。EKSを使えば、Kubernetesの強力さと柔軟性を活かし、複数のAWSアベイラビリティゾーンにまたがってコンテナ化アプリケーションをデプロイ・管理・スケールできます。さらにIAM、VPC、CloudWatch、CloudFormationなど数多くのAWSサービスや機能と統合されており、安全かつ信頼性が高くスケーラブルなKubernetesプラットフォームを実現します。

Amazon Route 53は、AWSやインターネット上のWebアプリケーション・リソースへユーザーを接続するクラウドベースのDNSサービスです。DNSクエリと応答に対し、高い可用性、スケーラビリティ、パフォーマンス、セキュリティを提供します。さらに、ヘルスチェック、トラフィック管理、ドメイン名登録、DNSSECなどの高度な機能もサポートします。Elastic Load Balancing、CloudFront、S3などの他のAWSサービスとも連携し、アプリケーションに最適なエンドポイントへユーザーをルーティングできます。
本記事では、US-EAST-1(本番リージョン)とUS-WEST-2(DRリージョン)に2つのEKSクラスターを起動します。本番クラスターにはRoute 53でカスタムドメインを割り当て、両クラスターで2048ゲームを動作させたうえで、本番クラスターに障害を発生させてRoute 53による自動フェイルオーバーを検証します。EKSクラスターを起動する方法はAWSコンソール、Terraform、CloudFormationなど複数ありますが、本記事ではどなたでも理解しやすいよう、シンプルにAWSコンソールを使用します。以下が概念アーキテクチャ図です。

概念アーキテクチャ
**ステップ1:EKSクラスターの作成**
ここでは本番リージョンus-east-1でゲームを起動する手順を紹介します。同様の構成をus-west-2にも用意してあります。
Name: eks-blog-production-us-east-1
Kubernetes Version: 1.25
Cluster Service Role:「eksClusterRole」というロールを作成し、AmazonEKSWorkerNodePolicy、AmazonEC2ContainerRegistryReadOnly、AmazonEKS_CNI_Policyの3つのポリシーがアタッチされていることを確認してください。

eksClusterRole
デフォルトVPCを選択し、サブネットを2〜3個指定します。
ポート22、80、8080を開放したセキュリティグループを選択します。
Cluster endpoint accessの設定: public

起動前のクラスター詳細
ステップ2:クラスターへのノードグループの追加
クラスターを開く > Compute > Add NodeGrp
Name: eks-blog-production-eks-nodegrp-1
Cluster Service Role:「eksNodeRole」というロールを作成し、AmazonEKSWorkerNodePolicy、AmazonEC2ContainerRegistryReadOnly、AmazonEKS_CNI_Policyの3つのポリシーがアタッチされていることを確認してください。
その他の項目はデフォルトのままで構いません。

EKSノードグループ
ステップ3:クラスターへの認証
AWS CloudShellを開き、以下のコマンドを実行します。
# Type on your AWS CLI window
aws sts get-caller-identity
# observe your account and user id details
# Create a kubeconfig file where it stores the credentials for EKS:
# kubeconfig configuration allows you to connect to your cluster using the kubectl command line.
aws eks update-kubeconfig --region us-east-1 --name eks-blog-production-us-east-1
# see if you can get the nodes you created
kubectl get nodes

コマンドの実行結果
ステップ4:2048ゲーム用のPodをEKSに作成
クラスターに2048ゲームのPodをデプロイするため、以下の2048-pod.yamlを作成します。
### code starts ###
apiVersion: v1
kind: Pod
metadata:
name: 2048-pod
labels:
app: 2048-ws
spec:
containers:
- name: 2048-container
image: blackicebird/2048
ports:
- containerPort: 80
### code ends ###
YAMLファイルを適用してPodを作成します。
# apply the config file to create the pod
kubectl apply -f 2048-pod.yaml
#pod/2048-pod created
# view the newly created pod
kubectl get pods

2048 Pod作成完了
ステップ5:ロードバランサーサービスのセットアップ
続いて、以下のmygame-svc.yamlを作成し、ロードバランサーサービスを構築します。
### code starts ###
apiVersion: v1
kind: Service
metadata:
name: mygame-svc
spec:
selector:
app: 2048-ws
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer
### code ends ###
ロードバランサーサービスのファイルを適用します。
# apply the config file
kubectl apply -f mygame-svc.yaml
# view details of the modified service
kubectl describe svc mygame-svc

ロードバランサーサービスの作成完了
ロードバランサーのエンドポイント「ab8412c93389c4e29beb8c5e3778d368–260705609.us-east-1.elb.amazonaws.com」をブラウザに貼り付けると、ゲームが表示されるはずです。

ステップ6:ドメイン[www.doyouneedk8s.com](http://www.doyouneedk8s.com/)をゲームへルーティング
Route 53でドメインwww.doyouneedk8s.comのホストゾーンを開き、ロードバランサーのエンドポイントをCNAMEレコードとして追加します。DNSレコードが伝播したら、ブラウザでドメインにアクセスするとゲームが表示されます。

Route 53のCNAME
ステップ7:障害の発生
ここで、米国バージニアで障害が発生したと仮定します。US-EAST-1のアプリケーションに対し、手動で障害状態を再現してみましょう。具体的には、ロードバランサーのセキュリティグループからポート80のインバウンドルールを削除します。すると、ゲームは読み込めなくなります。これは、本番アプリケーションにフェイルオーバー先が用意されていないためです。

ステップ8:Route 53によるDRリージョンへのフェイルオーバー設定
まず、Route 53でアプリケーション向けのヘルスチェックを作成します。Route 53を開き、左側のナビゲーションから「Health Checks」を選択し、「Create Health Check」ボタンをクリックします。
Name: www.doyouneedk8s.com
What to monitor: Endpoint
Monitor and endpoint > Select Domain Name > Domain Nameのテキストボックスにwww.doyouneedk8s.comを入力し、Portは80を指定します。

ヘルスチェック作成画面1
Nextをクリックすると、次のページでこのイベント用のアラームを作成するオプションが表示され、フェイルオーバー発生時に通知を受け取れるようになります。設定は非常に簡単で、検証済みのSNSトピックを選ぶだけです。「Create Alarm」でYesを選択し、「Create health check」をクリックします。

ヘルスチェックの作成
設定したパラメータをヘルスチェックがクリアすると、緑色の「Healthy」と表示されます。

ヘルスチェックの利用準備完了
Route 53でwww.doyouneedk8s.comのホストゾーンを開き、CNAMEレコードを選択して、Routing Policyで「Failover」を選びます。
Failover record type: Secondary
Health Check ID: 先ほど作成したドメインのヘルスチェックを指定します。
Record ID: 米国オレゴンリージョンでゲームを起動した際に作成されたUS-WEST-2のロードバランサーを指定します。レコードを保存します。

いよいよテストです。上記ステップ7と同じ手順で再度障害を発生させます。今回はゲームが引き続き動作することが確認できます。分かりやすくするため、ゲーム画面に異なるテキストを表示するようにしてあり、今回はDRリージョンからゲームが配信されていることが分かります。

DRフェイルオーバー成功
まとめ
Route 53は、堅牢なDRおよび事業継続戦略を構築するうえで非常に強力なAWSのツールです。本記事ではフェイルオーバーを実現する仕組みを示しましたが、本番クラスターとDRクラスターのコード更新を同期させ続けるのは利用者側の責任です。また、上記のフェイルオーバー戦略を構築した場合は、メンテナンスウィンドウで定期的にサニティテストを実施し、本番・DRの両アプリケーションが正しく動作するかを確認する必要があります。