G-gen の藤岡です。当記事では、Google Cloud(旧称 GCP)の 2023 年 8 月にリリース された Cloud Load Balancing のクロスリージョン内部アプリケーションロードバランサを紹介します。
はじめに
Cloud Load Balancing とは
Cloud Load Balancing とは Google Cloud が提供する仮想的なロードバランサです。 以下の記事では、External Application Load Balancer だけでなく Cloud Load Balancing の内部的な仕組みについて触れていますので、当記事と併せてご参照ください。 blog.g-gen.co.jp
Cloud Load Balancing は以下の 9 種類 が提供されています。当記事では図内の Cross-region internal Application Load Balancer であるクロスリージョン内部アプリケーションロードバランサに焦点を当てています。
内部アプリケーションロードバランサとは
内部アプリケーションロードバランサ は、Envoy プロキシベースのレイヤ 7 ロードバランサで、接続元が Google Cloud 内や Cloud VPN、Cloud Interconnect で接続されたオンプレミスの他、Amazon Web Services(AWS)等からのトラフィックをバックエンドサービスへ分散します。
内部アプリケーションロードバランサは、バックエンドのタイプによってリージョンモードとクロスリージョンモードの 2 種類が提供されています。
- リージョン内部アプリケーションロードバランサ
- クロスリージョン内部アプリケーションロードバランサ(Preview 版)
リージョン内部アプリケーションロードバランサでは、バックエンドはロードバランサと同一リージョンに配置します。
バックエンドがリージョンを跨ぐ場合には、クロスリージョン内部アプリケーションロードバランサを選択します。 これによって、オフィスやデータセンター拠点から Google Cloud へ国内であれば東京(asia-northeast1)と大阪(asia-northeast2)への負荷分散やフェイルオーバーができ、単一リージョンにおける障害回避が可能になります。
クロスリージョン内部アプリケーションロードバランサがリリースされる前は、バックエンドがリージョンを跨ぐ場合には以下の記事あるように Cloud DNS による分散が候補に挙げられましたが、バックエンドに異常が発生した場合の自動フェイルオーバー機能は用意されていないため、独自に実装する必要がある等の制限がありました。
アーキテクチャ
クロスリージョン内部アプリケーションロードバランサのアーキテクチャは以下の通りです。
クロスリージョン内部アプリケーションロードバランサからバックエンドサービス (インスタンスグループやサーバレス NEG 等) へのパケットは「プロキシ専用サブネット」から送信されます。また、バックエンドサービスはヘルスチェックによってバックエンド (VM 等) の正常性を確認します。
そのため VPC ファイアウォールではそれらの通信を許可する必要があります。
実施内容
構成図
当記事で作成するリソースは以下の通りです。
前提
gcloud
コマンドでリソースを作成します。実行環境は Cloud Shell で、Google Cloud SDK バージョンは以下の通りです。
fujioka@cloudshell:~ (xxxx)$ gcloud version | grep "Google Cloud SDK" Google Cloud SDK 445.0.0 fujioka@cloudshell:~ (xxxx)$
構築
事前準備
プロジェクトの作成と請求先アカウントの紐づけ
プロジェクトを作成し、作成したプロジェクトに請求先アカウントを紐づけます。
$ gcloud projects create ${PROJECT_ID} --name=${PROJECT_NAME} --organization=${ORGANIZATION_ID} && \ gcloud beta billing projects link ${PROJECT_ID} --billing-account=${BILLING_ACCOUNT_ID}
デフォルトプロジェクトのセット
作成したプロジェクトをデフォルトプロジェクトとしてセットし、結果を確認します。
$ gcloud config set project ${PROJECT_ID} && \ gcloud config list project
API の有効化
今回の検証で必要な API を有効化します。
$ gcloud services enable compute.googleapis.com dns.googleapis.com
リソースの作成
VPC とサブネットの作成
VPC とサブネットを作成します。
# VPC の作成 $ gcloud compute networks create lb-network --subnet-mode=custom # asia-northeast1(Tokyo)にサブネットの作成 $ gcloud compute networks subnets create lb-subnet-asia-northeast1 \ --network=lb-network \ --range=10.1.2.0/24 \ --region=asia-northeast1 # asia-northeast2(Osaka)にサブネットの作成 $ gcloud compute networks subnets create lb-subnet-asia-northeast2 \ --network=lb-network \ --range=10.1.3.0/24 \ --region=asia-northeast2
プロキシ専用サブネットの作成
プロキシ専用サブネットを作成します。バックエンドサービスへのアクセスは、プロキシ専用サブネットからになるため、後述のファイアウォールの設定でプロキシ専用サブネットからのアクセスを許可する必要があります。
プロキシ専用サブネットは 64 個以上の IP アドレスが必要であり、推奨されるサブネットサイズは /23
です。
# asia-northeast1(Tokyo)にプロキシ専用サブネットの作成 $ gcloud beta compute networks subnets create proxy-only-subnet-asia-northeast1 \ --purpose=GLOBAL_MANAGED_PROXY \ --role=ACTIVE \ --region=asia-northeast1 \ --network=lb-network \ --range=10.129.0.0/23 # asia-northeast2(Osaka)にプロキシ専用サブネットの作成 $ gcloud beta compute networks subnets create proxy-only-subnet-asia-northeast2 \ --purpose=GLOBAL_MANAGED_PROXY \ --role=ACTIVE \ --region=asia-northeast2 \ --network=lb-network \ --range=10.130.0.0/23
プロキシ専用サブネットを作成すると、コンソールでは以下のように表示されます。
ファイアウォールルールの作成
3 つのファイアウォールルールを作成します。
- fw-allow-ssh:Compute Engine へ SSH 用
- fw-allow-health-check: ヘルスチェック用
- fw-allow-proxies:プロキシ専用サブネットからバックエンドサービスへのアクセス用(今回は 80/tcp)
フェイルオーバーの検証をタグの削除によるヘルスチェックの失敗で確認をするため、ファイアウォールのターゲットはタグにします。
# fw-allow-ssh $ gcloud compute firewall-rules create fw-allow-ssh \ --network=lb-network \ --action=allow \ --direction=ingress \ --source-ranges=0.0.0.0/0 \ --target-tags=allow-ssh \ --rules=tcp:22 # fw-allow-health-check $ gcloud compute firewall-rules create fw-allow-health-check \ --network=lb-network \ --action=allow \ --direction=ingress \ --source-ranges=130.211.0.0/22,35.191.0.0/16 \ --target-tags=load-balanced-backend \ --rules=tcp # fw-allow-proxies $ gcloud compute firewall-rules create fw-allow-proxies \ --network=lb-network \ --action=allow \ --direction=ingress \ --source-ranges=10.129.0.0/23,10.130.0.0/23 \ --target-tags=load-balanced-backend \ --rules=tcp:80
マネージドインスタンスグループの作成
インスタンステンプレートを作成します。
# asia-northeast1(Tokyo)にインスタンステンプレートの作成 $ gcloud compute instance-templates create gil7-backend-asia-northeast1-template \ --region=asia-northeast1 \ --network=lb-network \ --subnet=lb-subnet-asia-northeast1 \ --tags=allow-ssh,load-balanced-backend \ --image-family=debian-10 \ --image-project=debian-cloud \ --metadata=startup-script='#! /bin/bash apt-get update apt-get install apache2 -y a2ensite default-ssl a2enmod ssl vm_hostname="$(curl -H "Metadata-Flavor:Google" \ http://169.254.169.254/computeMetadata/v1/instance/name)" echo "Page served from: $vm_hostname" | \ tee /var/www/html/index.html systemctl restart apache2' # asia-northeast2(Osaka)にインスタンステンプレートの作成 $ gcloud compute instance-templates create gil7-backend-asia-northeast2-template \ --region=asia-northeast2 \ --network=lb-network \ --subnet=lb-subnet-asia-northeast2 \ --tags=allow-ssh,load-balanced-backend \ --image-family=debian-10 \ --image-project=debian-cloud \ --metadata=startup-script='#! /bin/bash apt-get update apt-get install apache2 -y a2ensite default-ssl a2enmod ssl vm_hostname="$(curl -H "Metadata-Flavor:Google" \ http://169.254.169.254/computeMetadata/v1/instance/name)" echo "Page served from: $vm_hostname" | \ tee /var/www/html/index.html systemctl restart apache2'
インスタンステンプレートを使って、マネージドインスタンスグループを作成します。
# asia-northeast1(Tokyo)にインスタンスグループの作成 $ gcloud compute instance-groups managed create l7-ilb-backend-asia-northeast1 \ --zone=asia-northeast1-a \ --size=2 \ --template=gil7-backend-asia-northeast1-template # asia-northeast2(Osaka)にインスタンスグループの作成 $ gcloud compute instance-groups managed create l7-ilb-backend-asia-northeast2 \ --zone=asia-northeast2-a \ --size=2 \ --template=gil7-backend-asia-northeast2-template
クロスリージョン内部アプリケーションロードバランサの作成
ヘルスチェックを作成します。
ここでは HTTP ヘルスチェックを作成しますが、クロスリージョン内部アプリケーションロードバランサでは他にも TCP、SSL、HTTPS 等もサポートしています。
# HTTP ヘルスチェックの作成 $ gcloud compute health-checks create http gil7-basic-check \ --use-serving-port \ --global
- 参考:ヘルスチェックの概要
バックエンドサービスを定義します。
ロギングはバックエンドサービス単位で有効にできます。ロギングはトラブルシューティング時に有用です。
$ gcloud compute backend-services create gil7-backend-service \ --load-balancing-scheme=INTERNAL_MANAGED \ --protocol=HTTP \ --enable-logging \ --logging-sample-rate=1.0 \ --health-checks=gil7-basic-check \ --global-health-checks \ --global
バックエンドサービスにインスタンスグループを追加します。
# asia-northeast1(Tokyo)にインスタンスグループをバックエンドに追加 $ gcloud compute backend-services add-backend gil7-backend-service \ --balancing-mode=UTILIZATION \ --instance-group=l7-ilb-backend-asia-northeast1 \ --instance-group-zone=asia-northeast1-a \ --global # asia-northeast2(Osaka)にインスタンスグループをバックエンドに追加 $ gcloud compute backend-services add-backend gil7-backend-service \ --balancing-mode=UTILIZATION \ --instance-group=l7-ilb-backend-asia-northeast2 \ --instance-group-zone=asia-northeast2-a \ --global
URL マップを作成します。
$ gcloud compute url-maps create gil7-map \ --default-service=gil7-backend-service \ --global
ターゲットプロキシを作成します。
$ gcloud compute target-http-proxies create gil7-http-proxy \ --url-map=gil7-map \ --global
今回はターゲットプロキシを HTTP としていますが、HTTPS で DNS 認証を使う場合、以下の記事を参考にしてください。 blog.g-gen.co.jp
フォワーディングルールを作成します。
# asia-northeast1(Tokyo) $ gcloud compute forwarding-rules create gil7-forwarding-rule-asia-northeast1 \ --load-balancing-scheme=INTERNAL_MANAGED \ --network=lb-network \ --subnet=lb-subnet-asia-northeast1 \ --subnet-region=asia-northeast1 \ --address=10.1.2.99 \ --ports=80 \ --target-http-proxy=gil7-http-proxy \ --global # asia-northeast2(Osaka) $ gcloud compute forwarding-rules create gil7-forwarding-rule-asia-northeast2 \ --load-balancing-scheme=INTERNAL_MANAGED \ --network=lb-network \ --subnet=lb-subnet-asia-northeast2 \ --subnet-region=asia-northeast2 \ --address=10.1.3.99 \ --ports=80 \ --target-http-proxy=gil7-http-proxy \ --global
クロスリージョン内部アプリケーションロードバランサはコンソールで見た時に、「リージョン」が空欄になるのに対し、リージョン内部アプリケーション ロードバランサは属するリージョンが表示されます。
- 参考:モードの識別
検証クライアントの作成
検証クライアントとして、Compute Engine インスタンスを作成します。
# asia-northeast1(Tokyo) $ gcloud compute instances create l7-ilb-client-asia-northeast1-a \ --image-family=debian-10 \ --image-project=debian-cloud \ --network=lb-network \ --subnet=lb-subnet-asia-northeast1 \ --zone=asia-northeast1-a \ --tags=allow-ssh \ --metadata=startup-script='#!/bin/bash apt-get update apt-get install -y dnsutils' # asia-northeast2(Osaka) gcloud compute instances create l7-ilb-client-asia-northeast2-a \ --image-family=debian-10 \ --image-project=debian-cloud \ --network=lb-network \ --subnet=lb-subnet-asia-northeast2 \ --zone=asia-northeast2-a \ --tags=allow-ssh \ --metadata=startup-script='#!/bin/bash apt-get update apt-get install -y dnsutils'
フェイルオーバーとフェイルバックの検証
正常時のトラフィック
検証クライアントからクロスリージョン内部アプリケーションロードバランサ(10.1.2.99
/ 10.1.3.99
)へ 100 個のリクエストをし、負荷分散されていることを確認します。
インスタンス名は l7-ilb-backend-<リージョン名>-<乱数>
です。
以下のように、各リージョンのバックエンドの 2 インスタンスへトラフィックが分散されていることがわかります。
# asia-northeast1 のインスタンスグループへ分散 fujioka@l7-ilb-client-asia-northeast1-a:~$ { > RESULTS= > for i in {1..100} > do > RESULTS="$RESULTS:$(curl --silent 10.1.2.99)" > done > echo "" > echo " Results of load-balancing to 10.1.2.99: " > echo "***" > echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -c > echo > } Results of load-balancing to 10.1.2.99: *** 49 l7-ilb-backend-asia-northeast1-cn22 51 l7-ilb-backend-asia-northeast1-pdtr 100 Page served from fujioka@l7-ilb-client-asia-northeast1-a:~$
# asia-northeast2 のインスタンスグループへ分散 fujioka@l7-ilb-client-asia-northeast2-a:~$ { > RESULTS= > for i in {1..100} > do > RESULTS="$RESULTS:$(curl --silent 10.1.3.99)" > done > echo "" > echo " Results of load-balancing to 10.1.3.99: " > echo "***" > echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -c > echo > } Results of load-balancing to 10.1.3.99: *** 49 l7-ilb-backend-asia-northeast2-088t 51 l7-ilb-backend-asia-northeast2-zqtx 100 Page served from fujioka@l7-ilb-client-asia-northeast2-a:~$
フェイルオーバー
asia-northeast1 のバックエンドのインスタンスグループに付与された load-balanced-backend
タグを削除します。これによってファイアウォールのタグで許可されていたヘルスチェックのアクセスが拒否されるため、ヘルスチェックが失敗し asia-northeast1 のインスタンスグループへトラフィックが流れなくなります。
# l7-ilb-backend-asia-northeast1-cn22 からタグを削除 $ gcloud compute instances remove-tags l7-ilb-backend-asia-northeast1-cn22 \ --zone=asia-northeast1-a \ --tags=load-balanced-backend # l7-ilb-backend-asia-northeast1-pdtr からタグを削除 $ gcloud compute instances remove-tags l7-ilb-backend-asia-northeast1-pdtr \ --zone=asia-northeast1-a \ --tags=load-balanced-backend
タグの削除により、ヘルスチェックが失敗しています。
この状態で再度クロスリージョン内部アプリケーションロードバランサ(10.1.2.99
/ 10.1.3.99
)へ 100 個のリクエストをすると、10.1.2.99
へのリクエストは asia-northeast1 のバックエンドではなく、asia-northeast2 のバックエンドへトラフィックが流れるようになります。
# asia-northeast2 のインスタンスグループへトラフィックが流れるようになる fujioka@l7-ilb-client-asia-northeast1-a:~$ { > RESULTS= > for i in {1..100} > do > RESULTS="$RESULTS:$(curl --silent 10.1.2.99)" > done > echo "" > echo " Results of load-balancing to 10.1.2.99: " > echo "***" > echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -c > echo > } Results of load-balancing to 10.1.2.99: *** 51 l7-ilb-backend-asia-northeast2-088t 49 l7-ilb-backend-asia-northeast2-zqtx 100 Page served from fujioka@l7-ilb-client-asia-northeast1-a:~$
# asia-northeast2 のインスタンスグループへ分散 fujioka@l7-ilb-client-asia-northeast2-a:~$ { > RESULTS= > for i in {1..100} > do > RESULTS="$RESULTS:$(curl --silent 10.1.3.99)" > done > echo "" > echo " Results of load-balancing to 10.1.3.99: " > echo "***" > echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -c > echo > } Results of load-balancing to 10.1.3.99: *** 51 l7-ilb-backend-asia-northeast2-088t 49 l7-ilb-backend-asia-northeast2-zqtx 100 Page served from fujioka@l7-ilb-client-asia-northeast2-a:~$
フェイルバック
タグを再度付与し、ヘルスチェックが成功後のトラフィックを確認します。
# タグを付与 $ gcloud compute instances add-tags l7-ilb-backend-asia-northeast1-cn22 --tags=load-balanced-backend --zone=asia-northeast1-a && gcloud compute instances add-tags l7-ilb-backend-asia-northeast1-pdtr --tags=load-balanced-backend --zone=asia-northeast1-a
10.1.2.99
へのトラフィックが元通り asia-northeast2 ではなく、asia-northeast1 のバックエンドに流れていることがわかります。
fujioka@l7-ilb-client-asia-northeast1-a:~$ { > RESULTS= > for i in {1..100} > do > RESULTS="$RESULTS:$(curl --silent 10.1.2.99)" > done > echo "" > echo " Results of load-balancing to 10.1.2.99: " > echo "***" > echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -c > echo > } Results of load-balancing to 10.1.2.99: *** 51 l7-ilb-backend-asia-northeast1-cn22 49 l7-ilb-backend-asia-northeast1-pdtr 100 Page served from fujioka@l7-ilb-client-asia-northeast1-a:~$
実際の運用では Cloud DNS のルーティングポリシーも併せて使うことで、バックエンドのサービス停止だけでなく、リージョン停止やレイテンシ、ネットワーク転送費用を抑えることもできます。
藤岡 里美 (記事一覧)
クラウドソリューション部
数年前までチキン売ったりドレスショップで働いてました!2022年9月 G-gen にジョイン。ハイキューの映画を4回は見に行きたい。
Google Cloud All Certifications Engineer / Google Cloud Partner Top Engineer 2024
Follow @fujioka57621469