Anleitung zum Konfigurieren eines Cloud Run-Dienstes für den Zugriff auf einen internen Cloud Run-Dienst über ausgehenden VPC-Traffic

1. Einführung

Übersicht

Viele Organisationen verwenden in Google Cloud ein VPC-Netzwerk (Virtual Private Cloud) mit Perimeterkontrollen, um den Daten-Exfiltration zu verhindern, um den Netzwerktraffic für ihre Dienste und Anwendungen zu sichern. Ein VPC-Netzwerk ist eine virtuelle Version eines physischen Netzwerks, das innerhalb des Produktionsnetzwerks von Google implementiert ist. Ein VPC-Netzwerk stellt die Konnektivität für Ihre Compute Engine-VM-Instanzen bereit, bietet native interne Passthrough-Network Load Balancer und Proxysysteme für interne Application Load Balancer, stellt über Cloud VPN-Tunnel und VLAN-Anhänge für Cloud Interconnect eine Verbindung zu lokalen Netzwerken her und verteilt den Traffic von externen Google Cloud-Load-Balancern auf Back-Ends.

Im Gegensatz zu VMs sind Cloud Run-Dienste standardmäßig nicht mit einem bestimmten VPC-Netzwerk verknüpft. In diesem Codelab wird gezeigt, wie Sie die Einstellungen für eingehenden Traffic (Verbindungen für eingehende Verbindungen) so ändern, dass nur Traffic aus einer VPC auf einen Cloud Run-Dienst (z.B. einen Back-End-Dienst) zugreifen kann. Außerdem erfahren Sie in diesem Codelab, wie Sie einen zweiten Dienst (z.B. einen Frontend-Dienst) über eine VPC auf den Cloud Run-Backend-Dienst zugreifen lassen.

In diesem Beispiel gibt der Cloud Run-Dienst für das Back-End "hello world" zurück. Der Cloud Run-Dienst für das Frontend bietet in der UI ein Eingabefeld zum Erfassen einer URL. Dann stellt der Front-End-Dienst eine GET-Anfrage an diese URL (z.B. den Back-End-Dienst) und macht daraus einen Dienst-zu-Dienst-Anfrage (anstatt einen Browser-zu-Dienst-Anfrage). Wenn der Front-End-Dienst das Backend erreichen kann, wird im Browser die Nachricht "hello world" angezeigt.

Aufgaben in diesem Lab

  • Nur Traffic von einer VPC zu Ihrem Cloud Run-Dienst zulassen
  • Ausgehenden Traffic in einem Cloud Run-Dienst konfigurieren, um mit einem Cloud Run-Dienst für eingehenden Traffic zu kommunizieren

2. Einrichtung und Anforderungen

Voraussetzungen

Cloud Shell aktivieren

  1. Klicken Sie in der Cloud Console auf Cloud Shell aktivieren d1264ca30785e435.png.

cb81e7c8e34bc8d.png

Wenn Sie Cloud Shell zum ersten Mal starten, wird ein Zwischenbildschirm mit einer Beschreibung der Funktion angezeigt. Wenn ein Zwischenbildschirm angezeigt wird, klicken Sie auf Weiter.

d95252b003979716.png

Die Bereitstellung und Verbindung mit Cloud Shell dauert nur einen Moment.

7833d5e1c5d18f54.png

Diese virtuelle Maschine verfügt über alle erforderlichen Entwicklertools. Es bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und wird in Google Cloud ausgeführt. Dadurch werden die Netzwerkleistung und die Authentifizierung erheblich verbessert. Viele, wenn nicht sogar alle Arbeiten in diesem Codelab können mit einem Browser erledigt werden.

Sobald Sie mit Cloud Shell verbunden sind, sollten Sie sehen, dass Sie authentifiziert sind und das Projekt auf Ihre Projekt-ID eingestellt ist.

  1. Führen Sie in Cloud Shell den folgenden Befehl aus, um zu prüfen, ob Sie authentifiziert sind:
gcloud auth list

Befehlsausgabe

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Führen Sie in Cloud Shell den folgenden Befehl aus, um zu prüfen, ob der gcloud-Befehl Ihr Projekt kennt:
gcloud config list project

Befehlsausgabe

[core]
project = <PROJECT_ID>

Ist dies nicht der Fall, können Sie die Einstellung mit diesem Befehl vornehmen:

gcloud config set project <PROJECT_ID>

Befehlsausgabe

Updated property [core/project].

3. Cloud Run-Dienste erstellen

Umgebungsvariablen einrichten

Sie können Umgebungsvariablen festlegen, die in diesem Codelab verwendet werden.

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

Cloud Run-Back-End-Dienst erstellen

Erstellen Sie zunächst ein Verzeichnis für den Quellcode und speichern Sie das Verzeichnis mit cd.

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

Erstellen Sie dann eine package.json-Datei mit folgendem Inhalt:

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

Erstellen Sie als Nächstes eine index.js-Quelldatei mit folgendem Inhalt. Diese Datei enthält den Einstiegspunkt für den Dienst und die Hauptlogik für die Anwendung.

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}`);
});

Stellen Sie abschließend den Cloud Run-Dienst bereit, indem Sie den folgenden Befehl ausführen.

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

Cloud Run-Dienst für das Frontend erstellen

Wechseln Sie zum Front-End-Verzeichnis.

cd ../frontend

Erstellen Sie dann eine package.json-Datei mit folgendem Inhalt:

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

Erstellen Sie als Nächstes eine index.js-Quelldatei mit folgendem Inhalt. Diese Datei enthält den Einstiegspunkt für den Dienst und die Hauptlogik für die Anwendung.

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}`);
});

Öffentliches Verzeichnis für die Datei „index.html“ erstellen

mkdir public
touch public/index.html

Und aktualisieren Sie die Datei "index.html" so, dass sie Folgendes enthält:

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

Stellen Sie abschließend den Cloud Run-Dienst bereit, indem Sie den folgenden Befehl ausführen.

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

Back-End-Dienst aufrufen

Prüfen Sie, ob Sie zwei Cloud Run-Dienste erfolgreich bereitgestellt haben.

Öffnen Sie die URL des Front-End-Dienstes in Ihrem Webbrowser.

Geben Sie die URL für den Back-End-Dienst in das Textfeld ein. Beachten Sie, dass diese Anfrage von der Cloud Run-Front-End-Instanz an den Cloud Run-Back-End-Dienst und nicht von Ihrem Browser weitergeleitet wird.

Sie sehen „Hello World“.

4. Back-End-Dienst nur für internen eingehenden Traffic festlegen

Führen Sie den folgenden gcloud-Befehl aus, damit nur Traffic aus Ihrem VPC-Netzwerk auf den Back-End-Dienst zugreifen kann.

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

Um zu bestätigen, dass Ihr Backend-Dienst nur Traffic von Ihrer VPC empfangen kann, versuchen Sie noch einmal, den Backend-Dienst über den Frontend-Dienst aufzurufen.

Dieses Mal wird „Anfrage fehlgeschlagen mit Statuscode 404“ angezeigt

Sie haben diese Fehlermeldung erhalten, weil die ausgehende Anfrage des Cloud Run-Diensts für das Front-End (ausgehender Traffic) zuerst an das Internet gesendet wird und Google Cloud den Ursprung der Anfrage also nicht kennt.

Im nächsten Abschnitt konfigurieren Sie den Front-End-Dienst für den Zugriff auf die VPC, damit Google Cloud weiß, dass die Anfrage aus der VPC stammt, die als interne Quelle erkannt wird.

5. Front-End-Dienst für den Zugriff auf die VPC konfigurieren

In diesem Abschnitt konfigurieren Sie den Cloud Run-Dienst für das Front-End so, dass er über eine VPC mit dem Back-End-Dienst kommuniziert.

Dazu müssen Sie den Cloud Run-Front-End-Instanzen direkten VPC-Traffic hinzufügen und Ihrem Dienst eine interne IP-Adresse zur Verwendung innerhalb der VPC zuweisen. Anschließend konfigurieren Sie den ausgehenden Traffic so, dass alle ausgehenden Verbindungen vom Front-End-Dienst zur VPC geleitet werden.

Führen Sie zuerst diesen Befehl aus, um ausgehenden Traffic über die VPC zu aktivieren:

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

Sie können jetzt bestätigen, dass Ihr Front-End-Dienst Zugriff auf die VPC hat:

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

Die Ausgabe sollte in etwa so aussehen:

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

Versuchen Sie nun noch einmal, den Backend-Dienst von Ihrem Frontend-Dienst aus aufzurufen.

Dieses Mal siehst du „Hello World“.

Hinweis: Ihr Front-End-Dienst hat keinen Internetzugriff, da der gesamte ausgehende Traffic an die VPC weitergeleitet wurde. Ihr Front-End-Dienst führt beispielsweise zu einer Zeitüberschreitung, wenn er versucht, auf https://curlmyip.org/ zuzugreifen.

6. Glückwunsch!

Herzlichen Glückwunsch zum Abschluss des Codelabs!

Weitere Informationen finden Sie in der Dokumentation zu Cloud Run und zum Konfigurieren eines privaten Netzwerks für Cloud Run-Dienste.

Behandelte Themen

  • Nur Traffic von einer VPC zu Ihrem Cloud Run-Dienst zulassen
  • Ausgehenden Traffic in einem Cloud Run-Dienst konfigurieren, um mit einem Cloud Run-Dienst für eingehenden Traffic zu kommunizieren

7. Bereinigen

Um versehentliche Gebühren zu vermeiden, z. B. wenn die Cloud Run-Dienste versehentlich häufiger aufgerufen werden als Ihre monatliche Zuweisung von Cloud Run-Aufrufen in der kostenlosen Stufe, können Sie entweder Cloud Run oder das in Schritt 2 erstellte Projekt löschen.

Wenn Sie den Cloud Run-Dienst löschen möchten, rufen Sie die Cloud Run-Cloud Console unter https://console.cloud.google.com/run auf und löschen Sie die $FRONTEND- und $BACKEND-Dienste.

Wenn Sie das gesamte Projekt löschen möchten, rufen Sie https://console.cloud.google.com/cloud-resource-manager auf, wählen Sie das in Schritt 2 erstellte Projekt aus und klicken Sie auf „Löschen“. Wenn Sie das Projekt löschen, müssen Sie die Projekte in Ihrem Cloud SDK ändern. Sie können die Liste aller verfügbaren Projekte mit dem Befehl gcloud projects list aufrufen.