Cloud Run サービスからのインターネット接続に静的 IP アドレスを使用する

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

G-gen の佐々木です。当記事では、Google Cloud (旧称 GCP) のサーバーレスコンテナサービスである Cloud Run について、Cloud Run サービスからインターネット接続を行う際に Public IP アドレスを固定する方法を解説します。

使用するサービス・仕組み

Cloud Run

Cloud Run はサーバーレスな環境でコンテナを実行できるサービスです。
サービスの全体像については以下の記事で解説していますので、ご一読ください。

blog.g-gen.co.jp

サーバーレス VPC アクセス

サーバーレス VPC アクセス は Cloud Run や Cloud Functions などのサーバーレス実行環境から VPC 内リソースにアクセスするための仕組みです。
サーバーレス VPC アクセスを設定すると、VPC 内に コネクタ が作成され、サーバーレス実行環境からの通信を VPC にルーティングすることができます。

構成図

Cloud Run サービスでは、コンテナからインターネット通信を行う際、動的 IP アドレスプールを使用するのがデフォルトの動作となっています。
したがって、接続先となる外部エンドポイントで IP アドレスベースのファイアウォールが設定されているなど、静的 IP アドレスが必要となるケースでは、デフォルトの設定では上手くいきません。

そこで、サーバーレス VPC アクセスを使用して Cloud Run サービスを VPC に接続し、静的 IP アドレスを使用する Cloud NAT を経由してインターネット通信を行うように設定します。

サーバレス VPC アクセスコネクタ と Cloud NAT を経由したインターネット接続

Cloud Run サービスのデプロイ

アプリケーションを作成する

Cloud Run ドキュメントの クイックスタート をベースとし、アプリケーションを実行するコンテナがインターネット接続に使用した IP アドレスを確認できるようにコードを書き換えます。

IP アドレスの確認には DynDNSを使用します。
http://checkip.dyndns.com/ に対して HTTP リクエストを送信することで、現在使用している IP アドレスの情報が返ってきます。

main.py

DynDNS に HTTP リクエストを送信し、レスポンスをブラウザ上に表示するようにします。

import requests
from flask import Flask
 
 
app = Flask(__name__)
 
# DynDNS の URL
url = 'http://checkip.dyndns.com/'
 
 
@app.route('/')
def ip_check():
 
    # HTTP リクエストを送信
    res = requests.get(url)
    
    # レスポンスをブラウザ上に表示
    return res.text
 
if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=8080)

requirements.txt

クイックスタートの requirements.txt に requests パッケージを追記します。

Flask==2.1.0
gunicorn==20.1.0
requests==2.28.1

Dockerfile

クイックスタートの Dockerfile をそのまま使用します。

FROM python:3.10-slim

ENV PYTHONUNBUFFERED True

ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . ./

RUN pip install --no-cache-dir -r requirements.txt

CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app

コンテナイメージを Artifact Registry に格納する

Cloud Run サービスに使用するコンテナイメージをビルドします。
当記事では Cloud Build を使用してイメージをビルドし、Artifact Registry に格納します。

リポジトリを作成する

まず、 Artifact Registry のリポジトリを作成します。

$ gcloud artifacts repositories create {リポジトリ名} --repository-format=docker --location={ロケーション}

# 実行例
$ gcloud artifacts repositories create myrepository --repository-format=docker --location=asia-northeast1

コンテナイメージをビルドしてリポジトリに格納する

Cloud Build を使用してコンテナイメージをビルドし、先ほど作成したリポジトリに push します。

$ gcloud builds submit --tag {ロケーション}-docker.pkg.dev/{プロジェクトID}/{リポジトリ名}/{イメージ名}

# 実行例
$ gcloud builds submit --tag asia-northeast1-docker.pkg.dev/myproject/myrepository/myimage

ビルドしたイメージを使用して Cloud Run サービスをデプロイする

まずはコンテナイメージをそのまま Cloud Run にデプロイしていきます。 Artifact Registry に格納したコンテナイメージから Cloud Run にデプロイする を選択します。

Artifact Registry から Cloud Run サービスをデプロイ

任意の サービス名リージョン を設定します。

サービス名とリージョンを設定する

今回はサービスの呼び出し元は特に考慮しないので、Ingress 項目の「すべてのトラフィックを許可する」、認証 項目の「未認証の呼び出しを許可」にチェックを入れ、Cloud Run サービスを作成します。

