🐯

Direct VPC Egress で Cloud NAT がサポートされました

2024/03/15に公開

はじめに

こんにちは、クラウドエース SRE部 に所属している\textcolor{red}{赤髪}がトレードマークの Shanks です。
以前から記事発信している「Direct VPC Egress」で、Cloud NAT がついにサポートされました。

本記事では、この機能を利用するメリットやサンプル アーキテクチャをご紹介いたします。
Direct VPC Egress については既にわかりやすい解説記事を弊社から発信していますのでご参照ください。

Serverless 製品の特性をおさらい

Google Cloud は Cloud Run 等の Serverless 製品を展開しています。
Serverless 製品を活用することで、フルマネージドのプラットフォーム上で拡張性の高いアプリケーションをホストすることができます。
また、トラフィックに応じたワークロードの自動スケールだけでなく、ゼロまでスケールダウンできることも魅力的です。

既に読者の中でも活用いただいている方は多いと思いますが、魅力だけではなくもちろん注意点もあります。
Serverless という特性上、GCE インスタンスのように常に VM が稼働しているわけではありません。

そのため、ホスト先の IP アドレスが常に変化してしまうため、宛先サービス等で IP アドレス制限を設けている場合に、送信元 IP アドレスを固定化しなくてはいけません。

Serverless 製品と Cloud NAT

svac-arch

そこで、フルマネージドの NAT 機構を提供する Cloud NAT を中継することで、送信元 IP アドレスを静的 IP アドレスに変換してアクセスするケースがあります。
従来の Serverless 製品では、Egress トラフィックを静的 IP アドレスにする方法として、Serverless VPC Access を介して Cloud NAT からトラフィックを送信する方法が活用されてきました。

一方、Direct VPC Egress は、提供開始直後は Cloud NAT をサポートしていなかったため活用できない方法でした。
しかし、他記事でも述べられているように、Direct VPC Egress は Serverless VPC Access よりも高速かつ安価に構成できるため、Cloud NAT のサポートを期待されていました。

Direct VPC Egress の新機能

release-notes

2024/03/14 のリリースノートで、ついに Direct VPC Egress が Cloud NAT をサポートしたという嬉しいニュースが飛び込んできました 🎉
これにより、Serverless VPC Access に縛られていた Serverless 製品が、より安価で簡単に静的な送信元 IP アドレスを活用できるようになります。

従来の Serverless VPC Access これからの Direct VPC Egress
svac-arch direct-arch

試してみる

inet-ip.info に HTTP リクエストを行い、結果をブラウザに表示する簡単なアプリケーションを用意しました。
コードは Gemini を使って生成しました。

import http.server
import socketserver
import urllib.request

class MyHandler(http.server.SimpleHTTPRequestHandler):
    def do_GET(self):
        with urllib.request.urlopen('https://inet-ip.info/ip') as response:
            ip_address = response.read().decode('utf-8').strip()

        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()
        self.wfile.write(bytes(ip_address, 'utf-8'))

PORT = 8080
Handler = MyHandler
with socketserver.TCPServer(("", PORT), Handler) as httpd:
    print("serving at port", PORT)
    httpd.serve_forever()

上記のアプリケーションを Cloud Run で動かすために Dockerfile を作成します。
こちらも Gemini を使って生成しました。

FROM python:3.9-slim-buster
WORKDIR /app
COPY server.py /app/
EXPOSE 8080
CMD ["python", "server.py"]

あとは Cloud Build を使ってイメージをビルドし、デプロイするだけです。
ga-build

gcloud artifacts repositories create ${リポジトリ名} \
  --repository-format docker \
  --project ${プロジェクトID} \
  --location asia-northeast1

gcloud builds submit \
  --tag asia-northeast1-docker.pkg.dev/${プロジェクトID}/${リポジトリ名}/${イメージ名}

デプロイが正常に終了したら Cloud Run にアクセスしてみましょう。
出力された結果が、Cloud NAT で NAT された IP アドレスと同一であれば成功です。

diff \
  <(curl -s https://${Cloud Run のターゲットエンドポイント(run.app となっているもの)}) \
  <( \
    gcloud compute addresses describe ${Cloud NAT で利用している外部 IP アドレスのリソース名} \
    --project ${プロジェクト ID} \
    --region asia-northeast1 \
    --format json \
    | jq -cr '.address' \
  ) \
  | grep -vF '\ No newline at end of file'
1c1
< 104.198.118.xxx
---
> 104.198.118.xxx

まとめ

Direct VPC Egress の Cloud NAT サポートによって、従来よりも安価で簡単に送信元 IP アドレスを固定化することが可能です。
皆様もぜひこの機会に活用してみてはいかがでしょうか。

観点 Serverless VPC Access Direct VPC Egress
VPC と内部接続
Cloud NAT のサポート
料金 ⚠️
・スケールインできないため注意が必要

・自動スケールによる最適化が可能
構成のシンプルさ ⚠️
・必要とする帯域幅を計算してマシンタイプを選定する必要があるため手間

・自動スケールのため管理不要でシンプル
レイテンシ ⚠️
・適切なスケールアウトをすれば低レイテンシの結果を出す

・チューニングを行わずとも低レイテンシの結果を出す

Discussion