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 tue istanze di macchine virtuali (VM) Compute Engine, offre bilanciatori del carico di rete passthrough interni nativi e sistemi proxy per bilanciatori del carico delle applicazioni interni, si connette alle reti on-premise utilizzando tunnel Cloud VPN e 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 una particolare rete VPC per impostazione predefinita. Questo codelab mostra come modificare le impostazioni di traffico in entrata (connessioni in entrata) in modo che solo il traffico proveniente da un VPC possa accedere a un servizio Cloud Run (ad es. a 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 di backend Cloud Run restituisce hello world. Il servizio Cloud Run frontend fornisce un campo di immissione nella UI per raccogliere un URL. Quindi il servizio frontend effettua una richiesta GET a quell'URL (ad es. il servizio di backend), rendendola quindi una richiesta da servizio a servizio (anziché una richiesta da browser a servizio). Quando il servizio di 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 servizio Cloud Run
  • Come configurare il traffico in uscita su un servizio Cloud Run per comunicare con un servizio Cloud Run solo interno in entrata

2. Configurazione e requisiti

Prerequisiti

Attiva Cloud Shell

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

cb81e7c8e34bc8d.png

Se è la prima volta che avvii Cloud Shell, ti verrà mostrata una schermata intermedia che descrive di cosa si tratta. Se ti è stata presentata una schermata intermedia, fai clic su Continua.

d95252b003979716.png

Il provisioning e la connessione a Cloud Shell dovrebbero richiedere solo qualche istante.

7833d5e1c5d18f54.png

Questa macchina virtuale viene caricata con tutti gli strumenti di sviluppo necessari. Offre una home directory permanente da 5 GB e viene eseguita in Google Cloud, migliorando notevolmente le prestazioni di rete e l'autenticazione. Gran parte, se non tutto, del lavoro in questo codelab può essere svolto con un browser.

Una volta stabilita la connessione a Cloud Shell, dovresti vedere che hai eseguito l'autenticazione e che 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 confermare che il comando gcloud è a conoscenza del 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

Configura le variabili di ambiente

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

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

Crea il servizio Cloud Run di backend

Per prima cosa, crea una directory per il codice sorgente e accedi a quella 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"
    }
}

A questo punto, crea un file di origine index.js con i contenuti seguenti. 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 questo comando.

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

Crea il servizio Cloud Run frontend

Vai alla directory del 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"
  }
}

A questo punto, crea un file di origine index.js con i contenuti seguenti. 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

Inoltre, 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 questo comando.

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

Chiama il servizio di backend

Verifica di aver eseguito correttamente 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 tuo browser.

Visualizzerai il messaggio "Hello World".

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

Esegui questo comando gcloud per consentire solo al traffico interno alla tua rete VPC di accedere al servizio di backend.

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

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

Questa volta vedrai "Richiesta non riuscita con codice di stato 404".

Hai ricevuto questo errore perché la richiesta in uscita del servizio Cloud Run frontend (ovvero il traffico in uscita) arriva 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 è riconosciuto come origine interna.

5. configura il servizio frontend per accedere al VPC

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

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

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

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

Ora puoi verificare che il tuo 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 poiché tutto il traffico in uscita è stato instradato al VPC. Ad esempio, il servizio frontend scadrà se tenterà di accedere a https://curlmyip.org/.

6. Complimenti!

Complimenti per aver completato il codelab.

Ti consigliamo di consultare la documentazione di Cloud Run e di scoprire come configurare il networking privato per i servizi Cloud Run.

Argomenti trattati

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

7. Esegui la pulizia

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

Per eliminare il servizio Cloud Run, vai alla console Cloud di Cloud Run 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 che hai creato nel passaggio 2 e scegliere Elimina. Se elimini il progetto, dovrai modificarli in Cloud SDK. Puoi visualizzare l'elenco di tutti i progetti disponibili eseguendo gcloud projects list.