Cloud RunのサーバーレスVPCアクセスをDirect VPC Egressに安全に切り替える

記事タイトルとURLをコピーする

G-gen の佐々木です。当記事では、Cloud Run サービスが VPC に接続する際に使用するサーバーレス VPC アクセスを Direct VPC Egress に置き換える方法を解説します。

Cloud Run から VPC にトラフィックを送信する方法

サーバーレス VPC アクセスと Direct VPC Egress

Cloud Run のコンテナインスタンスは VPC の外で実行されます。しかし Cloud SQL、AlloyDB、Memorystore のような VPC リソースにプライベートネットワーク経由でアクセスしたい場合など、VPC に接続する必要があるケースが存在します。

このようなケースでは、VPC にサーバーレス VPC アクセス もしくは Direct VPC Egress を構成して、Cloud Run から VPC への送信トラフィックを中継させることで実現可能です。

サーバーレス VPC アクセスおよび Direct VPC Egress を使用する構成の詳細や、それぞれの比較については以下の記事をご一読ください。

blog.g-gen.co.jp

Direct VPC Egress を採用するケース

サーバーレス VPC アクセスは Direct VPC Egress よりも以前から提供されていた機能であり、Cloud Run から接続する サーバーレス VPC アクセス コネクタ というインスタンス(以下、コネクタインスタンス と呼びます)を VPC に作成します。このコネクタインスタンスの実体は VPC 上に起動する Compute Engine 仮想マシンのため、コネクタインスタンスが起動している時間ぶんの料金が発生します。

コネクタインスタンスは 2~10 台の範囲でスケールアウトすることができますが、一度スケールアウトするとスケールインすることができず、台数を減らしたい場合はサーバーレス VPC アクセスを再作成する必要があります(参考)。

仮想マシンの料金はコネクタインスタンスの台数ぶん発生してしまうため、コスト削減のために可能な限り台数を少なくしたいところですが、トラフィックのスパイクで一時的にスケールアウトするようなケースがあっても、台数を減らすには再作成が必要となります。

上記の理由から、常時起動のインスタンスが存在せず、柔軟にスケーリングする Direct VPC Egress のほうがコストメリットがあります。

また、Direct VPC Egress はサーバーレス VPC アクセスよりも低レイテンシ、高スループットのネットワークパフォーマンスが期待できます。そのため、Cloud Run から VPC への接続は、基本的には Direct VPC Egress の使用が推奨されます。

サーバーレス VPC アクセスを採用するケース

Direct VPC Egress にはいくつかの制限事項があるため、制限に抵触してしまう場合はサーバーレス VPC アクセスを使用することになります。

たとえば、Cloud Run で第2世代の実行環境を使用する場合、VPC への接続に Direct VPC Egress を使用すると、コールドスタートの時間が長くなる可能性があります。検証のうえ、コールドスタートによる影響が許容できない場合はサーバーレス VPC アクセスを採用することになります。

また Direct VPC Egress では、Cloud Run の最大コンテナインスタンス数の4倍の IP アドレスを Direct VPC Egress 用に割り当てることが推奨されており、IP アドレスが枯渇している環境では使用が難しくなります。サーバーレス VPC アクセスではコネクタインスタンスの数しか IP アドレスを必要としないため、IP アドレスの消費を抑えることができます。

サンプル構成

当記事では、Cloud Run から サーバーレス VPC アクセスを使用して VPC に接続し、Cloud NAT を経由してインターネット上の外部サービスにアクセスする構成を使用します。

サンプル構成(切り替え前)

Cloud Run にデプロイするアプリケーションのコードや、環境構成の手順については以下の記事を参照してください。

blog.g-gen.co.jp

Direct VPC Egress に切り替えた後の構成は、以下の記事の内容と同様になります。

blog.g-gen.co.jp

サンプル構成(切り替え後)

移行手順

当記事ではサーバーレス VPC アクセスから Direct VPC Egress への移行手順を記載しますが、逆に Direct VPC Egress からサーバーレス VPC アクセスへの移行についても同じような手順で実施することができます。

サンプル構成の初期状態

サンプル構成のアプリケーションは、インターネットアクセスに使用されている IP アドレスを確認することができる外部サイトにアクセスし、そのレスポンスを表示するようになっています。

