Cloud Run-Dienst mit einer Sidecar-Datei erstellen

1. Übersicht

Einführung

In diesem Codelab erfahren Sie, wie Sie einen Cloud Run-Dienst bereitstellen, der mehrere Container verwendet. Sie erstellen eine Node.js-Anwendung, die als Cloud Run-Ingress-Container verwendet wird, und eine zusätzliche Node.js-Anwendung, die als Sidecar verwendet wird.

Technische Übersicht

Wenn Sie mehrere Container in einer Cloud Run-Instanz verwenden, wird ein Container als Hauptcontainer für den Web-Ingress verwendet. Die ein oder mehreren zusätzlichen Container werden als Sidecars bezeichnet.

Es gibt zwei Möglichkeiten, wie mehrere Container miteinander kommunizieren können:

  1. Die Container teilen sich die localhost-Netzwerkschnittstelle, sodass alle Container einen Port überwachen können, z.B. localhost:port.
  2. Sie können auch In-Memory-Volumes verwenden und sie in den Containern einbinden, um Dateien freizugeben.

Anwendungsfälle

Da alle Container in der Cloud Run-Instanz die localhost-Netzwerkschnittstelle gemeinsam nutzen, können Sie einen Sidecar-Container vor Ihrem Hauptcontainer verwenden, um Anfragen weiterzuleiten. Solche Proxys können eine zusätzliche Abstraktionsebene für einen effizienteren Datenverkehr zur Anwendung zwischen Client und Servern bieten, indem sie Anfragen abfangen und an den entsprechenden Endpunkt weiterleiten. Sie können beispielsweise das offizielle Nginx-Image von DockerHub verwenden (wie hier gezeigt).

Da mehrere Container kommunizieren können, indem sie Dateien über freigegebene Volumes freigeben, fügen Sie Ihrem Dienst verschiedene Sidecar-Anwendungen hinzu. Sie können beispielsweise Ihren Cloud Run-Dienst so instrumentieren, dass benutzerdefinierte Agents wie OpenTelemetry verwendet werden, um Logs, Messwerte und Traces zu exportieren (OpenTelemetry-Beispiel). Ein weiteres Beispiel ist die Verwendung eines Sidecar, um eine Verbindung zu einer Cloud Spanner PostgreSQL-Datenbank herzustellen (Cloud Spanner Postgress example).

Beispiele in diesem Codelab

In diesem Codelab stellen Sie zuerst einen Cloud Run-Dienst bereit, dessen Ingress-Container über einen localhost-Port mit einem Sidecar kommuniziert. Anschließend aktualisieren Sie den Ingress-Container und den Sidecar, um eine Datei über eine Volumebereitstellung freizugeben.

Lerninhalte

  • Container mit Sidecar erstellen
  • Kommunikation eines Ingress-Containers mit einem Sidecar über „localhost“
  • So können ein Ingress-Container und ein Sidecar-Container eine Datei über ein bereitgestelltes Volume gemeinsam nutzen

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 die 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. Ingress-App erstellen

Umgebungsvariablen festlegen

In diesem Codelab erstellen Sie einige Umgebungsvariablen, um die Lesbarkeit der gcloud-Befehle zu verbessern.

REGION=<YOUR-REGION>
PROJECT_ID=<YOUR-PROJECT-ID>

SERVICE_NAME=sidecar-codelab
REPO_NAME=sidecar-codelab

Artifact Registry-Repository zum Speichern Ihrer Container-Images erstellen

Sie können ein Repository in Artifact Registry erstellen, um Ihre Container-Images für dieses Codelab zu speichern.

gcloud artifacts repositories create $REPO_NAME --repository-format=docker \
--location=$REGION --description="sidecar codelab"

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

{
  "name": "sidecar-codelab",
  "version": "1.0.0",
  "private": true,
  "description": "demonstrates how to use sidecars in cloud run",
  "main": "index.js",
  "author": "Google LLC",
  "license": "Apache-2.0",
  "scripts": {
    "start": "node ingress.js"
  },
  "dependencies": {
    "axios": "^1.6.2",
    "express": "^4.18.2"
  }
}

Erstellen Sie nun eine Datei mit dem Namen ingress.js und mit folgendem Inhalt:

const express = require('express');
const app = express();
const axios = require("axios");

app.get('/', async (req, res) => {

    let response = await axios.get("http://localhost:5000");

    res.send("The sidecar says: " + response.data);
});

const port = parseInt(process.env.PORT) || 8080;
app.listen(port, () => {
    console.log(`Ingress container listening on port ${port}`);
});

