Cloud Run-Dienst für den Zugriff auf einen internen Cloud Run-Dienst und das öffentliche Internet konfigurieren

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 und gleichzeitig weiterhin öffentlichen Internetzugriff haben 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. Anschließend sehen Sie, wie Sie einen Aufruf an https://curlmyip.org ausführen können, um die IP-Adresse Ihres Frontend-Dienstes abzurufen.

Lerninhalte

  • Nur Traffic von einer VPC für Ihren Cloud Run-Dienst zulassen
  • Konfiguration des ausgehenden Traffics für einen Cloud Run-Dienst (z.B. Frontend) für die Kommunikation mit einem Cloud Run-Dienst, der nur eingehenden internen Traffic zulässt (z.B. Backend), während der öffentliche Internetzugriff für den Frontend-Dienst beibehalten wird.

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.

PROJECT_ID=<YOUR_PROJECT_ID>
REGION=<YOUR_REGION, e.g. us-central1>
FRONTEND=frontend-with-internet
BACKEND=backend
SUBNET_NAME=default

Cloud Run-Back-End-Dienst erstellen

Erstellen Sie zuerst ein Verzeichnis für den Quellcode und wechseln Sie in dieses Verzeichnis.

mkdir -p egress-private-codelab/frontend-w-internet egress-private-codelab/backend && cd egress-private-codelab/backend

Erstellen Sie dann eine Datei namens `package.json` 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

Rufen Sie das Frontend-Verzeichnis auf.

cd ../frontend-w-internet

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",
    "htmx.org": "^1.9.10"
  }
}

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 index.html so, dass es 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 Request Tester service on the Internet</h1>
      <form hx-trigger="submit" hx-post="/callService" hx-target="#zen">
        <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="zen" 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

In diesem Abschnitt prüfen Sie, ob Sie zwei Cloud Run-Dienste erfolgreich bereitgestellt haben.

Öffnen Sie die URL des Frontend-Dienstes in Ihrem Webbrowser, z. B. https://frontend-your-hash-uc.a.run.app/.

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

Sie können den folgenden gcloud-Befehl ausführen, um einen Cloud Run-Dienst in Ihr privates Netzwerk einzubinden.

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

Wenn Sie versuchen, den Backend-Dienst über den Frontend-Dienst aufzurufen, erhalten Sie einen 404-Fehler. Die ausgehende Verbindung (oder der ausgehende Traffic) des Cloud Run-Frontend-Dienstes wird zuerst ins Internet geleitet. Google Cloud kennt daher den Ursprung der Anfrage nicht.

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 Ihrem Frontend-Cloud Run-Dienst direkten ausgehenden VPC-Traffic hinzufügen, damit er interne IP-Adressen im VPC-Netzwerk erreichen kann. Anschließend konfigurieren Sie den Egress so, dass nur Anfragen an private IP-Adressen an die VPC weitergeleitet werden. Mit dieser Konfiguration kann Ihr Frontend weiterhin auf das öffentliche Internet zugreifen. Weitere Informationen finden Sie in der Dokumentation unter Anfragen von anderen Cloud Run-Diensten empfangen.

Ausgehenden Direct VPC-Traffic konfigurieren

Führen Sie zuerst diesen Befehl aus, um ausgehenden VPC-Traffic für Ihren Frontend-Dienst zu verwenden:

gcloud beta run services update $FRONTEND \
--network=$SUBNET_NAME \
--subnet=$SUBNET_NAME  \
--vpc-egress=private-ranges-only \
--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:          private-ranges-only

Privaten Google-Zugriff aktivieren

Als Nächstes aktivieren Sie den privaten Google-Zugriff für das Subnetz, indem Sie den folgenden Befehl ausführen:

gcloud compute networks subnets update $SUBNET_NAME \
--region=$REGION \
--enable-private-ip-google-access

Sie können prüfen, ob der private Google-Zugriff aktiviert wurde. Führen Sie dazu folgenden Befehl aus:

gcloud compute networks subnets describe $SUBNET_NAME \
--region=$REGION \
--format="get(privateIpGoogleAccess)"

Cloud DNS-Zone für run.app-URLs erstellen

Erstellen Sie schließlich eine Cloud DNS-Zone für run.app-URLs, damit Google Cloud sie als interne IP-Adressen behandeln kann.