Ingress と 認証の設定

インターネット接続に動的 IP アドレスが使用されることを確認する

サービスのデプロイが完了したら、サービスの詳細画面にある Cloud Run サービスの URL をクリックします。

Cloud Run サービスの URL

アプリケーションが実行され、実行基盤となったコンテナがインターネット通信に使用している IP アドレスがブラウザ上に表示されます。

コンテナがインターネット接続に使用している IP アドレスが表示される

その後、起動したコンテナが削除されるまでしばらく待ちます。
コンテナ インスタンス数のメトリクスで activeidle の値が 0 になってから、もう一度サービスの URL にアクセスします。

コンテナ インスタンス数の active と idle の値が 0 になるまで待つ

先ほどとは異なるコンテナ上でアプリケーションが実行され、ブラウザには別の IP アドレスが表示されます。
このように、デフォルトの設定では、コンテナは動的 IP アドレスプールを使用してインターネット通信を行います。

コンテナが新たに起動するため、別の IP アドレスが使用される

静的 IP アドレスを使用したインターネット接続

サーバーレス VPC アクセスコネクタを作成する

VPC にサーバーレス VPC アクセスコネクタを作成していきます。
VPC ネットワーク のコンソールからコネクタの作成画面に進みます。

VPC ネットワークのコンソールからコネクタを作成する

ネットワーク に使用する VPC を設定し、サブネット で「カスタム IP 範囲」を選択します。
IP 範囲に VPC で使用されていない /28 の IP 範囲を入力し、コネクタを作成します。

サーバーレス VPC アクセス コネクタの作成

「スケーリング設定を表示」を開くと、コネクタインスタンスの最小/最大数の設定や、インスタンスが使用するマシンタイプ(f1-micro/e2-micro/e2-standard-4)を設定することができます。
最小インスタンス数は 2~9、最大インスタンス数は 3~10 の値を設定することができますが、コネクタインスタンスが一度スケールアウトするとスケールインすることができない 仕様のため、最大インスタンス数は慎重に設定しましょう。

サーバーレスVPCアクセスコネクタのスケーリング設定

Cloud NAT を設定するための Cloud Router を作成する

Cloud NAT は VPC 、リージョン、そして Cloud Router に関連付けられるため、VPC に対して Cloud Router を作成します。
ハイブリッド接続 のコンソールから Cloud Router を作成していきます。

ハイブリッド接続のコンソールから Cloud Router を作成する

名前ネットワークリージョン を設定し、それ以外の項目はデフォルトのまま作成します。

Cloud Router の作成

静的 IP アドレスを使用する Cloud NAT を設定する

ネットワーク サービス のコンソールから Cloud NAT を作成していきます。

ネットワーク サービスのコンソールから Cloud NAT を作成する

先ほど作成した Cloud Router を設定し、Cloud NAT IP アドレス 項目で「手動」を選択して、「IP アドレスを作成」をクリックします。

Cloud NAT の作成

予約する静的 IP アドレスの名前を入力し、「予約」をクリックします。

静的 IP アドレスの予約

予約した静的 IP アドレスが CLoud NAT に設定されるので、「作成」をクリックします。

予約した静的 IP アドレスが設定される

コネクタを使用するように Cloud Run サービスを設定する

Cloud Run サービスの詳細画面から 新しいリビジョンの編集とデプロイ を選択し、サーバーレス VPC アクセス コネクタを使用するようにサービスを設定します。

Cloud Run サービスを編集する

編集画面の 接続 タブにある VPC 項目で コネクタを作成した VPC を選択し、「すべてのトラフィックを VPC コネクタ経由でルーティングする」にチェックを入れます。

サーバーレス VPC アクセス コネクタの設定

「デプロイ」を選択し、Cloud Run サービスを更新します。

インターネット接続に静的 IP アドレスが使用されることを確認する

Cloud Run サービスの URL をクリックし、アプリケーションを実行します。
ここまでの設定により、コンテナ は VPC にある Cloud NAT を経由してインターネットアクセスを行うため、ブラウザに表示される IP アドレスが Cloud NAT に設定した静的 IP アドレスになっています。

Cloud NAT の静的 IP アドレスが表示される

Cloud NAT の静的 IP アドレス

佐々木 駿太 (記事一覧)

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

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

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