Como configurar um serviço do Cloud Run para acessar um serviço interno do Cloud Run usando saída de VPC direta

1. Introdução

Visão geral

Para proteger o tráfego de rede dos serviços e aplicativos, muitas organizações usam uma rede de nuvem privada virtual (VPC) no Google Cloud com controles de perímetro para evitar a exfiltração de dados. Uma rede VPC é uma versão virtual de uma rede física, implementada dentro da rede de produção do Google. Uma rede VPC oferece conectividade para suas instâncias de máquina virtual (VM) do Compute Engine, balanceadores de carga de rede de passagem interna nativos e sistemas de proxy para balanceadores de carga de aplicativo internos, se conecta a redes locais usando túneis do Cloud VPN e anexos de VLAN para o Cloud Interconnect e distribui o tráfego dos balanceadores de carga externos do Google Cloud para back-ends.

Ao contrário das VMs, os serviços do Cloud Run não são associados a nenhuma rede VPC específica por padrão. Este codelab demonstra como mudar as configurações de entrada (conexões de entrada) para que apenas o tráfego de uma VPC possa acessar um serviço do Cloud Run (por exemplo, um serviço de back-end). Além disso, este codelab mostra como ter um segundo serviço (por exemplo, um serviço de front-end) acessando o serviço de back-end do Cloud Run por uma VPC.

Neste exemplo, o serviço de back-end do Cloud Run retorna "hello world". O serviço de front-end do Cloud Run fornece um campo de entrada na interface para coletar um URL. Em seguida, o serviço de front-end faz uma solicitação GET para esse URL (por exemplo, o serviço de back-end), transformando isso em uma solicitação de serviço para serviço (em vez de uma solicitação de navegador para serviço). Quando o serviço de front-end consegue alcançar o back-end, a mensagem "Hello World" aparece no navegador.

O que você vai aprender

  • Como permitir apenas o tráfego de uma VPC para seu serviço do Cloud Run
  • Como configurar a saída em um serviço do Cloud Run para se comunicar com um serviço do Cloud Run somente de entrada interna

2. Configuração e requisitos

Pré-requisitos

Ativar o Cloud Shell

  1. No Console do Cloud, clique em Ativar o Cloud Shelld1264ca30785e435.png.

cb81e7c8e34bc8d.png

Se esta for a primeira vez que você inicia o Cloud Shell, uma tela intermediária vai aparecer com a descrição dele. Se isso acontecer, clique em Continuar.

d95252b003979716.png

Leva apenas alguns instantes para provisionar e se conectar ao Cloud Shell.

7833d5e1c5d18f54.png

Essa máquina virtual contém todas as ferramentas de desenvolvimento necessárias. Ela oferece um diretório principal persistente de 5 GB, além de ser executada no Google Cloud. Isso aprimora o desempenho e a autenticação da rede. Neste codelab, quase todo o trabalho pode ser feito com um navegador.

Depois de se conectar ao Cloud Shell, você vai ver que sua conta já está autenticada e que o projeto está configurado com o ID do seu projeto.

  1. Execute o seguinte comando no Cloud Shell para confirmar se a conta está autenticada:
gcloud auth list

Resposta ao comando

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Execute o comando a seguir no Cloud Shell para confirmar se o comando gcloud sabe sobre seu projeto:
gcloud config list project

Resposta ao comando

[core]
project = <PROJECT_ID>

Se o projeto não estiver configurado, configure-o usando este comando:

gcloud config set project <PROJECT_ID>

Resposta ao comando

Updated property [core/project].

3. Criar os serviços do Cloud Run

Configurar as variáveis de ambiente.

Você pode definir variáveis de ambiente que serão usadas ao longo deste codelab.

REGION=<YOUR_REGION, e.g. us-central1>
FRONTEND=frontend
BACKEND=backend

Criar o serviço de back-end do Cloud Run

Primeiro, crie um diretório para o código-fonte e use cd para acessar esse diretório.

mkdir -p internal-codelab/frontend internal-codelab/backend && cd internal-codelab/backend

Em seguida, crie um arquivo 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"
    }
}

Em seguida, crie um arquivo de origem index.js com o conteúdo abaixo. Esse arquivo contém o ponto de entrada do serviço e a lógica principal do app.

const express = require('express');

const app = express();

app.use(express.urlencoded({ extended: true }));

app.get('/', function (req, res) {
    res.send("hello world");
});

const port = parseInt(process.env.PORT) || 8080;
app.listen(port, () => {
    console.log(`helloworld: listening on port ${port}`);
});

Por fim, implante o serviço do Cloud Run executando o seguinte comando.

gcloud run deploy $BACKEND --source . --allow-unauthenticated --region $REGION

Criar o serviço de front-end do Cloud Run

Navegue até o diretório do front-end.

cd ../frontend

Em seguida, crie um arquivo package.json com o seguinte conteúdo:

{
  "name": "frontend",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "start": "node index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "axios": "^1.6.6",
    "express": "^4.18.2"
  }
}

Em seguida, crie um arquivo de origem index.js com o conteúdo abaixo. Esse arquivo contém o ponto de entrada do serviço e a lógica principal do app.

const express = require("express");
const app = express();
const port = 8080;
const path = require('path');
const axios = require('axios');

// serve static content (index.html) using
// built-in middleware function in Express 
app.use(express.static('public'));
app.use(express.urlencoded({ extended: true }));

