第 2 世代の関数のダイレクト VPC 下り(外向き)を構成する

ダイレクト VPC 下り(外向き)を使用すると、Cloud Run functions(第 2 世代)関数から VPC ネットワークにトラフィックを直接ルーティングできます。

制限事項

  • ダイレクト VPC 下り(外向き)は第 1 世代の関数では使用できません。
  • ダイレクト VPC 下り(外向き)とサーバーレス VPC アクセス コネクタを同時に使用することはできません。詳細については、ダイレクト VPC 下り(外向き)と VPC コネクタの比較をご覧ください。

始める前に

  • Cloud Functions API を有効にします。
  • Google Cloud CLI をインストールし、gcloud init を実行して初期化します。
  • gcloud コンポーネントをバージョン 545.0.0 以降に更新します。

    gcloud components update
    

  • プロジェクトに VPC ネットワークがない場合は作成します

  • 省略可: 関数が内部 IP アドレスを使用して Google API とサービスにアクセスする必要がある場合は、Direct VPC 下り(外向き)に使用するサブネットで限定公開の Google アクセスを有効にします。

IAM 権限を設定する

Direct VPC 下り(外向き)を承認するには、関数に Cloud Run 起動元(roles/run.invoker)ロールを付与するよう管理者に依頼してください。

次のいずれかの方法で、Cloud Run が VPC ネットワークにアクセスできるようにします。

  • Cloud Run サービス エージェントのロール: デフォルトでは、Cloud Run サービス エージェントには、必要な権限を含む Cloud Run サービス エージェントのロール(roles/run.serviceAgentが付与されています。

  • カスタム権限: より詳細に制御するには、プロジェクトに対する次の追加権限を Cloud Run サービス エージェントに付与します。

    • compute.networks.get
    • compute.subnetworks.get
    • プロジェクトまたは特定のサブネットに対する compute.subnetworks.use
    • compute.addresses.get
    • compute.addresses.list
    • compute.addresses.create外部 IPv6 を使用するデュアルスタック サブネットの場合にのみ必要)
    • compute.addresses.delete(外部 IPv6 を使用するデュアルスタック サブネットの場合にのみ必要)
    • compute.addresses.createInternal
    • compute.addresses.deleteInternal
    • compute.regionOperations.get
  • Compute ネットワーク ユーザー ロール: デフォルトの Cloud Run サービス エージェント ロールまたはカスタム権限を使用しない場合は、Cloud Run サービス エージェント サービス アカウントに Compute ネットワーク ユーザー ロール(roles/compute.networkUserを付与します。外部 IPv6 を使用するサブネットには、Compute パブリック IP 管理者ロール(roles/compute.publicIpAdminも必要です。

    たとえば、Compute ネットワーク ユーザーのロールを付与するには、次のコマンドを実行します。

    gcloud projects add-iam-policy-binding PROJECT_ID \
    --member "serviceAccount:service-PROJECT_NUMBER@serverless-robot-prod.iam.gserviceaccount.com" \
    --role "roles/compute.networkUser"

    次のように置き換えます。

    • PROJECT_ID: 実際のプロジェクトの ID。
    • PROJECT_NUMBER: Cloud Run 関数をデプロイするプロジェクト番号。

ダイレクト VPC 下り(外向き)を構成する

新規または既存の第 2 世代関数にダイレクト VPC 下り(外向き)を構成します。

gcloud

  1. 関数をデプロイするときにダイレクト VPC 下り(外向き)を構成するには、ネットワーク設定のフラグを指定して gcloud beta functions deploy コマンドを使用します。

    gcloud beta functions deploy FUNCTION_NAME \
        --source . \
        --runtime RUNTIME \
        --trigger-http \
        --region REGION \
        --network=NETWORK \
        --subnet=SUBNET \
        --network-tags=NETWORK_TAG_NAMES \
        --direct-vpc-egress=EGRESS_SETTING
    

    次のように置き換えます。

    • FUNCTION_NAME: 関数の名前
    • RUNTIME: 関数のランタイム(例: nodejs20)。
    • REGION: 関数をデプロイするリージョン。
    • (省略可)NETWORK: VPC ネットワークの名前。VPC ネットワークまたはサブネット、あるいはその両方を指定します。ネットワークのみを指定した場合、サブネットにはネットワークと同じ名前が使用されます。
    • (省略可)SUBNET: サブネットの名前。VPC ネットワークとサブネットのいずれかまたは両方を指定します。ネットワークのみを指定した場合、サブネットにはネットワークと同じ名前が使用されます。同じサブネットに複数の関数をデプロイまたは実行できます。
    • (省略可)NETWORK_TAG_NAMES: 関数に関連付けるネットワーク タグのカンマ区切り名。関数ごとに異なるネットワーク タグ(network-tag-2 など)を設定できます。
    • EGRESS_SETTING: 下り(外向き)設定値
      • all: デフォルト。すべてのアウトバウンド トラフィックを VPC ネットワーク経由で送信します。
      • private-ranges-only: VPC ネットワーク経由で内部アドレスにのみトラフィックを送信します。
  2. 省略可: 関数からすべてのダイレクト VPC 下り(外向き)設定を削除するには、--clear-network フラグと --clear-network-tags フラグを指定して関数を再デプロイします。

Terraform

Terraform 構成を適用または削除する方法については、基本的な Terraform コマンドをご覧ください。

ダイレクト VPC 下り(外向き)を構成するには、google-beta Terraform プロバイダを使用します。

Cloud Run functions(第 2 世代)のダイレクト VPC 下り(外向き)の例を起点として、次のフィールドを更新します。

  • service_config.network: VPC ネットワークの名前。
  • service_config.subnetwork: VPC サブネットワークの名前。
  • service_config.direct_vpc_egress: VPC ネットワークに送信するトラフィック。VPC_EGRESS_ALL_TRAFFIC は、すべてのアウトバウンド トラフィックを VPC ネットワーク経由で送信します。VPC_EGRESS_PRIVATE_RANGES_ONLY は、プライベート IP アドレス範囲へのトラフィックのみを VPC ネットワークに送信します。

例: 関数から内部サービスを呼び出す

この例では、内部 Cloud Run サービスを作成し、Direct VPC 下り(外向き)を使用する Cloud Run functions(第 2 世代)関数から呼び出す方法を示します。

内部バックエンド サービスを作成する

  1. バックエンド サービスの新しいディレクトリを作成し、そのディレクトリに移動します。

    mkdir backend-service
    cd backend-service
    
  2. 次の内容の package.json ファイルを作成します。

    {
        "name": "backend-service",
        "version": "1.0.0",
        "description": "",
        "scripts": {
            "start": "node index.js"
        },
        "dependencies": {
            "express": "^4.18.1"
        }
    }
    
  3. 次の内容の index.js ファイルを作成します。

    const express = require('express');
    const app = express();
    
    app.get('/', (req, res) => {
        res.send("hello world");
    });
    
    const port = parseInt(process.env.PORT) || 8080;
    app.listen(port, () => {
        console.log(`helloworld: listening on port ${port}`);
    });
    
  4. 内部上り(内向き)を使用してサービスを Cloud Run にデプロイします。

    gcloud run deploy backend \
        --source . \
        --no-allow-unauthenticated \
        --region=REGION \
        --ingress internal
    

    REGION は、リージョン(us-west1 など)に置き換えます。

  5. 新しいサービスの URL を保存します。コピーしたメールアドレスは次のセクションで必要になります。

関数を作成してデプロイする

  1. 関数の新しいディレクトリを作成し、そのディレクトリに移動します。

    cd ..
    mkdir dvpc-function
    cd dvpc-function
    
  2. 次の内容の package.json ファイルを作成します。

    {
      "name": "sample-http",
      "version": "0.0.1",
      "dependencies": {
        "axios": "0.21.1",
        "@google-cloud/functions-framework": "^3.0.0"
      }
    }
    
  3. 次の内容の index.js ファイルを作成します。このコードは、内部バックエンド サービスに対して認証済みリクエストを行います。

    const axios = require('axios');
    const functions = require('@google-cloud/functions-framework');
    
    const callVPCService = async (req, res) => {
      const backendUrl = process.env.BACKEND_URL;
    
      if (!backendUrl) {
        console.error('BACKEND_URL environment variable not set.');
        res.status(500).send('BACKEND_URL not configured.');
        return;
      }
    
      try {
        const metadataServerURL = 'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=';
        const tokenUrl = metadataServerURL + backendUrl;
    
        const tokenResponse = await axios.get(tokenUrl, {
          headers: {
            'Metadata-Flavor': 'Google',
          },
        });
        const token = tokenResponse.data;
    
        const response = await axios.get(backendUrl, {
          headers: {
            Authorization: `bearer ${token}`,
          },
    });
    
    res.status(200).send(`Response from backend: ${response.data}`);
      } catch (error) {
        console.error(`Error calling backend service: ${error.message}`);
        res.status(500).send(`Error calling backend: ${error.message}`);
      }
    };
    
    functions.http('callVPCService', callVPCService);
    
  4. すべてのトラフィックをデフォルトの VPC ネットワークに転送するように構成されたダイレクト VPC 下り(外向き)を使用して関数をデプロイします。

    gcloud beta functions deploy my-2ndgen-function \
      --source . \
      --runtime nodejs20 \
      --trigger-http \
      --entry-point callVPCService \
      --network=default \
      --subnet=default \
      --direct-vpc-egress=all \
      --region=REGION \
      --allow-unauthenticated \
      --set-env-vars BACKEND_URL=BACKEND_URL
    

    次のように置き換えます。

    • REGION: バックエンド サービスをデプロイしたリージョン。
    • BACKEND_URL: 作成したバックエンド サービスの URL。
  5. 関数がデプロイされたら、その URL にアクセスして関数を呼び出します。関数は内部バックエンド サービスを呼び出し、そのレスポンスを返します。

次のステップ