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

Zum Schutz des Netzwerkverkehrs für ihre Dienste und Anwendungen verwenden viele Unternehmen ein Virtual Private Cloud-Netzwerk (VPC) in Google Cloud mit Perimeterkontrollen, um Daten-Exfiltrationen zu verhindern. Ein VPC-Netzwerk ist eine virtuelle Version eines physischen Netzwerks, die innerhalb des Produktionsnetzwerks von Google implementiert wurde. Ein VPC-Netzwerk bietet Konnektivität für Ihre Compute Engine-VM-Instanzen, 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 Traffic von externen Google Cloud-Load Balancern auf Backends.

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

In diesem Beispiel gibt der Backend-Cloud-Run-Dienst „Hello World“ zurück. Der Frontend-Cloud Run-Dienst stellt in der Benutzeroberfläche ein Eingabefeld zum Erfassen einer URL bereit. Der Frontend-Dienst sendet dann eine GET-Anfrage an diese URL (z. B. an den Backend-Dienst). Es handelt sich also um eine Dienst-zu-Dienst-Anfrage (und nicht um eine Browser-zu-Dienst-Anfrage). Wenn der Frontend-Dienst das Backend erfolgreich erreichen kann, wird im Browser die Meldung „Hello World“ angezeigt.

Lerninhalte

  • Nur Traffic von einer VPC für Ihren Cloud Run-Dienst zulassen
  • Ausgehenden Traffic für einen Cloud Run-Dienst konfigurieren, um mit einem Cloud Run-Dienst zu kommunizieren, der nur eingehenden internen Traffic akzeptiert

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 Fenster mit einer Beschreibung eingeblendet. Klicken Sie in diesem Fall einfach auf Weiter.

d95252b003979716.png

Das Herstellen der Verbindung mit der Cloud Shell sollte nur wenige Augenblicke dauern.

7833d5e1c5d18f54.png

Auf dieser virtuellen Maschine sind alle erforderlichen Entwicklungstools installiert. Sie bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und läuft in Google Cloud, was die Netzwerkleistung und Authentifizierung erheblich verbessert. Die meisten, wenn nicht sogar alle Aufgaben in diesem Codelab können mit einem Browser erledigt werden.

Sobald die Verbindung mit der Cloud Shell hergestellt ist, sehen Sie, dass Sie authentifiziert sind und für das Projekt Ihre Projekt-ID eingestellt ist.

  1. Führen Sie in der 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 den folgenden Befehl in Cloud Shell aus, um zu bestätigen, dass 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 zuerst ein Verzeichnis für den Quellcode und wechseln Sie in dieses Verzeichnis.

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 dem folgenden Inhalt. Diese Datei enthält den Einstiegspunkt für den Dienst und die Hauptlogik für die 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}`);
});

Stellen Sie schließlich den Cloud Run-Dienst mit dem folgenden Befehl bereit.

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

Cloud Run-Front-End-Dienst erstellen

Wechseln Sie zum Frontend-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 dem folgenden Inhalt. Diese Datei enthält den Einstiegspunkt für den Dienst und die Hauptlogik für die 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}`);
});

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

mkdir public
touch public/index.html

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 schließlich den Cloud Run-Dienst mit dem folgenden Befehl bereit.

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 Frontend-Dienstes in Ihrem Webbrowser.

Geben Sie im Textfeld die URL für den Backend-Dienst ein. Diese Anfrage wird von der Frontend-Cloud Run-Instanz an den Backend-Cloud Run-Dienst weitergeleitet und nicht von Ihrem Browser.

Es wird „hello world“ angezeigt.

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

Führen Sie den folgenden gcloud-Befehl aus, um nur Traffic aus Ihrem VPC-Netzwerk den Zugriff auf Ihren Backend-Dienst zu erlauben.

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

Um zu bestätigen, dass Ihr Back-End-Dienst nur Traffic von Ihrer VPC empfangen kann, versuchen Sie noch einmal, Ihren Back-End-Dienst über Ihren Front-End-Dienst aufzurufen.

Dieses Mal wird „Anfrage mit Statuscode 404 fehlgeschlagen“ angezeigt.

Sie haben diesen Fehler erhalten, weil die ausgehende Anfrage (Egress) des Frontend-Cloud Run-Dienstes zuerst ins Internet geht. Google Cloud kennt daher den Ursprung der Anfrage nicht.

Im nächsten Abschnitt konfigurieren Sie den Frontend-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 Ihren Frontend-Cloud Run-Dienst so, dass er über eine VPC mit Ihrem Backend-Dienst kommuniziert.

Dazu müssen Sie Ihren Frontend-Cloud Run-Instanzen direkten ausgehenden VPC-Traffic hinzufügen, damit Ihr Dienst eine interne IP-Adresse für die Verwendung in der VPC erhält. Anschließend konfigurieren Sie den ausgehenden Traffic so, dass alle ausgehenden Verbindungen vom Frontend-Dienst zur VPC geleitet werden.

Führen Sie zuerst diesen Befehl aus, um den direkten VPC-Ausgang 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 Frontend-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, Ihren Backend-Dienst über Ihren Frontend-Dienst aufzurufen.

Dieses Mal wird „hello world“ angezeigt.

Hinweis: Ihr Frontend-Dienst hat keinen Internetzugriff, da der gesamte ausgehende Traffic an die VPC weitergeleitet wurde. Ihr Frontend-Dienst hat beispielsweise ein Zeitlimit, wenn er versucht, auf „https://curlmyip.org/“ zuzugreifen.

6. Glückwunsch!

Herzlichen Glückwunsch zum Abschluss des Codelabs!

Wir empfehlen, die Dokumentation zu Cloud Run und zur Konfiguration privater Netzwerke für Cloud Run-Dienste zu lesen.

Behandelte Themen

  • Nur Traffic von einer VPC für Ihren Cloud Run-Dienst zulassen
  • Ausgehenden Traffic für einen Cloud Run-Dienst konfigurieren, um mit einem Cloud Run-Dienst zu kommunizieren, der nur eingehenden internen Traffic akzeptiert

7. Bereinigen

Damit Ihnen keine unbeabsichtigten Gebühren in Rechnung gestellt werden (z. B. wenn die Cloud Run-Dienste versehentlich öfter aufgerufen werden als Ihre monatliche Cloud Run-Aufrufkontingent im kostenlosen Kontingent), können Sie entweder den Cloud Run-Dienst 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 Dienste $FRONTEND und $BACKEND.

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