2세대 함수의 직접 VPC 이그레스 구성

직접 VPC 이그레스를 사용하면 Cloud Run Functions (2세대) 함수의 트래픽을 VPC 네트워크로 직접 라우팅할 수 있습니다.

제한사항

  • 1세대 함수에서는 Direct VPC 이그레스를 사용할 수 없습니다.
  • 직접 VPC 이그레스와 서버리스 VPC 액세스 커넥터를 동시에 사용할 수는 없습니다. 자세한 내용은 직접 VPC 이그레스와 VPC 커넥터 비교를 참고하세요.

시작하기 전에

  • Cloud Functions API를 사용 설정합니다.
  • Google Cloud CLI를 설치한 후 gcloud init을 실행하여 초기화합니다.
  • gcloud 구성요소를 버전 545.0.0 이상으로 업데이트합니다.

    gcloud components update
    

  • 프로젝트에 VPC 네트워크가 아직 없는 경우 VPC 네트워크를 만듭니다.

  • 선택사항: 함수가 내부 IP 주소를 사용하여 Google API 및 서비스에 액세스해야 하는 경우 직접 VPC 이그레스에 사용하는 서브넷에서 비공개 Google 액세스를 사용 설정합니다.

IAM 권한 설정

직접 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 함수를 배포하는 프로젝트 번호

Direct 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 명령어를 참조하세요.

Direct 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 서비스를 만든 다음 직접 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을 방문하여 함수를 호출합니다. 함수는 내부 백엔드 서비스를 호출하고 응답을 반환합니다.

다음 단계