マルチリージョンKubernetes:K8gbによるグローバル負荷分散の実践ガイド

DevOps tutorial - IT technology blog
DevOps tutorial - IT technology blog

リージョン障害という悪夢

標準的なKubernetes Ingressコントローラーは、ローカルのトラフィックを完璧に処理します。しかし、US-East-1のようなクラウドリージョン全体がダウンした場合、ローカルのIngressは行き止まりになってしまいます。インフラがUS-EastやEU-Westといった地理的境界をまたいでいる場合、クラスターの健全性をリアルタイムで監視し、DNSレベルでトラフィックを制御する方法が必要です。

長年、グローバルサーバー負荷分散(GSLB)は、F5 BIG-IPのような高価なハードウェアや、AWS Route53のようなプロプライエタリなクラウドサービスの中に閉じ込められてきました。これらのツールは、Kubernetesネイティブなワークフローにおいては異物のように感じられることがよくあります。K8gbはそれを変えます。これは、既存のCoreDNSを、コードと同じ場所で動作するグローバル分散型ロードバランサーへと変貌させるオープンソースのオペレーターです。

なぜK8gbが従来のGSLBよりも優れているのか

ほとんどのGSLBソリューションは、障害発生時にDNSレコードを更新するために手動のAPIコールや煩雑な統合を必要とします。K8gbは、Kubernetesのオペレーターパターンを使用することでこれを回避します。クラスターをまたいでアプリケーションの健全性を常に監視し、例えばロンドンのサービスが失敗した場合、K8gbは自動的にDNSレスポンスを書き換え、ユーザーをニューヨークへ誘導します。

ベンダーロックインの心配もありません。一つのクラスターをGKEで、もう一つをオンプレミスで、三つ目をAWSで実行することも可能です。K8gbはそれらの間に軽量なメッシュを作成し、健全性ステータスを共有します。私の本番環境でのテストでは、このセットアップは静的なDNSの重み付けよりもはるかに適切にリージョン間のレイテンシスパイクを処理し、多くの場合10秒未満でフェイルオーバーをトリガーしました。

マルチリージョンメッシュの構築

この魔法のような仕組みを確認するには、少なくとも2つのKubernetesクラスターが必要です。本ガイドでは、cluster-eucluster-usを使用します。各クラスターには、パブリックに公開されたLoadBalancerサービス、またはアクセス可能なIPアドレスが必要です。

事前準備

  • 2つのアクティブなKubernetesクラスター (v1.24以上)。
  • ローカルマシンにインストールされたHelm。
  • Route53、Cloudflare、または同様のプロバイダーで管理されているドメイン(例:example.com)。

HelmによるK8gbのインストール

両方のクラスターを通信させるために、両方でインストールを実行する必要があります。K8gbはCoreDNSの上で動作するため、公式のHelmチャートを使用してデプロイします。各サイトには、その場所を識別するためのユニークなgeo-tag(地理タグ)が必要です。

# EUクラスターへのデプロイ
helm repo add k8gb https://www.k8gb.io
helm repo update

helm install k8gb k8gb/k8gb \
  --namespace k8gb \
  --create-namespace \
  --set k8gb.clusterGeoTag="eu" \
  --set k8gb.extGslbClustersGeoTags="us" \
  --set k8gb.edgeDNSZone="example.com" \
  --set k8gb.edgeDNSServers="8.8.8.8"

次に、コンテキストをUSクラスターに切り替えて同じコマンドを実行しますが、タグを入れ替えます。

# USクラスターへのデプロイ
helm install k8gb k8gb/k8gb \
  --namespace k8gb \
  --create-namespace \
  --set k8gb.clusterGeoTag="us" \
  --set k8gb.extGslbClustersGeoTags="eu" \
  --set k8gb.edgeDNSZone="example.com" \
  --set k8gb.edgeDNSServers="8.8.8.8"

K8gbは内部でExternalDNSを使用しています。メインのDNSプロバイダーにNS(ネームサーバー)レコードを作成し、gslb.example.comのようなサブドメインの権限を、クラスター内で実行されているK8gbインスタンスに効果的に委任します。

トラフィック戦略の定義

手動のDNSレコード管理はもう不要です。オペレーターが起動すれば、Gslbカスタムリソースを使用してトラフィックを制御できます。ニーズに応じて、RoundRobinFailoverGeoIPの戦略から選択できます。

フェイルオーバー戦略

フェイルオーバーは、データベースを多用するアプリケーションにとって最も安全な選択肢です。プライマリ(Primary)リージョンを指定し、プライマリが完全に到達不能になった場合にのみセカンダリ(Secondary)にトラフィックをルーティングします。これにより、リージョンをまたぐレプリケーションの遅延によって引き起こされるデータ整合性の問題を回避できます。

# failover-strategy.yaml
apiVersion: k8gb.absa.oss/v1beta1
kind: Gslb
metadata:
  name: my-app-gslb
  namespace: my-app
spec:
  strategy:
    type: failover
    primaryGeoTag: eu
  ingress:
    rules:
      - host: app.gslb.example.com
        http:
          paths:
          - path: /
            backend:
              serviceName: my-app-service
              servicePort: 80

これを両方のクラスターに適用します。K8gbは共有ホストapp.gslb.example.comを検出します。euがプライマリであるため、それらのPodが健全である限り、DNSクエリはEUのLoadBalancerのIPを返します。

ラウンドロビン戦略

ステートレスなマイクロサービスにはroundRobinが適しています。この戦略では、負荷を分散するためにすべてのリージョンにユーザーを振り分けます。グローバルなユーザーベースに対してパフォーマンスを向上させるためのシンプルな方法です。

spec:
  strategy:
    type: roundRobin

このモードでは、K8gbは両方のクラスターからIPアドレスを返します。クライアントのDNSリゾルバーは、それらを自動的に循環させて利用します。

検証と本番環境のモニタリング

GSLBのテストには、考え方の転換が必要です。単にHTTPステータスコードをチェックするだけでなく、DNSレスポンスを監視します。digツールを使用して、どのクラスターがリクエストに回答しているかを確認します。

# K8gbのDNSインスタンスに直接クエリを実行
dig @<K8GB_SERVICE_IP> app.gslb.example.com

障害のシミュレーションを試してみましょう。プライマリのデプロイメントをゼロにスケールダウンします。およそ10秒から30秒以内に、K8gbのヘルスチェックがEUサイトをダウンとしてフラグを立てます。再度digを実行すると、即座にUSクラスターのIPアドレスが表示されるはずです。

本番環境ではオブザーバビリティ(可観測性)が不可欠です。K8gbはデフォルトでPrometheusにメトリクスをエクスポートします。以下の3つの主要な領域を監視するために、Grafanaダッシュボードを構築することをお勧めします。

  • リージョンの健全性 (k8gb_gslb_status): USクラスターはEUクラスターを「Up」として認識しているか?
  • 解決レイテンシ: CoreDNSインスタンスは20ミリ秒未満で応答しているか?
  • エッジ同期エラー: Route53やCloudflareのAPIレート制限に達していないか?

私の経験では、K8gbのレベルでセットアップが失敗することはほとんどありません。ほとんどの問題は「エッジDNS」の設定に起因します。親ドメインのNSレコードがK8gbのLoadBalancer IPを正しく指していない場合、トラフィックの制御は開始される前に失敗します。グローバルなトラフィックルールをコードとして扱うことで、現代の分散システムが求めるレジリエンスを実現できるでしょう。

Share: