
Cloud Run のサービスを自前ドメインでデプロイしてみる
はじめに
Cloud Run を使って Web サービスなどをデプロイするとき、自前のドメインでアクセスできるようにしたい時が必ず来ると思います。そのときに備えて、Cloud Run を自前のドメインからアクセスする方法を試してみました。
補足: 今回はロードバランサーのパターンでの紹介
なお、今回はロードバランサーを利用するパターンの紹介をします。Cloud Run には "ドメインマッピング" という標準機能がありますが、この機能はプレビュー段階です。
ドキュメントには以下のような記述があり、本番環境での利用は非推奨となっています。
Cloud Run のドメイン マッピングは、プレビュー リリース ステージです。レイテンシの問題で本番環境に対応していないため、一般提供ではサポートされていません。現時点では、このオプションは本番環境のサービスにはおすすめしません。
https://docs.cloud.google.com/run/docs/mapping-custom-domains?hl=ja#run
今回は本番環境でも利用できる手順としてロードバランサーを経由させる方式で紹介します。
やること
- 準備
- Cloud Run のサービス作成
- ドメイン取得
- グローバル静的IPの予約
- ドメインを Cloud Run 接続するための設定
- Aレコードの追加&SSL証明書の作成
- 証明書マップの作成
- サーバーレスNEGの作成
- バックエンドサービスの作成と紐付け
- ルーティングの設定(URLマップ / HTTPSプロキシ / 転送ルール)
- 動作確認
準備
まず、事前の準備を進めていきます。
Cloud Run サービスの作成
まず、事前準備として Cloud Run サービスを作成しておきます。
今回は、以前ブログの検証で使った以下のサービスをデプロイしていきます。

ドメインの取得
独自ドメインを取得し、レコードの編集が可能な状態にしておきます。
なお、今回はドメインの管理を AWS の Route53 で実施しているため、ドメイン操作のみ Route53 で設定します。
グローバル静的IPの予約
以下のコマンドを実行し、グローバル静的IPを予約します。
gcloud compute addresses create custom-domain-lb-ip \
--network-tier=PREMIUM \
--ip-version=IPV4 \
--global
コマンドが成功すると、以下のように IPアドレスの画面で静的外部IPが予約されたことが確認できます。

実際の設定
続いて、ネットワーク周りの設定を進めていきます。
Aレコードの追加&ドメイン紐付け
まず、先ほど取得したグローバル静的IPアドレスを、ドメインの Aレコードに追加します。

続いて、ドメインに対する証明書を取得します。
gcloud certificate-manager certificates create nextjs-cloudrun-cert \
--domains=<ドメイン>
完了すると以下のようになります。
なお、デフォルトだとロードバランサー認証になります。これは、「ドメインのAレコードがロードバランサーのIPアドレスを指しているか」を確認します。そのため、ロードバランサーの設定を完了させるまでプロビジョニングも完了しません。注意してください。

証明書マップの作成
Certificate Manager を使って、証明書マップを作成します。 <ドメイン> の部分は、ご自身のドメインに差し替えてください。
# 証明書マップの作成
gcloud certificate-manager maps create nextjs-cloudrun-cert-map
# 証明書マップに証明書を紐付け
gcloud certificate-manager maps entries create nextjs-cloudrun-cert-map-entry \
--map=nextjs-cloudrun-cert-map \
--certificates=nextjs-cloudrun-cert \
--hostname=<ドメイン>
サーバーレスNEGの作成
サーバーレスNEGを作成します。
サーバーレスNEG は、ロードバランサの宛先を定義するリソースです。名前に「サーバーレス」と入っている通り、Cloud Run や App Engine などのサーバーレスサービスを宛先として指定できます。
以下のコマンドを実行してサーバーレスNEGを作成しましょう。
gcloud compute network-endpoint-groups create nextjs-cloudrun-neg \
--region=asia-northeast1 \
--network-endpoint-type=serverless \
--cloud-run-service=nextjs-cloudrun-deploy-app
完了すると、Compute Engine > ネットワークエンドポイントグループ から、以下のようにサーバーレスNEGが作成されたことが確認できます。

バックエンドサービスの作成と紐付け
次に、バックエンドサービスを作成します。バックエンドサービスは、ルールに基づいてリクエストをどのエンドポイントグループに送るかを定義するリソースです。
今回は、特にルールや宛先の細かい制御はせず、すべてのリクエストを先ほど作成した1つのNEGに対して送信する構成を取ります。
# バックエンドサービス自体の作成
gcloud compute backend-services create nextjs-cloudrun-backend \
--load-balancing-scheme=EXTERNAL_MANAGED \
--global
# バックエンドと先ほど作成したNEGを紐付け
gcloud compute backend-services add-backend nextjs-cloudrun-backend \
--global \
--network-endpoint-group=nextjs-cloudrun-neg \
--network-endpoint-group-region=asia-northeast1
完了すると、ネットワークサービス > ロードバランシング > バックエンド から、以下のようにバックエンドサービスが確認できます。

また、クリックして詳細を確認すると、先ほどのNEGとの関連付けも確認できます。

ルーティングの設定
次に、リクエストをロードバランサが受けられるよう、フロントエンドを設定していきます。フロントエンドという名前ですが、ロードバランサが「どのIP」の「どのポートで待ち受けるか」と「そのオプション」を定義する部分になります。
今回は、事前に予約したグローバル静的IPに対する443ポートのリクエスト受信時に SSL 証明書が適用されるよう設定をしていきます。
# URLマップ
gcloud compute url-maps create nextjs-cloudrun-urlmap \
--default-service=nextjs-cloudrun-backend
# ターゲットHTTPSプロキシ
gcloud compute target-https-proxies create nextjs-cloudrun-https-proxy \
--certificate-map=nextjs-cloudrun-cert-map \
--url-map=nextjs-cloudrun-urlmap \
--global
# 転送ルール(手順3で予約した静的IPを指定)
gcloud compute forwarding-rules create nextjs-cloudrun-https-rule \
--load-balancing-scheme=EXTERNAL_MANAGED \
--network-tier=PREMIUM \
--address=custom-domain-lb-ip \
--target-https-proxy=nextjs-cloudrun-https-proxy \
--global \
--ports=443
この設定が終わった段階で、 ドメインのAレコードが Google Cloud のロードバランサーを指すようになります。
この状態から数分待つと、以下のようにプロビジョニングが完了します。

動作確認
SSL 証明書のプロビジョニングが完了したら、実際にドメインにアクセスしてみます。
今回の Cloud Run サービスには Next.js のデフォルトのアプリケーションがデプロイされているので、問題なく動作していることが確認できました。

終わりに
以上、Cloud Run サービスに対して、自前ドメインでのアクセスを設定する方法を試してみました。
ロードバランサーを噛ませることで、証明書やルーティング周りの設定などが必要になるため少し複雑でしたが、その分1つ1つの設定項目の理解も深まったので、良い経験でした。
今回はロードバランサーの証明書を使ったことでDNSにはAレコードのみの設定でSSL証明書まで設定できました。ただ、ドメイン証明には CNAME レコードを使った証明の方法もあり、こちらはLBが存在しなくても証明書が利用できるので、環境次第ではこちらの方が融通が利きやすいケースもあります。環境に応じて、使い分けてみましょう。
以上、この記事がどなたかの助けになれば幸いです。以上、すらぼでした!




