
Cloud Load Balancer × Cloud Runの3-Tier構成で構築してみた
今回は、Google Cloud(GCP)の「Cloud Load Balancer」「Cloud Storage」「Cloud Run 」「Cloud SQL」を使ってWebアプリケーションを構築してみました。
設計は、以下のGoogle Cloud Japanさんの記事内で紹介されている「Web アプリケーション + API の 3-Tier 構成 (SPA)」を参考にしました。

SPA (Single Page Application) がフロントになり、バックエンドの API サーバーとして Cloud Run を使用するアーキテクチャです。SPA は Next.js > や Vue.js、Angular などを想定していただければ良いかと思います。
SPA は静的コンテンツになるので Cloud Storage に置き、Cloud Storage と Cloud Run を Application Load Balaner にひとまとめにします。こうす> ることでドメインが同一かつパスで切り替えるといった構成が取れ、CORS (Cross Origin Resource Sharing) の必要がありません。
Cloud SQL
RDB部分は、Cloud SQLを使用しました。
今回は、Cloud SQLを使いましたが、個人開発や小規模なプロジェクトでは、サービスの規模が大きくなるまで、Firestoreあたりを使う方が費用の面を考えると良さそうです。
Instanceの設定


以下の記事を参考に、練習のためスペックなどは一旦無視して安く仕上がる設定にしてあります。
ローカルのPCからからCloud SQLに接続するためには、以下のコマンドを実行します。
# connect to cloud sql
cloud_sql_proxy -dir=/cloudsql -instances=[PROJECT_NAME]:[REGION 例:us-central1]:main=tcp:0.0.0.0:1234 -credential_file=[CREDENCIAL_JSON_FILE]
cloudsql-proxyをインストールしていない場合は、ホームディレクトリで以下のコマンドを実行してインストールします。
curl -o cloud-sql-proxy https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.1.2/cloud-sql-proxy.darwin.amd64
# 権限を付与
chmod 744 cloud-sql-proxy
Cloud Run
さて続いては、APIサーバーを動かすCloud Runを設定していきます。
Cloud Runには、Artifact Registryにデプロイされたサーバーを設定します。
Artifact Registoryへのデプロイ
Google Cloudのプロジェクトにログインしていない場合は、以下のコマンドを実行してログインします。
gcloud auth login
こうするとよくあるGoogleアカウントの選択画面が表示されるので、Google Cloudで使用しているアカウントを選択しましょう。
初回は、以下のコマンドで、プロジェクトを設定します。
gcloud auth set project [PROJECT_ID]
gcloud auth configure-docker
gcloud auth [REGION 例:asia-northeast1]
cat [CREDENCIAL_JSON_FILE] | docker login -u _json_key_base64 --password-stdin https://[REGION]-docker.pkg.dev
Dockerイメージをビルドするためには、以下のコマンドを実行します。
docker build --platform linux/amd64 -t [REGION]-docker.pkg.dev/tube-ai/main/image:latest -f Dockerfile .
ビルドが成功したら、以下のコマンドを実行して、DockerイメージをGoogle CloudのArtifact Registryにプッシュします。
docker push [REGION]-docker.pkg.dev/[PROJECT_NAME]/main/image:latest
デフォルトのコールドスタートの場合は、立ち上がりに時間がかかるため、定期的にアクセスされるような場合は、Cloud Runのコールドスタートの時間を考慮する必要があります。
Cloud Runは、デプロイしただけ時点では、外部からpublicにアクセスできてしまうため、Cloud Load Balancerを使って、外部からアクセスを制限する必要があります。
Cloud Runの設定


毎回手動でビルドしてデプロイするのは面倒なので、Cloud Buildを使ってGithubのRepositoryへPushする度に自動でビルドすることもできます。
Cloud Storage
Cloud Storageでは、フロントエンドの部分をアップロードします。
今回は、NextjsでbuildとexportをしたものをStorageに置いています。


ビルドしたのを各フォルダやファイルごとにアップロードするのは大変なので、package.jsonに以下のコマンドを追加して、ビルドしたファイルをアップロードするようにしました。
"deploy": "rm -rf dist&&rm -rf output && next build && next export && gcloud storage cp out/* gs://[STORAGE_NAME] --recursive"
Cloud Load Balancer
これまでデプロイしてきたCloud RunのサーバーとCloud Storageの静的コンテンツをApplication Load Balancerに繋ぎます。
Cloud Runのサーバーを設定

Storageのバケットを設定

CDNの設定

まとめ
今回は、Cloud Load Balancer × Cloud Storage × Cloud Run × Cloud SQLの3-Tier構成でWebアプリケーションを構築してみました。
この構成を実際に使用する場合は、各サービスの設定やセキュリティについても考慮する必要がありますが、練習としては良いかと思います。
例えば、Cloud Load BalancerにCloud Armorを使ってDDoS攻撃から保護するなど、Cloud Storageのアクセス権限を設定するなど、セキュリティについても考慮する必要があります。