Cloud Runから固定IPでインターネット接続する(Direct VPC Egress編)

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

G-gen の佐々木です。当記事では、Cloud Run からインターネットアクセスを行う際に使用されるパブリック IP アドレスを固定する方法を解説します。

Cloud Run から Cloud NAT を使用してインターネット接続を行う

はじめに

当記事の内容は Cloud Run service、Cloud Run jobs の両方を対象としているため、それぞれを区別せずに「Cloud Run」と記載しています。

なお、当記事で解説する手順では Cloud Run services を使用しています。

サーバーレス VPC アクセスを使用する方法

Cloud Run では、コンテナインスタンスを起動する際にパブリック IP アドレスが動的に割り当てられ、インターネットにアクセスする場合はこの動的 IP アドレスが使用されるようになっています。

Cloud Run でインターネットアクセスに使用するパブリック IP アドレスを固定したい場合、静的 IP アドレスを紐付けた Cloud NAT を経由してインターネットアクセスを行うように設定する必要があります。

従来の方法では、Cloud NAT が存在する VPC にサーバーレス VPC アクセスを構成し、サーバーレス VPC アクセスコネクタを使用して Cloud Run から VPC に接続する必要がありました。

IPアドレスの固定にサーバーレスVPCアクセスを使用する場合の構成

サーバーレス VPC アクセスを使用する方法については、以下の記事で詳細な手順を解説しています。

blog.g-gen.co.jp

Direct VPC Egress を使用する方法(当記事で解説)

2024年3月に Direct VPC Egress で Cloud NAT が使用できるようになったことで、サーバーレス VPC アクセスを構成することなく、Cloud Run が使用するパブリック IP アドレスを固定できるようになりました。

Direct VPC Egress では、サーバーレス VPC アクセスとは異なり、常時起動のコネクタインスタンスを経由する必要がないため、より安価かつ高速に VPC に接続することができます。

IPアドレスの固定にDirect VPC Egressを使用する場合の構成

Direct VPC Egress の解説、およびサーバーレス VPC アクセスとの詳細な比較については、以下の記事をご一読ください。

blog.g-gen.co.jp

手順

シェル変数の設定

当記事では gcloud コマンドを使用して各種リソースを作成していきます。

コマンド内で何度か使用する値は、以下のようにシェル変数として設定しておきます。

PROJECT 変数の値にはリソースを作成するプロジェクトを、LOCATION 変数の値にはリージョンを設定してください。残りの変数は各種リソースの名前を指定する際に使用します。

PROJECT=myproject
LOCATION=asia-northeast1
NETWORK=vpc-direct-vpc-egress
SUBNET=subnet-direct-vpc-egress
ROUTER=router-direct-vpc-egress
ADDRESS=address-direct-vpc-egress
NAT=nat-direct-vpc-egress

VPC とサブネットの作成

Cloud Run から接続する Cloud NAT を配置するための VPC を作成します。

# VPC の作成
$ gcloud compute networks create ${NETWORK} \
    --project=${PROJECT} \
    --subnet-mode=custom
  

作成した VPC にサブネットを作成します。Cloud Run から Direct VPC Egress を使用して VPC に接続する際、このサブネットに設定された IP アドレス範囲の IP アドレスが使用されます。

# サブネットの作成
$ gcloud compute networks subnets create ${SUBNET} \
    --project=${PROJECT} \
    --network=${NETWORK} \
    --range=192.168.101.0/24 \
    --region=${LOCATION}
  

サブネットのアドレス範囲は、最低でも /28 の CIDR 範囲で指定する必要があります。

Cloud Run がスケールアウトすると、ここで指定したアドレス範囲の IP アドレスが消費されます。使用できる IP アドレスが枯渇していると Cloud Run のスケールアウトが阻害されてしまうため、サブネットには十分なアドレス数を確保するようにアドレス範囲を設定する必要があります。

アドレス数の目安は、Cloud Run に設定された最大コンテナインスタンス数の4倍となっています。また、Cloud Run jobs を使用する場合は少なくとも1,024個の IP アドレスを確保しておく必要があります。

Cloud NAT の作成

作成した VPC に Cloud NAT を作成していきます。Cloud NAT は VPC 内の Cloud Router に関連付ける必要があるため、Cloud Router を先に作成しています。

# Cloud Router の作成
$ gcloud compute routers create ${ROUTER} \
    --project=${PROJECT} \
    --network=${NETWORK} \
    --region=${LOCATION}
  
# Cloud NAT 用のパブリック IP アドレスを予約
$ gcloud compute addresses create ${ADDRESS} \
    --region=${LOCATION}
  
# Cloud NAT の作成
$ gcloud compute routers nats create ${NAT} \
    --router=${ROUTER} \
    --region=${LOCATION} \
    --nat-all-subnet-ip-ranges \
    --nat-external-ip-pool=${ADDRESS}