インターネットアクセスに Cloud NAT を使用する構成となっているため、外部サイトからのレスポンスには Cloud NAT の IP アドレスが表示されます、

Cloud NATの静的IPアドレス

Cloud Runがインターネットアクセスに使用したIPアドレス

Cloud Run のコンソールから確認できるアウトバウンド接続設定は、以下のスクリーンショットのようになっています。

サーバーレスVPCアクセスを使用してVPCに接続する設定

当記事の切り替え手順の解説について

当記事の検証(2024年8月現在)にて、gcloud CLI を使ってサーバーレス VPC アクセスから Direct VPC Egress への切り替えを実施したところ、意図しない挙動が発生したため、切り替えの部分はコンソール上で実施しました。

意図しない挙動の詳細については当記事の最後にある補足をご一読ください。

Direct VPC Egress を使用するリビジョンをデプロイする

Cloud Run の詳細画面から [新しいリビジョンの編集とデプロイ] を開き、リビジョンの設定を行います。

ネットワーキングタブで「VPC に直接トラフィックを送信する」を選択し、接続先の VPC とサブネットを選択します。

新しいリビジョンでサーバーレスVPCアクセスの代わりにDirect VPC Egressを設定する

ここでは、「このリビジョンをすぐに利用する」のチェックを外し、Direct VPC Egress を使用するリビジョンに受信トラフィックをルーティングしないようにします。このあと、Direct VPC Egress を使用する VPC への接続が上手く行くことを確認してから、新しいリビジョンに受信トラフィックをルーティングさせます。

接続の確認が不要な場合は、この項目にチェックをしたままデプロイします。

新しいリビジョンにトラフィックをルーティングせずにデプロイ

デプロイした時点では、受信トラフィックはサーバーレス VPC アクセスを使用するリビジョンにすべてルーティングされており、Direct VPC Egress を使用する最新のリビジョンにはルーティングされていません。

既存のリビジョンに全てのトラフィックをルーティングしながら、Direct VPC Egressを使用する新しいリビジョンをデプロイ

ここから、新しいリビジョンが Direct VPC Egress を使って正しく動作するかを確認していきます。

新しいリビジョンの VPC 接続を確認する

タグ付きリビジョンを使用する方法

稼働中の Cloud Run サービスの受信トラフィックを新しいリビジョンにルーティングさせずに、新しいリビジョンの動作確認をするには、タグ付きリビジョン が使用できます。

タグ付きリビジョンの詳細については以下の記事をご一読ください。

blog.g-gen.co.jp

タグ付きリビジョンでは専用の URL を発行することで、トラフィックをルーティングしない設定のリビジョンであってもアクセスすることができます。

まず、リビジョンにタグをつけるため、Direct VPC Egress を設定した新しいリビジョンの名前を確認します。

# 新しいリビジョンの名前を確認する
$ gcloud run revisions list --service={サービス名} --region={リージョン}

以下の出力例では「ipcheck-00002-fzg」が新しいリビジョンの名前です。

# 出力例
   REVISION           ACTIVE  SERVICE  DEPLOYED                 DEPLOYED BY
✔  ipcheck-00002-fzg          ipcheck  2024-08-08 16:59:11 UTC  example@g-gen.co.jp
✔  ipcheck-00001-kk6  yes     ipcheck  2024-08-08 16:48:23 UTC  example@g-gen.co.jp

以下のコマンドで、新しいリビジョンに対してタグを付与します。当記事ではタグとして dev を付与していますが、ここは任意の値でかまいません。

# Direct VPC Egress を使用する新しいリビジョンに dev タグを付与
$ gcloud run services update-traffic {サービス名} \
    --region={リージョン名} \
    --set-tags=dev={新しいリビジョンの名前}

出力の最下部にタグ付きリビジョンの URL が表示されています。以下の出力例では「https://dev---ipcheck-xxxxxxxxxx-an.a.run.app」がタグ付きリビジョンの URL となります(URL の一部をマスクしています)。

# 出力例
✓ Updating traffic... Done.                                                                                                                                                                                                       
  ✓ Routing traffic...                                                                                                                                                                                                            
Done.                                                                                                                                                                                                                             
URL: https://ipcheck-xxxxxxxxxx-an.a.run.app
Traffic:
  100% ipcheck-00001-kk6
  0%   ipcheck-00002-fzg
         dev: https://dev---ipcheck-xxxxxxxxxx-an.a.run.app