// this endpoint receives a URL in the post body
// and then makes a get request to that URL
// results are sent back to the caller
app.post('/callService', async (req, res) => {

    const url = req.body.url;
    let message = "";

    try {
        console.log("url: ", url);
        const response = await axios.get(url);
        message = response.data;

    } catch (error) {
        message = error.message;
        console.error(error.message);
    }

    res.send(`
        ${message}
        <p>
        </p>
    `);
});

app.listen(port, () => {
    console.log(`Example app listening on port ${port}`);
});

Criar um diretório público para o arquivo index.html

mkdir public
touch public/index.html

E atualize o index.html para conter o seguinte:

<html>
  <script
    src="https://unpkg.com/htmx.org@1.9.10"
    integrity="sha384-D1Kt99CQMDuVetoL1lrYwg5t+9QdHe7NLX/SoJYkXDFfX37iInKRy5xLSi8nO7UC"
    crossorigin="anonymous"
  ></script>
  <body>
    <div style="margin-top: 100px; margin-left: 100px">
      <h1>I'm the Frontend service on the Internet</h1>
      <form hx-trigger="submit" hx-post="/callService" hx-target="#message">
        <label for="url"> URL:</label>
        <input
          style="width: 308px"
          type="text"
          id="url"
          name="url"
          placeholder="The backend service URL"
          required
        />
        <button hx-indicator="#loading" type="submit">Submit</button>
        <p></p>
        <span class="htmx-indicator" id="loading"> Loading... </span>
        <div id="message" style="white-space: pre-wrap"></div>
        <p></p>
      </form>
    </div>
  </body>
</html>

Por fim, implante o serviço do Cloud Run executando o seguinte comando.

gcloud run deploy $FRONTEND --source . --allow-unauthenticated --region $REGION

Chamar o serviço de back-end

Verifique se você implantou dois serviços do Cloud Run.

Abra o URL do serviço de front-end no navegador da Web.

Na caixa de texto, insira o URL do serviço de back-end. Essa solicitação é encaminhada da instância do Cloud Run de front-end para o serviço do Cloud Run de back-end, em vez de ser encaminhada do navegador.

Você vai ver "hello world".

4. Definir o serviço de back-end somente para entrada interna

Execute o seguinte comando gcloud para permitir apenas o tráfego da sua rede VPC para acessar o serviço de back-end.

gcloud run services update $BACKEND --ingress internal --region $REGION

Para confirmar que o serviço de back-end só pode receber tráfego da VPC, tente chamar o serviço de back-end do serviço de front-end novamente.

Desta vez, você vai ver "Request failed with status code 404"

Você recebeu esse erro porque a solicitação de saída do serviço de front-end do Cloud Run (ou seja, saída) vai primeiro para a Internet. Assim, o Google Cloud não sabe a origem da solicitação.

Na próxima seção, você vai configurar o serviço de front-end para acessar a VPC. Assim, o Google Cloud saberá que a solicitação veio da VPC, que é reconhecida como uma fonte interna.

5. Configurar o serviço de front-end para acessar a VPC

Nesta seção, você vai configurar o serviço de front-end do Cloud Run para se comunicar com o serviço de back-end por uma VPC.

Para isso, adicione a saída VPC direta às instâncias do Cloud Run de front-end para dar ao serviço um IP interno para uso na VPC. Em seguida, você vai configurar a saída para que todas as conexões de saída do serviço de front-end sejam direcionadas à VPC.

Primeiro, execute este comando para ativar a saída direta da VPC:

gcloud beta run services update $FRONTEND \
--network=default \
--subnet=default \
--vpc-egress=all-traffic \
--region=$REGION

Agora você pode confirmar se o serviço de front-end tem acesso à VPC:

gcloud beta run services describe $FRONTEND \
--region=$REGION

Você vai ver uma saída semelhante a

VPC access:
    Network:         default
    Subnet:          default
    Egress:          all-traffic

Agora tente chamar o serviço de back-end do serviço de front-end novamente.

Desta vez, você vai ver "hello world".

Observação: seu serviço de front-end não terá acesso à Internet, já que toda a saída foi roteada para a VPC. Por exemplo, o serviço de front-end vai atingir o tempo limite se tentar acessar https://curlmyip.org/.

6. Parabéns!

Parabéns por concluir o codelab!

Recomendamos consultar a documentação do Cloud Run e como configurar redes particulares para serviços do Cloud Run.

O que vimos

  • Como permitir apenas o tráfego de uma VPC para seu serviço do Cloud Run
  • Como configurar a saída em um serviço do Cloud Run para se comunicar com um serviço do Cloud Run somente de entrada interna

7. Limpar

Para evitar cobranças acidentais, por exemplo, se os serviços do Cloud Run forem invocados mais vezes do que sua alocação mensal de invocações do Cloud Run no nível sem custo financeiro, exclua o Cloud Run ou o projeto criado na etapa 2.

Para excluir o serviço do Cloud Run, acesse o console do Cloud Run em https://console.cloud.google.com/run e exclua os serviços $FRONTEND e $BACKEND.

Se você quiser excluir todo o projeto, acesse https://console.cloud.google.com/cloud-resource-manager, selecione o projeto criado na Etapa 2 e escolha "Excluir". Se você excluir o projeto, vai precisar mudar de projeto no SDK Cloud. Para conferir a lista de todos os projetos disponíveis, execute gcloud projects list.