Cloud Run サービスのデプロイ

使用するコード

当記事では Cloud Run のクイックスタートのサンプルコードをベースに、Cloud Run のコンテナインスタンスがインターネットアクセスに使用している IP アドレスをブラウザ上に表示するだけの Web アプリケーションを実装します。

インターネットアクセスに使用している IP アドレスは「https://inet-ip.info/ip」から取得します。

// main.go
package main
  
import (
    "fmt"
    "log"
    "net/http"
    "os"
)
  
func main() {
    log.Print("starting server...")
    http.HandleFunc("/", ipCheck)
  
    // Determine port for HTTP service.
    port := os.Getenv("PORT")
    if port == "" {
        port = "8080"
    }
  
    // Start HTTP server.
    log.Printf("listening on port %s", port)
    if err := http.ListenAndServe(":"+port, nil); err != nil {
        log.Fatal(err)
    }
}
  
// インターネットアクセスに使用される IP アドレスを確認する
func ipCheck(w http.ResponseWriter, r *http.Request) {
  
    // https://inet-ip.info/ip にアクセスし、自身の IP アドレスを取得する
    resp, err := http.Get("https://inet-ip.info/ip")
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()
  
    // レスポンスボディを読み込む
    buf := make([]byte, 32)
    n, err := resp.Body.Read(buf)
    if err != nil {
        log.Fatal(err)
    }
    // ブラウザに IP アドレスを表示する
    fmt.Fprintf(w, string(buf[:n]))
  
}
  

ソースコードから Cloud Run をデプロイする

main.gogo.mod ファイルがあるディレクトリで以下のコマンドを実行し、Cloud Run サービスをデプロイします。

# Cloud Run サービスのデプロイ
$ gcloud run deploy ipcheck \
    --source . \
    --project=${PROJECT} \
    --region=${LOCATION} \
    --network=${NETWORK} \
    --subnet=${SUBNET} \
    --vpc-egress=all-traffic \
    --allow-unauthenticated

このデプロイコマンドでは、Cloud Run で Direct VPC Egress を使用するために、以下のフラグを使用しています。

フラグ 設定する値 説明
--region VPCの名前 Direct VPC Egress で接続する VPC の名前を指定する。
--subnet サブネットの名前 Direct VPC Egress で接続する VPC のサブネットの名前を指定する。
--vpc-egress all-trafic すべての Egress トラフィックを VPC で送信する場合 all-trafic を指定する。プライベート IP アドレスへの通信のみ VPC 経由にしたい場合は private-ranges-only を指定する。(参考

Cloud Run からのインターネットへのアクセスを Cloud NAT 経由にする場合、--vpc-egress フラグの値は必ず all-trafic を指定します。
ここでprivate-ranges-only を指定した場合、インターネットへのアクセスには Cloud Run インスタンスの動的なパブリック IP アドレスが使用されてしまいます。

なお、コンソールから Direct VPC Egress を設定する場合は、以下のスクリーンショットのように設定します。

Cloud Runのコンソール上でDirect VPC Egressを設定する場合

動作確認

gcloud コマンドによる Cloud Run サービスのデプロイが完了すると、標準出力のService URL: の行にサービスの URL が表示されています。

Building using Buildpacks and deploying container to Cloud Run service [ipcheck] in project [myproject] region [asia-northeast1]
✓ Building and deploying new service... Done.                                                                                                                                                  
  ✓ Uploading sources...                                                                                                                                                                       
  ✓ Building Container... Logs are available at [https://console.cloud.google.com/cloud-build/builds/2aa331ab-11aa-46bd-976b-xxxxxxxxxxxx?project=xxxxxxxxxxxx].                               
  ✓ Creating Revision...                                                                                                                                                                       
  ✓ Routing traffic...                                                                                                                                                                         
  ✓ Setting IAM Policy...                                                                                                                                                                      
Done.                                                                                                                                                                                          
Service [ipcheck] revision [ipcheck-00001-k2j] has been deployed and is serving 100 percent of traffic.
Service URL: https://ipcheck-ai4xxxxxxx-an.a.run.app
  

ブラウザでサービスの URL にアクセスすると、Cloud Run のコンテナインスタンスが起動し、コンテナインスタンスがインターネットアクセスに使用した IP アドレスが表示されます。

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

ブラウザに表示された IP アドレスが、Cloud NAT に設定された静的パブリック IP アドレスと一致するかを確認します。

以下のコマンドを使用するか、コンソール上で Cloud NAT の IP アドレスを確認します。

# Cloud NAT に紐づけた静的パブリック IP アドレスを確認
$ gcloud compute addresses describe ${ADDRESS} | head -n 1
  

Cloud NAT に紐づけた静的パブリックIPアドレスを確認(コンソール)

佐々木 駿太 (記事一覧)

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

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

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