Dockerfile für den Ingress-Container erstellen

FROM node:20.10.0-slim
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --production

# Copy local code to the container image.
COPY . .

# Run the web service on container startup.
ENV PORT=8080
CMD [ "npm", "start" ]

Erstellen Sie eine `.dockerignore`-Datei für den Ingress-Container.

# Exclude locally installed dependencies
node_modules/

# Exclude "build-time" ignore files.
.dockerignore
.gcloudignore

# Exclude git history and configuration.
.gitignore

Jetzt können Sie das Image für Ihren Ingress-Container erstellen, indem Sie den folgenden Befehl ausführen:

gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/ingress:latest

4. Sidecar-App erstellen

In diesem Abschnitt erstellen Sie eine zweite Node.js-App, die als Sidecar im Cloud Run-Dienst verwendet wird.

Rufen Sie das Sidecar-Verzeichnis auf.

cd ../sidecar

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

{
  "name": "sidecar-codelab",
  "version": "1.0.0",
  "private": true,
  "description": "demonstrates how to use sidecars in cloud run",
  "main": "index.js",
  "author": "Google LLC",
  "license": "Apache-2.0",
  "scripts": {
    "start": "node sidecar.js"
  },
  "dependencies": {
    "axios": "^1.6.2",
    "express": "^4.18.2"
  }
}

Erstellen Sie nun eine Datei mit dem Namen sidecar.js und mit folgendem Inhalt:

const express = require('express');
const app = express();

app.get('/', async (req, res) => {
    res.send("Hello ingress container! I'm the sidecar.");
});

const port = parseInt(process.env.PORT || 5000);
app.listen(port, () => {
    console.log(`Sidecar container listening on port ${port}`);
});

Dockerfile für den Sidecar-Container erstellen

FROM node:20.10.0-slim
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --production

# Copy local code to the container image.
COPY . .

# Run the web service on container startup.
ENV PORT=5000
CMD [ "npm", "start" ]

Erstellen Sie eine Datei vom Typ „.dockerignore“ für den Sidecar-Container.

# Exclude locally installed dependencies
node_modules/

# Exclude "build-time" ignore files.
.dockerignore
.gcloudignore

# Exclude git history and configuration.
.gitignore

Jetzt können Sie das Image für Ihren Ingress-Container erstellen, indem Sie den folgenden Befehl ausführen:

gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/sidecar:latest

Cloud Run-Dienst bereitstellen

Sie stellen den Cloud Run-Dienst mit einer YAML-Datei bereit.

Wechseln Sie zum übergeordneten Verzeichnis.

cd ..

Erstellen Sie eine Datei mit dem Namen sidecar-codelab.yaml und mit folgendem Inhalt:

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  annotations:
  name: sidecar-codelab
  labels:
    cloud.googleapis.com/location: "<YOUR_REGION>"
spec:
  template:
    spec:
      containers:
        - image: "<YOUR_REGION>-docker.pkg.dev/<YOUR_PROJECT_ID>/sidecar-codelab/ingress:latest"
          ports:
            - containerPort: 8080
        - image: "<YOUR_REGION>-docker.pkg.dev/<YOUR_PROJECT_ID>/sidecar-codelab/sidecar:latest"
          env:
            - name: PORT
              value: "5000"

Stellen Sie den Dienst dann mit dem folgenden Befehl bereit. Sie müssen gcloud beta verwenden, da sich die Volume-Einbindung in der öffentlichen Vorschau befindet.

gcloud beta run services replace sidecar-codelab.yaml

Speichern Sie nach der Bereitstellung die Dienst-URL in einer Umgebungsvariablen.

SERVICE_URL=$(gcloud run services describe $SERVICE_NAME --platform managed --region $REGION --format 'value(status.url)') 

5. Cloud Run-Dienst aufrufen

Jetzt können Sie Ihren Dienst aufrufen, indem Sie Ihr Identitätstoken angeben.

curl -X GET -H "Authorization: Bearer $(gcloud auth print-identity-token)" ${SERVICE_URL}

Ihre Ergebnisse sollten der Beispielausgabe unten ähneln:

The sidecar says: Hello ingress container! I'm the sidecar.

6. Datei über eine Volume-Bereitstellung freigeben

In diesem Abschnitt aktualisieren Sie die Container, um eine Datei über eine Volume-Bereitstellung freizugeben. In diesem Beispiel schreibt der Ingress-Container in eine Datei auf einem freigegebenen Volume. Der Sidecar liest die Datei und gibt ihren Inhalt an den Ingress-Container zurück.