In einem vorherigen Schritt haben Sie den direkten VPC-Ausgang auf „Nur private Bereiche“ konfiguriert. Das bedeutet, dass ausgehende Verbindungen von Ihrem Frontend-Dienst nur dann zum VPC-Netzwerk weitergeleitet werden, wenn das Ziel eine interne IP-Adresse ist. Ihr Back-End-Dienst verwendet jedoch eine run.app-URL, die in eine öffentliche IP-Adresse aufgelöst wird.

In diesem Schritt erstellen Sie eine Cloud DNS-Zone für die run.app-URLs, damit sie in die IP-Adressbereiche von private.googleapis.com aufgelöst werden, die als interne IP-Adressen erkannt werden. Alle Anfragen an diese Bereiche werden jetzt über Ihr VPC-Netzwerk weitergeleitet.

Weitere Informationen finden Sie unter https://cloud.google.com/run/docs/securing/private-networking#from-other-services.

# do not include the https:// in your DNS Name
# for example: backend-<hash>-uc.a.run.app
DNS_NAME=<your backend service URL without the https://>

gcloud dns --project=$PROJECT_ID managed-zones create codelab-backend-service \
 --description="" \
 --dns-name="a.run.app." \
 --visibility="private" \
 --networks=$SUBNET_NAME

gcloud dns --project=$PROJECT_ID record-sets create $DNS_NAME. \
--zone="codelab-backend-service" \
 --type="A" \
 --ttl="60" \
--rrdatas="199.36.153.8,199.36.153.9,199.36.153.10,199.36.153.11"

Wenn Sie jetzt versuchen, den Backend-Dienst für Ihre Website zu erreichen, wird „hello world“ zurückgegeben.

Wenn Sie versuchen, über https://curlmyip.org/ auf das Internet zuzugreifen, wird Ihre IP-Adresse angezeigt.

6. Fehlerbehebung

Hier sind einige mögliche Fehlermeldungen, die angezeigt werden können, wenn die Einstellungen nicht richtig konfiguriert wurden.

  • Wenn Sie den Fehler getaddrinfo ENOTFOUND backend-your-hash-uc.a.run.app erhalten, prüfen Sie, ob Sie dem DNS-A-Eintrag „https://“ hinzugefügt haben.
  • Wenn Sie beim Versuch, nach der Konfiguration der Zone auf das Backend zuzugreifen, einen 404-Fehler erhalten, können Sie entweder warten, bis der Cache für den globalen run.app-Eintrag abläuft (z.B. 6 Stunden), oder Sie können eine neue Revision erstellen (und damit den Cache leeren), indem Sie den folgenden Befehl ausführen: gcloud beta run services update $FRONTEND --network=$SUBNET_NAME --subnet=$SUBNET_NAME --vpc-egress=private-ranges-only --region=$REGION

7. Glückwunsch!

Herzlichen Glückwunsch zum Abschluss des Codelabs!

Es empfiehlt sich, die Dokumentation zu Private Networking on Cloud Run (Private Netzwerke in Cloud Run) zu lesen.

Behandelte Themen

  • Nur Traffic von einer VPC für Ihren Cloud Run-Dienst zulassen
  • Konfiguration des ausgehenden Traffics für einen Cloud Run-Dienst (z.B. Frontend) für die Kommunikation mit einem Cloud Run-Dienst, der nur eingehenden internen Traffic zulässt (z.B. Backend), während der öffentliche Internetzugriff für den Frontend-Dienst beibehalten wird.

8. Bereinigen

Damit keine unbeabsichtigten Gebühren anfallen (z. B. wenn dieser Cloud Run-Dienst versehentlich öfter aufgerufen wird als Ihre monatliche Cloud Run-Aufrufkontingent im kostenlosen Kontingent), können Sie entweder den Cloud Run-Dienst oder das Projekt löschen, das Sie in Schritt 2 erstellt haben.

Rufen Sie zum Löschen der Cloud Run-Dienste die Cloud Run Cloud Console unter https://console.cloud.google.com/functions/ auf und löschen Sie die Dienste $FRONTEND und $BACKEND, die Sie in diesem Codelab erstellt haben.

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.