GAしたDirect VPC Egressを使ってみた

2024/05/09に公開されました。
2024/05/09に更新されました。

Direct VPC Egressを使ってみてメリデメを考える


author: kuribo-

はじめに

インフラチームのkuribo-です。
今回は先日GAしたDirect VPC Egressを使ってみました。

Direct VPC Egressとは

Direct VPC Egressとは、サーバレスのサービスであるCloud RunのEgress(外向き通信)をVPC内に通信できるようにするサービスです。
色々とコンソールも触ってみたのですが、裏側がCloud RunであるCloud Functions Gen2も対応しているかと思ったのですが使えませんでした。
(ドキュメントにも対応の文字無し)

Direct VPC Egressのユースケースとしては以下のようなものが考えられます。

  • VPC内のサービスと通信できるようにしたい(Compute EngineやCloud SQLなど)
  • インターネットとの通信の際にVPCに設定してあるFirewallで通信先を限定したい
  • VPCフローログやCloud NATで通信ログを取りたい
  • Cloud NATを経由することで外部通信のIPを固定IPとしたい

以前からあったServerless VPC Access Connectorとの違いは大きく3つでしょうか。

  • Direct VPC Egressでは大量のIPを利用する
    • 100個のインスタンスが立つようなCloud Runを作ると800個分のIPが必要になるようです
    • IPをあるだけ使ってもいいなら特に問題ないですが、負荷に応じてスケールするサーバレスサービスと若干相性の悪い仕様かも
  • Direct VPC Egressは対応しているサーバレスサービスがまだ少ない
    • Serverless VPC AccessはCloud Runの他に、Cloud FunctionsやApp Engineも対応している
  • Direct VPC Egressはコストが安く通信が速い
    • Serverless VPC Access ConnectorはCompute Engineが立つのでコストがかかる
    • Direct VPC Egressは直接通信するのでGCE分のコストはかからないし、通信も速い
      ※VPC Access Connectorは最低2台、最大10台のGCEが常時立つのでコストが高いです。また、スケールアウトはしますがスケールインはしてくれません。

そのプロジェクト単体で利用し他のプロジェクトと接続しないとか、全社的にIPが管理されていないならそこまで気にすることはない違いでしょうか。
ただ、Cloud Run毎にサブネット作るのちょっとめんどくさいですね。
(IP帯域を大きく取って複数のCloud Runを同じサブネットに全部押し込むこともできるけど、IPの必要量計算しづらくなるので分けた方が無難な気がする)

次は使ってみます。

環境

以下の環境で試してみます。

  • VPC(default)
    • 東京リージョンのSubnet
  • Cloud Run
  • Cloud NAT

構築

VPCの作成

VPCはdefaultで作成されているものを利用します。
(Subnetも同様)
もし会社の組織ポリシーなどでdefaultVPCが作成されないようにされていた場合は各自作成します。

Cloud NATの作成

以下のコマンドでCloud NATを作成します。

gcloud compute addresses create nat-address \
    --region asia-northeast1

gcloud compute routers create nat-router \
    --network default \
    --region asia-northeast1

gcloud compute routers nats create nat-gw \
    --router=nat-router \
    --router-region=asia-northeast1 \
    --nat-all-subnet-ip-ranges \
    --nat-external-ip-pool=nat-address

Cloud Runの作成

以下のコードを使ってCloud Runをデプロイします。

package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		resp, err := http.Get("https://dryaki.gicloud.co.jp/articles/direct-vpc-egress")
		if err != nil {
			log.Fatal(err)
		}
		defer resp.Body.Close()

		body, err := io.ReadAll(resp.Body)
		if err != nil {
			log.Fatal(err)
		}

		fmt.Fprintf(w, "%s", body)
	})
	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
		log.Printf("defaulting to port %s", port)
	}

	log.Printf("Listening on port %s", port)
	if err := http.ListenAndServe(":"+port, nil); err != nil {
		log.Fatal(err)
	}
}

main.goとgo.modを作成したフォルダで以下のコマンドを実行します。
尚、direct vpc egressは2024/4/24にGAしたのですが、まだなぜかalphaのコマンドです。(2024/05/09時点)

gcloud alpha run deploy directvpc \
  --source=. \
  --allow-unauthenticated \
  --vpc-egress=all-traffic \
  --network=default \
  --subnet=default \
  --region=asia-northeast1 \
  --project=sandbox-kurihara-h2

デプロイが完了すると、アクセスするためのURLが表示されます。

動作確認

Cloud Run作成の時に表示された、URLにアクセスします。(Cloud RunのURL)
アクセスした結果、本記事のHTMLのソースコードが取得できていれば成功です!
(ブラウザだとJavascriptやCSSが取得できないので崩れた表示になりますが、それが正常な挙動です。HTMLしか取得していませんので。)

追加検証

Cloud NATを削除した状態でどのように動作するか確認します。
以下のコマンドを実行して、Cloud NATを削除します。
(作った順番と逆順)

gcloud compute routers nats delete nat-gw \
    --router=nat-router \
    --router-region=asia-northeast1

gcloud compute routers delete nat-router \
    --region asia-northeast1

gcloud compute addresses delete nat-address \
    --region asia-northeast1

再度Cloud Runにアクセスします。
アクセスした結果、タイムアウトして「Service Unavailable」と表示されたら想定通りです。

まとめ

Direct VPC Egressを使ってみましたが、Serverless VPC Accessに比べて簡単に使えました。
コストも安いし、構築も楽だしで色々いいところはありますが、大量のアクセスを受けるようなサービスの場合は、
IPアドレスの問題で向いていないこともわかりました。

また、Direct VPC Egressを使っている状態で、インターネットに出て行こうとするとCloud NATがないと出ていくことができませんでした。
内部IPは貰えても、外部IPは貰えないようですね。
ここも上記と同じ懸念ですが大量のアクセスを受けるようなサービスの場合、Cloud NATのポート枯渇が起こりそうですね。
(Serverless VPC Accessも同じ問題は抱えますが。内部通信のみDirect VPC Egressを利用するというオプションはあるので、外部通信のログが必要とかFWで制御したいという要件がなければそちらを使った方が良さそうです。)

ですので、やはり小規模なシステムに向いたサービスかなという所感です。

おわりに

まだ登場したばかりの機能なので、これからもっと弱点を解消した機能になっていくのかな。
また、GAEやGCFにも対応してほしいですね。

※本記事は、ジーアイクラウド株式会社の見解を述べたものであり、必要な調査・検討は行っているものの必ずしもその正確性や真実性を保証するものではありません。

※リンクを利用する際には、必ず出典がGIC dryaki-blogであることを明記してください。
リンクの利用によりトラブルが発生した場合、リンクを設置した方ご自身の責任で対応してください。
ジーアイクラウド株式会社はユーザーによるリンクの利用につき、如何なる責任を負うものではありません。