コンソールからは、リビジョンタグをクリックすることでタグ付きリビジョンにアクセスすることができます。

コンソールからタグ付きリビジョンのURLにアクセスする

ブラウザからタグ付きリビジョンの URL にアクセスすると、Cloud NAT の IP アドレスが表示されます。

Direct VPC Egressの設定ができている場合Cloud NATのIPアドレスが表示される

したがって、Direct VPC Egress を使用する新しいリビジョンでも、VPC 内にある Cloud NAT を使用してインターネットに接続できていることがわかります。

トラフィック分割を使用する方法

トラフィック分割を使用することで、本番トラフィックを使用して Direct VPC Egress を使用する新しいリビジョンのテストが可能です。

# 以前のリビジョンに90%、新しいリビジョンに10%のトラフィックをルーティングする
$ gcloud run services update-traffic {サービス名} \
    --region={リージョン} \
    --to-revisions={以前のリビジョン名}=90,{新しいリビジョン名}=10

上記のコマンドでは、サービスが受信したトラフィックの90%がサーバーレス VPC アクセスを使用するリビジョンに、10%が Direct VPC Egress を使用するリビジョンにルーティングされます。

新しいリビジョンに受信トラフィックの10%をルーティングする

新しいリビジョンにトラフィックを移行する

新しいリビジョンの動作を確認したら、新しいリビジョンに受信トラフィックが100%ルーティングされるように修正します。タグはもう不要なため、ここで削除しておきます。

# トラフィックを最新のリビジョンにルーティングする(あわせてdevタグを削除する)
$ gcloud run services update-traffic {サービス名} \
    --region={リージョン} \
    --to-latest \
    --remove-tags=dev

これにより、全てのトラフィックが Direct VPC Egress を使用するリビジョンにルーティングされるようになりました。

全てのトラフィックがDirect VPC Egressを使用するリビジョンにルーティングされる

Cloud Run サービスで新しいリビジョンをデプロイすると、新しいリクエストは切り替え後のリビジョンにルーティングされますが、切り替え以前のリビジョンで処理していたリクエストは処理が終わるまで破棄されません。したがって、リビジョンの切り替えは安全に行うことができます(参考)。

サーバーレス VPC アクセスを削除する

サーバーレス VPC アクセスのコネクタインスタンスは使用されていなくても料金が発生しているため、リビジョンの切り替え後に忘れずに削除します。

# サーバーレス VPC アクセスの削除
$ gcloud compute networks vpc-access connectors delete {サーバーレスVPCアクセスの名前} --region={リージョン}

補足 : CLI の意図しない挙動

当記事のサンプル構成でサーバーレス VPC アクセスを Direct VPC Egress に切り替える場合、CLI では以下のコマンドを実行します。

# サーバーレスVPCアクセスの設定を解除しつつ、Direct VPC Egressを使用するリビジョンをデプロイする
$ gcloud run services update {サービス名} \
    --clear-vpc-connector \
    --network={接続するVPC} \
    --subnet={接続するサブネット} \
    --region={リージョン} \
    --no-traffic \
    --tag=dev \
    --vpc-egress=all-traffic 

記事執筆時の2024年8月初旬、数回の検証を行ったところ、--vpc-egress=all-traffic のフラグが機能せず、---vpc-egress=private-ranges-only を使用したときの設定でリビジョンがデプロイされてしまいました。

この場合、以下のスクリーンショットのように、トラフィック ルーティングの設定が「プライベート IP へのリクエストのみを VPC にルーティングする」なってしまいます。Cloud NAT を使用する場合、ここは「すべてのトラフィックを VPC にルーティングする」に設定する必要があります。

トラフィック ルーティングがコマンドで指定した設定にならない

CLI でサーバーレス VPC アクセスから Direct VPC Egress に切り替えを行う場合、以上の点に注意して切り替えを実施してください。

上記は記事執筆時の2024年8月初旬の挙動であり、修正される場合があることにご留意ください。

佐々木 駿太 (記事一覧)

G-gen最北端、北海道在住のクラウドソリューション部エンジニア

2022年6月にG-genにジョイン。Google Cloud Partner Top Engineer 2024に選出。好きなGoogle CloudプロダクトはCloud Run。

趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。