Come configurare un servizio Cloud Run per accedere a un servizio Cloud Run interno utilizzando VPC diretto in uscita

1. Introduzione

Panoramica

Per proteggere il traffico di rete per i propri servizi e applicazioni, molte organizzazioni utilizzano una rete Virtual Private Cloud (VPC) su Google Cloud con controlli perimetrali per impedire l'esfiltrazione di dati. Una rete VPC è una versione virtuale di una rete fisica implementata all'interno della rete di produzione di Google. Una rete VPC fornisce connettività per le istanze di macchine virtuali (VM) Compute Engine, offre bilanciatori del carico di rete pass-through interni nativi e sistemi proxy per i bilanciatori del carico delle applicazioni interni, si connette alle reti on-premise utilizzando i tunnel Cloud VPN e i collegamenti VLAN per Cloud Interconnect e distribuisce il traffico dai bilanciatori del carico esterni di Google Cloud ai backend.

A differenza delle VM, i servizi Cloud Run non sono associati a nessuna rete VPC specifica per impostazione predefinita. Questo codelab mostra come modificare le impostazioni di Ingress (connessioni in entrata) in modo che solo il traffico proveniente da un VPC possa accedere a un servizio Cloud Run (ad es. un servizio di backend). Inoltre, questo codelab mostra come fare in modo che un secondo servizio (ad es. un servizio frontend) acceda al servizio Cloud Run di backend tramite un VPC.

In questo esempio, il servizio Cloud Run di backend restituisce "hello world". Il servizio Cloud Run di frontend fornisce un campo di immissione nell'interfaccia utente per raccogliere un URL. Quindi il servizio frontend effettua una richiesta GET a quell'URL (ad es. il servizio di backend), rendendola una richiesta da servizio a servizio (anziché una richiesta da browser a servizio). Quando il servizio frontend riesce a raggiungere il backend, nel browser viene visualizzato il messaggio "hello world".

Cosa imparerai a fare

  • Come consentire solo il traffico da un VPC al tuo servizio Cloud Run
  • Come configurare il traffico in uscita su un servizio Cloud Run per comunicare con un servizio Cloud Run solo con traffico in entrata interno

2. Configurazione e requisiti

Prerequisiti

Attiva Cloud Shell

  1. Nella console Cloud, fai clic su Attiva Cloud Shell d1264ca30785e435.png.

cb81e7c8e34bc8d.png

Se è la prima volta che avvii Cloud Shell, viene visualizzata una schermata intermedia che ne descrive le funzionalità. Se hai visualizzato una schermata intermedia, fai clic su Continua.

d95252b003979716.png

Bastano pochi istanti per eseguire il provisioning e connettersi a Cloud Shell.

7833d5e1c5d18f54.png

Questa macchina virtuale è dotata di tutti gli strumenti di sviluppo necessari. Offre una home directory persistente di 5 GB ed è in esecuzione su Google Cloud, migliorando notevolmente le prestazioni di rete e l'autenticazione. Gran parte del lavoro per questo codelab, se non tutto, può essere svolto con un browser.

Una volta eseguita la connessione a Cloud Shell, dovresti vedere che il tuo account è autenticato e il progetto è impostato sul tuo ID progetto.

  1. Esegui questo comando in Cloud Shell per verificare che l'account sia autenticato:
gcloud auth list

Output comando

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Esegui questo comando in Cloud Shell per verificare che il comando gcloud conosca il tuo progetto:
gcloud config list project

Output comando

[core]
project = <PROJECT_ID>

In caso contrario, puoi impostarlo con questo comando:

gcloud config set project <PROJECT_ID>

Output comando

Updated property [core/project].

3. Crea i servizi Cloud Run

Imposta le variabili di ambiente

Puoi impostare le variabili di ambiente che verranno utilizzate durante questo codelab.

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

Crea il servizio Cloud Run di backend

Innanzitutto, crea una directory per il codice sorgente e passa a questa directory.

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

Quindi, crea un file package.json con i seguenti contenuti:

{
    "name": "backend-service",
    "version": "1.0.0",
    "description": "",
    "scripts": {
        "start": "node index.js"
    },
    "dependencies": {
        "express": "^4.18.1"
    }
}

Poi, crea un file sorgente index.js con i contenuti riportati di seguito. Questo file contiene il punto di ingresso del servizio e la logica principale dell'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}`);
});

