Configure a saída da VPC direta para funções de 2.ª geração

A saída direta da VPC permite-lhe encaminhar o tráfego da sua função do Cloud Run (2.ª geração) diretamente para a sua rede VPC.

Limitações

  • A saída direta da VPC não está disponível para funções de 1.ª geração.
  • Não pode usar a saída da VPC direta e os conetores do Acesso a VPC sem servidor ao mesmo tempo. Consulte o artigo Compare a saída da VPC direta e os conetores da VPC para ver detalhes.

Antes de começar

  • Ative a Cloud Functions API.
  • Instale a CLI Google Cloud e, em seguida, inicialize-a executando gcloud init.
  • Atualize os componentes gcloud para a versão 545.0.0 ou posterior:

    gcloud components update
    

  • Se ainda não tiver uma rede VPC no seu projeto, crie uma.

  • Opcional: se a sua função precisar de aceder a APIs e serviços Google através dos respetivos endereços IP internos, ative o acesso privado Google na sub-rede que usa para a saída do VPC direta.

Configure as autorizações de IAM

Para autorizar a saída da VPC direta, peça ao seu administrador para conceder a função Cloud Run Invoker (roles/run.invoker) à conta de serviço da sua função.

Certifique-se de que o Cloud Run tem acesso à rede VPC através de um dos seguintes métodos:

  • Função de agente de serviço do Cloud Run: por predefinição, o agente de serviço do Cloud Run tem a função de agente de serviço do Cloud Run (roles/run.serviceAgent) que contém as autorizações necessárias.

  • Autorizações personalizadas: para um controlo mais detalhado, conceda ao agente do serviço do Cloud Run as seguintes autorizações adicionais no projeto:

    • compute.networks.get
    • compute.subnetworks.get
    • compute.subnetworks.use no projeto ou na sub-rede específica
    • compute.addresses.get
    • compute.addresses.list
    • compute.addresses.create (obrigatório apenas para sub-redes de pilha dupla com IPv6 externo)
    • compute.addresses.delete (obrigatório apenas para sub-redes de pilha dupla com IPv6 externo)
    • compute.addresses.createInternal
    • compute.addresses.deleteInternal
    • compute.regionOperations.get
  • Função de utilizador da rede de computação: se não usar a função de agente de serviço do Cloud Run predefinida ou as autorizações personalizadas, conceda a função de utilizador da rede de computação (roles/compute.networkUser) à conta de serviço do agente de serviço do Cloud Run. As sub-redes com IPv6 externo também requerem a função de administrador de IP público do Compute (roles/compute.publicIpAdmin).

    Por exemplo, para conceder a função de utilizador da rede de computação, execute o seguinte comando:

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

    Substitua o seguinte:

    • PROJECT_ID: o ID do seu projeto.
    • PROJECT_NUMBER: o número do projeto onde implementa a sua função do Cloud Run.

Configure a saída da VPC direta

Configure a saída da VPC direta para funções de 2.ª geração novas ou existentes.

gcloud

  1. Para configurar a saída da VPC direta quando implementa uma função, use o comando gcloud beta functions deploy com flags para as definições de rede.

    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
    

    Substitua o seguinte:

    • FUNCTION_NAME: o nome da sua função.
    • RUNTIME: o tempo de execução da sua função, por exemplo, nodejs20.
    • REGION: a região onde implementa a sua função.
    • Opcional: NETWORK com o nome da sua rede de VPC. Especifique uma rede de VPC ou uma sub-rede, ou ambas. Se especificar apenas uma rede, a sub-rede usa o mesmo nome que a rede.
    • Opcional: SUBNET com o nome da sua sub-rede. Especifique uma rede de VPC ou uma sub-rede, ou ambas. Se especificar apenas uma rede, a sub-rede usa o mesmo nome que a rede. Pode implementar ou executar várias funções na mesma sub-rede.
    • Opcional: NETWORK_TAG_NAMES com os nomes separados por vírgulas das etiquetas de rede que quer associar a uma função. Cada função pode ter etiquetas de rede diferentes, como network-tag-2.
    • EGRESS_SETTING com um valor de definição de saída:
      • all: predefinição. Envia todo o tráfego de saída através da rede VPC.
      • private-ranges-only: envia apenas tráfego para endereços internos através da rede VPC.
  2. Opcional: para remover todas as definições de saída da VPC direta de uma função, implemente novamente a função com as flags --clear-network e --clear-network-tags.

Terraform

Para saber como aplicar ou remover uma configuração do Terraform, consulte os comandos básicos do Terraform.

Para configurar a saída da VPC direta, use o fornecedor google-beta Terraform.

Usando as funções do Cloud Run (2.ª geração) Exemplo de saída direta da VPC como ponto de partida, atualize os seguintes campos:

  • service_config.network: o nome da sua rede VPC.
  • service_config.subnetwork: o nome da sua sub-rede de VPC.
  • service_config.direct_vpc_egress: que tráfego enviar para a rede VPC. VPC_EGRESS_ALL_TRAFFIC envia todo o tráfego de saída através da rede VPC. VPC_EGRESS_PRIVATE_RANGES_ONLY envia tráfego apenas para intervalos de endereços IP privados para a rede VPC.

Exemplo: chamar um serviço interno a partir de uma função

Este exemplo mostra como criar um serviço interno do Cloud Run e, em seguida, chamá-lo a partir de uma função do Cloud Run (2.ª geração) que usa a saída da VPC direta.

Crie o serviço de back-end interno

  1. Crie um novo diretório para o serviço de back-end e mude para o mesmo:

    mkdir backend-service
    cd backend-service
    
  2. Crie um ficheiro package.json com o seguinte conteúdo:

    {
        "name": "backend-service",
        "version": "1.0.0",
        "description": "",
        "scripts": {
            "start": "node index.js"
        },
        "dependencies": {
            "express": "^4.18.1"
        }
    }
    
  3. Crie um ficheiro index.js com o seguinte conteúdo:

    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. Implemente o serviço no Cloud Run com entrada interna:

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

    Substitua REGION pela sua região, por exemplo, us-west1.

  5. Guarde o URL do novo serviço. Precisa dele na secção seguinte.

Crie e implemente a função

  1. Crie um novo diretório para a função e mude para o mesmo:

    cd ..
    mkdir dvpc-function
    cd dvpc-function
    
  2. Crie um ficheiro package.json com o seguinte conteúdo:

    {
      "name": "sample-http",
      "version": "0.0.1",
      "dependencies": {
        "axios": "0.21.1",
        "@google-cloud/functions-framework": "^3.0.0"
      }
    }
    
  3. Crie um ficheiro index.js com o seguinte conteúdo. Este código faz um pedido autenticado ao serviço de back-end interno.

    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. Implemente a função com a saída da VPC direta configurada para encaminhar todo o tráfego para a sua rede VPC predefinida:

    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
    

    Substitua o seguinte:

    • REGION: a região onde implementou o serviço de back-end.
    • BACKEND_URL: o URL do serviço de back-end que criou.
  5. Depois de implementar a função, invoque-a visitando o respetivo URL. A função chama o serviço de back-end interno e devolve a respetiva resposta.

O que se segue?