Zuerst aktualisieren Sie den Ingress-Container-Code. Rufen Sie das Ingress-Verzeichnis auf.

cd ../ingress

Ersetzen Sie dann den Inhalt der Datei ingress.js durch Folgendes:

const express = require('express');
const app = express();
const fs = require('fs');
const axios = require("axios");

const filename = "test.txt"

let path = "/my-volume-mount";
app.use(path, express.static(path));

try {
    fs.writeFileSync(`${path}/${filename}`, "The ingress container created this file.");
} catch (err) {
    console.error(err);
}

app.get('/', async (req, res) => {

    let response = await axios.get("http://localhost:5000");

    res.send("The sidecar says: " + response.data);
});

const port = parseInt(process.env.PORT) || 8080;
app.listen(port, () => {
    console.log(`Ingress container listening on port ${port}`);
});

Erstellen Sie das neue Image für Ihren Ingress-Container mit dem folgenden Befehl:

gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/ingress:latest

Wechseln Sie nun zum Sidecar-Verzeichnis:

cd ../sidecar

Aktualisieren Sie sidecar.js mit folgendem Inhalt:

const express = require('express');
const app = express();
const fs = require('fs');

const filename = "test.txt"

let path = "/my-volume-mount";
app.use(path, express.static(path));

async function readFile() {
    try {
        return await fs.readFileSync(`${path}/${filename}`, { encoding: 'utf8' });
    } catch (err) {
        console.log(err);
    }
}

app.get('/', async (req, res) => {
    let contents = await readFile();
    res.send(contents);
});

const port = parseInt(process.env.PORT || 5000);
app.listen(port, () => {
    console.log(`Sidecar container listening on port ${port}`);
});

Erstellen Sie das neue Image für den Sidecar-Container mit dem folgenden Befehl:

gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/sidecar:latest

Aktualisieren Sie sidecar-codelab.yaml mit Folgendem, um ein Volume freizugeben:

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  annotations:
  name: sidecar-codelab
  labels:
    cloud.googleapis.com/location: "<YOUR_REGION>"
spec:
  template:
    spec:
      containers:
        - image: "<YOUR_REGION>-docker.pkg.dev/<YOUR_PROJECT_ID>/sidecar-codelab/ingress:latest"
          ports:
            - containerPort: 8080
          volumeMounts:
            - mountPath: /my-volume-mount
              name: in-memory-1
        - image: "<YOUR_REGION>-docker.pkg.dev/<YOUR_PROJECT_ID>/sidecar-codelab/sidecar:latest"
          env:
            - name: PORT
              value: "5000"
          volumeMounts:
            - mountPath: /my-volume-mount
              name: in-memory-1
      volumes:
        - emptyDir:
            medium: Memory
          name: in-memory-1

Aktualisierte Datei sidecar-codelab.yaml bereitstellen

gcloud beta run services replace sidecar-codelab.yaml

Jetzt können Sie Ihren Dienst aufrufen, indem Sie Ihr Identitätstoken angeben.

curl -X GET -H "Authorization: Bearer $(gcloud auth print-identity-token)" ${SERVICE_URL}

Ihre Ergebnisse sollten der Beispielausgabe unten ähneln:

The sidecar says: the ingress container created this file.

7. Glückwunsch!

Herzlichen Glückwunsch zum Abschluss des Codelabs!

Wir empfehlen, die Dokumentation zu Cloud Run zu lesen, insbesondere zum Bereitstellen von Multicontainern und zur Verwendung von In-Memory-Volume-Bereitstellungen.

Behandelte Themen

  • Container mit Sidecar erstellen
  • Kommunikation eines Ingress-Containers mit einem Sidecar über „localhost“
  • So können sich ein Ingress-Container und ein Sidecar ein bereitgestelltes Volume teilen

8. Bereinigen

Um unbeabsichtigte Gebühren zu vermeiden (z. B. wenn diese Cloud-Funktion versehentlich öfter aufgerufen wird als Ihre monatliche Cloud Run-Aufrufzuweisung im kostenlosen Kontingent), können Sie entweder den Cloud Run-Dienst oder das Projekt löschen, das Sie in Schritt 2 erstellt haben.

Wenn Sie die Cloud-Funktion löschen möchten, rufen Sie die Cloud Console für Cloud Functions unter https://console.cloud.google.com/run/ auf und löschen Sie den sidecar-codelab-Dienst (oder $SERVICE_NAME, falls Sie einen anderen Namen verwendet 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.