🐡

Google Cloud RunにLoadBalancerを設定してカスタムドメインを適用する話

2024/01/03に公開

こんにちは、育休ニートのzabroxです。

現在私は以下2つのGoogle Cloud Runサービスで構成されたWebアプリケーションを構築しています。

  1. Reactで構成されたClientサイド用のmyapp-clientサービス
  2. FirestoreやGCS上のデータをサーブするAPI用のmyapp-api-serverサービス

Cloud Runのサービスにはそれぞれ独自にURLが与えられますが、1つのドメインに統一されているとすっきりするので、カスタムドメインを設定したいと思い立ちました。

そこに至るまでに予想以上の長い道のりが待っていたため、Shareします。

Version Info

Google Cloud SDK 455.0.0
bq 2.0.98
bundled-python3-unix 3.11.6
core 2023.11.10
gcloud-crc32c 1.0.0
gsutil 5.27

Load Balancer設定

カスタムドメインを設定するためには、Load Balancer設定をする必要があります。

今回はURLのpath mappingを行い、/*のトラフィックはmyapp-clientに、/app/*はmyapp-api-serverに転送されるよう設定します。

SSL 証明書にはGoogleマネージドSSL証明書サービスを利用します。

最終的にforwarding-ruleに対してIPアドレスが割り当てられることになり、そのIPアドレスをDNSのAレコードに追加することになります。

目指すべき状態:

こちらの公式ドキュメントをベースに設定を進めます。

またこちらの素晴らしい記事も参考(というかほぼコピー?)にさせていただいています。

NEGの作成

まずはNEG(Network Endpoint Group)の作成です。2つのCloud Runサービスそれぞれに対して作成します。

gcloud compute network-endpoint-groups create myapp-client-neg --region=us-central1 --network-endpoint-type=serverless --cloud-run-service=myapp-client
gcloud compute network-endpoint-groups create myapp-api-server-neg --region=us-central1 --network-endpoint-type=serverless --cloud-run-service=myapp-api-server

Backend Serviceの作成

作成したNEGをBackendServiceに登録します。

myapp-client用

gcloud compute backend-services create myapp-backend --global
gcloud compute backend-services add-backend myapp-backend --global --network-endpoint-group=myapp-client-neg --network-endpoint-group-region=us-central1

myapp-api-server用

gcloud compute backend-services create myapp-api-server-backend --global
gcloud compute backend-services add-backend myapp-api-server-backend --global --network-endpoint-group=myapp-api-server-neg --network-endpoint-group-region=us-central1

URL Mapの作成

Backend Serviceが1つの場合は特に設定する必要がありませんが、今回は/*をmyapp-clientに、/app/*をmyapp-api-serverに転送するように、path matching ruleを定義します

hostRules:
- hosts:
  - '*'
  pathMatcher: path-matcher-1
kind: compute#urlMap
name: myapp-url-map
defaultService: https://www.googleapis.com/compute/v1/projects/<PROJECT ID>/global/backendServices/myapp-backend
pathMatchers:
- defaultService: https://www.googleapis.com/compute/v1/projects/<PROJECT ID>/global/backendServices/myapp-backend
  name: path-matcher-1
  pathRules:
  - paths:
    - /api/*
    service: https://www.googleapis.com/compute/v1/projects/<PROJECT ID>/global/backendServices/myapp-api-server-backend

URL Mapオブジェクトを作成し、ymlをimportします。

gcloud compute url-maps create myapp-url-map --default-service=myapp-backend
gcloud compute url-maps import myapp-url-map --global --source=./url-map.yml

証明書の設定

Googleマネージド証明書を利用する場合は以下のコマンドで作成します。

gcloud compute ssl-certificates create myapp-certificate --domains <MY DOMAIN>

HTTPS Proxyの作成

作成したURL Mapと証明書を利用してHTTPS Proxyを作成します。

gcloud compute target-https-proxies create myapp-https-proxy \
  --ssl-certificates=myapp-certificate \
  --url-map=myapp-url-map

Forwarding Ruleの作成

最後にForwarding Ruleを追加し、Load Balancerの設定が完了です。

gcloud compute forwarding-rules create myapp-forwarding-rule \
  --target-https-proxy=myapp-https-proxy \
  --global \
  --ports=443

カスタムドメイン設定

Forwarding Ruleをlistすると以下のような出力が得られます。

NAME                         REGION  IP_ADDRESS     IP_PROTOCOL  TARGET
myapp-forwarding-rule                <forwarding ruleに割り当てられたIP>    TCP          myapp-https-proxy

ここで表示されたIPアドレスを、お使いのドメインサービスのAレコードに設定して完了です

余談

カスタムドメインについて調査していて最初に行き当たったのがこちらの公式ドキュメントでした。
どうやらbeta版では--serverless-deployment-xxxのオプションが追加されているようで、gcloudのhelpには以下のような記載があります。

 --serverless-deployment-resource=SERVERLESS_DEPLOYMENT_RESOURCE
            The user-defined name of the workload/instance. This value must be
            provided explicitly or using the --serverless-deployment-url-mask
            option. The resource identified by this value is platform-specific
            and is as follows:

            ▫ API Gateway: The gateway ID
            ▫ App Engine: The service name
            ▫ Cloud Functions: The function name
            ▫ Cloud Run: The service name

Cloud Runサービスなどだけではなく、API Gatewayが指定可能になっています。
API Gatewayにはapi-configにpath matcherを指定することができ、URL MapだけでなくAPI Gatewayの中でもさらにmatchingできるようになるということなのかもしれません。
URL Mapで荒い粒度の振り分けを行い、API Gatewayで細かな制御を行うというユースケースなのだろうか。

Discussion