Infine, esegui il deployment del servizio Cloud Run eseguendo il seguente comando.

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

Crea il servizio Cloud Run di frontend

Vai alla directory frontend.

cd ../frontend

Quindi, crea un file package.json con i seguenti contenuti:

{
  "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"
  }
}

Poi, crea un file sorgente index.js con i contenuti riportati di seguito. Questo file contiene il punto di ingresso del servizio e la logica principale dell'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}`);
});

Crea una directory pubblica per il file index.html

mkdir public
touch public/index.html

Aggiorna il file index.html in modo che contenga quanto segue:

<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>

Infine, esegui il deployment del servizio Cloud Run eseguendo il seguente comando.

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

Chiama il servizio di backend

Verifica di aver eseguito il deployment di due servizi Cloud Run.

Apri l'URL del servizio frontend nel browser web.

Nella casella di testo, inserisci l'URL del servizio di backend. Tieni presente che questa richiesta viene instradata dall'istanza Cloud Run di frontend al servizio Cloud Run di backend, anziché dal browser.

Vedrai "hello world".

4. Imposta il servizio di backend solo per il traffico in entrata interno

Esegui il seguente comando gcloud per consentire l'accesso al servizio di backend solo al traffico proveniente dalla rete VPC.

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

Per verificare che il servizio di backend possa ricevere traffico solo dal VPC, prova di nuovo a chiamare il servizio di backend dal servizio frontend.

Questa volta vedrai "Request failed with status code 404"

Hai ricevuto questo errore perché la richiesta in uscita (ovvero il traffico in uscita) del servizio Cloud Run di frontend viene inviata prima a internet, quindi Google Cloud non conosce l'origine della richiesta.

Nella sezione successiva, configurerai il servizio frontend per accedere al VPC, in modo che Google Cloud sappia che la richiesta proviene dal VPC, che viene riconosciuto come origine interna.

5. Configura il servizio frontend per accedere al VPC

In questa sezione configurerai il servizio Cloud Run di frontend per comunicare con il servizio di backend tramite un VPC.

Per farlo, devi aggiungere il traffico in uscita VPC diretto alle istanze Cloud Run di frontend per assegnare al servizio un IP interno da utilizzare all'interno del VPC. Poi, configurerai il traffico in uscita in modo che tutte le connessioni in uscita dal servizio frontend vengano inviate al VPC.

Innanzitutto, esegui questo comando per abilitare il traffico in uscita VPC diretto:

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

Ora puoi verificare che il servizio frontend abbia accesso al VPC:

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

Dovresti vedere un output simile a

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

Ora prova di nuovo a chiamare il servizio di backend dal servizio frontend.

Questa volta vedrai "hello world".

Nota: il servizio frontend non avrà accesso a internet perché tutto il traffico in uscita è stato instradato al VPC. Ad esempio, il servizio frontend andrà in timeout se tenta di accedere a https://curlmyip.org/.

6. Complimenti!

Complimenti per aver completato il codelab.

Ti consigliamo di consultare la documentazione su Cloud Run e su come configurare la rete privata per i servizi Cloud Run.

Argomenti trattati

  • Come consentire solo il traffico da un VPC al tuo servizio Cloud Run
  • Come configurare il traffico in uscita su un servizio Cloud Run per comunicare con un servizio Cloud Run solo con traffico in entrata interno

7. Libera spazio

Per evitare addebiti involontari (ad esempio, se i servizi Cloud Run vengono richiamati inavvertitamente più volte rispetto a all'allocazione mensile di richiami di Cloud Run nel livello senza costi), puoi eliminare Cloud Run o il progetto creato nel passaggio 2.

Per eliminare il servizio Cloud Run, vai a Cloud Run Cloud Console all'indirizzo https://console.cloud.google.com/run ed elimina i servizi $FRONTEND e $BACKEND.

Se scegli di eliminare l'intero progetto, puoi andare all'indirizzo https://console.cloud.google.com/cloud-resource-manager, selezionare il progetto creato nel passaggio 2 e scegliere Elimina. Se elimini il progetto, dovrai cambiare progetto in Cloud SDK. Puoi visualizzare l'elenco di tutti i progetti disponibili eseguendo gcloud projects list.