1. Einführung
Übersicht
Cloud Run-Funktionen sind das FaaS-Angebot (Function as a Service) von Google Cloud auf Basis von Cloud Run und Eventarc. Es bietet Ihnen erweiterte Steuerungsmöglichkeiten für Leistung und Skalierbarkeit, mehr Kontrolle über die Laufzeit der Funktion sowie Trigger aus über 90 Ereignisquellen.
In diesem Codelab erfahren Sie, wie Sie Cloud Run-Funktionen erstellen, die auf HTTP-Aufrufe reagieren und durch Pub/Sub-Nachrichten und Cloud-Audit-Logs ausgelöst werden.
In diesem Codelab werden auch automatische Basis-Image-Updates für die Bereitstellung von Funktionen verwendet. Dazu wird ein Basis-Image mit dem Flag --base-image
angegeben. Wenn Sie automatische Basis-Image-Aktualisierungen für Cloud Run konfigurieren, kann Google automatisch Sicherheits-Patches für die Betriebssystem- und Sprachlaufzeitkomponenten des Basis-Images anwenden. Sie müssen den Dienst nicht neu erstellen oder neu bereitstellen, damit das Basis-Image aktualisiert wird. Weitere Informationen finden Sie unter Automatische Basis-Image-Updates.
Wenn Sie keine automatischen Basis-Image-Updates verwenden möchten, können Sie das Flag --base-image
aus den Beispielen in diesem Codelab entfernen.
Lerninhalte
- Übersicht über Cloud Run-Funktionen und die Verwendung automatischer Basis-Image-Updates.
- So schreiben Sie eine Funktion, die auf HTTP-Aufrufe reagiert.
- So schreiben Sie eine Funktion, die auf Pub/Sub-Nachrichten reagiert.
- So schreiben Sie eine Funktion, die auf Cloud Storage-Ereignisse reagiert.
- So teilen Sie den Traffic auf zwei Überarbeitungen auf.
- Kaltstarts mit einer Mindestanzahl von Instanzen vermeiden
2. Einrichtung und Anforderungen
Stammordner erstellen
Erstellen Sie einen Stammordner für alle Beispiele.
mkdir crf-codelab cd crf-codelab
Umgebungsvariablen einrichten
Legen Sie Umgebungsvariablen fest, die in diesem Codelab verwendet werden.
gcloud config set project <YOUR-PROJECT-ID> REGION=<YOUR_REGION> PROJECT_ID=$(gcloud config get-value project)
APIs aktivieren
Aktivieren Sie alle erforderlichen Dienste:
gcloud services enable \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ eventarc.googleapis.com \ run.googleapis.com \ logging.googleapis.com \ pubsub.googleapis.com
3. HTTP-Funktion
Für die erste Funktion erstellen wir eine authentifizierte Node.js-Funktion, die auf HTTP-Anfragen reagiert. Wir verwenden auch ein Zeitlimit von 10 Minuten, um zu zeigen, wie eine Funktion mehr Zeit für die Antwort auf HTTP-Anfragen haben kann.
Erstellen
Erstellen Sie einen Ordner für die App und wechseln Sie zu diesem Ordner:
mkdir hello-http cd hello-http
Erstellen Sie eine index.js
-Datei, die auf HTTP-Anfragen reagiert:
const functions = require('@google-cloud/functions-framework'); functions.http('helloWorld', (req, res) => { res.status(200).send('HTTP with Node.js in Cloud Run functions!'); });
Erstellen Sie eine package.json
-Datei, um die Abhängigkeiten anzugeben:
{ "name": "nodejs-run-functions-codelab", "version": "0.0.1", "main": "index.js", "dependencies": { "@google-cloud/functions-framework": "^2.0.0" } }
Bereitstellen
Die Funktion bereitstellen:
gcloud run deploy nodejs-run-function \ --source . \ --function helloWorld \ --base-image nodejs22 \ --region $REGION \ --timeout 600 \ --no-allow-unauthenticated
Mit diesem Befehl werden Buildpacks verwendet, um den Quellcode Ihrer Funktion in ein produktionsbereites Container-Image umzuwandeln.
Hinweis:
- Das Flag
--source
wird verwendet, um Cloud Run anzuweisen, die Funktion in einem ausführbaren containerbasierten Dienst zu erstellen. - Das Flag
--function
(neu) wird verwendet, um den Einstiegspunkt des neuen Dienstes auf die Funktionssignatur festzulegen, die aufgerufen werden soll. - Das Flag
--base-image
(neu) gibt die Umgebung des Basis-Images für Ihre Funktion an, z. B.nodejs22
,python312
,go123
,java21
,dotnet8
,ruby33
oderphp83
. Weitere Informationen zu Basis-Images und den in den einzelnen Images enthaltenen Paketen finden Sie unter Basis-Images für Laufzeiten. - (optional) Das Flag
--timeout
ermöglicht der Funktion ein längeres Zeitlimit für die Reaktion auf HTTP-Anfragen. In diesem Beispiel werden 600 Sekunden verwendet, um eine Reaktionszeit von 10 Minuten zu demonstrieren. - (optional)
--no-allow-unauthenticated
, um zu verhindern, dass Ihre Funktion öffentlich aufgerufen werden kann
Test
Testen Sie die Funktion mit den folgenden Befehlen:
# get the Service URL SERVICE_URL="$(gcloud run services describe nodejs-run-function --region $REGION --format 'value(status.url)')" # invoke the service curl -H "Authorization: bearer $(gcloud auth print-identity-token)" -X GET $SERVICE_URL
Als Antwort sollte die Meldung HTTP with Node.js in Cloud Run functions!
angezeigt werden.
4. Pub/Sub-Funktion
Für die zweite Funktion erstellen wir eine Python-Funktion, die durch eine Pub/Sub-Nachricht ausgelöst wird, die in einem bestimmten Thema veröffentlicht wird.
Pub/Sub-Authentifizierungstokens einrichten
Wenn Sie das Pub/Sub-Dienstkonto am oder vor dem 8. April 2021 aktiviert haben, weisen Sie dem Pub/Sub-Dienstkonto die Rolle iam.serviceAccountTokenCreator
zu:
PROJECT_NUMBER=$(gcloud projects list --filter="project_id:$PROJECT_ID" --format='value(project_number)') gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:service-$PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \ --role roles/iam.serviceAccountTokenCreator
Erstellen
Erstellen Sie ein Pub/Sub-Thema für das Beispiel:
TOPIC=cloud-run-functions-pubsub-topic gcloud pubsub topics create $TOPIC
Erstellen Sie einen Ordner für die App und wechseln Sie zu diesem Ordner:
mkdir ../hello-pubsub cd ../hello-pubsub
Erstellen Sie eine main.py
-Datei, in der eine Nachricht mit der CloudEvent-ID protokolliert wird:
import functions_framework @functions_framework.cloud_event def hello_pubsub(cloud_event): print('Pub/Sub with Python in Cloud Run functions! Id: ' + cloud_event['id'])
Erstellen Sie eine requirements.txt
-Datei mit folgendem Inhalt, um die Abhängigkeiten anzugeben:
functions-framework==3.*
Bereitstellen
Die Funktion bereitstellen:
gcloud run deploy python-pubsub-function \ --source . \ --function hello_pubsub \ --base-image python313 \ --region $REGION \ --no-allow-unauthenticated
Rufen Sie die Projektnummer ab, die für die Dienstkontoidentität verwendet werden soll.
PROJECT_NUMBER=$(gcloud projects list --filter="project_id:$PROJECT_ID" --format='value(project_number)')
Trigger erstellen
gcloud eventarc triggers create python-pubsub-function-trigger \ --location=$REGION \ --destination-run-service=python-pubsub-function \ --destination-run-region=$REGION \ --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \ --transport-topic=projects/$PROJECT_ID/topics/$TOPIC \ --service-account=$PROJECT_NUMBER-compute@developer.gserviceaccount.com
Test
Testen Sie die Funktion, indem Sie eine Nachricht an das Thema senden:
gcloud pubsub topics publish $TOPIC --message="Hello World"
Das empfangene CloudEvent sollte in den Logs angezeigt werden:
gcloud run services logs read python-pubsub-function --region $REGION --limit=10
5. Cloud Storage-Funktion
Als Nächstes erstellen wir eine Node.js-Funktion, die auf Ereignisse aus einem Cloud Storage-Bucket reagiert.
Einrichten
Wenn Sie Cloud Storage-Funktionen verwenden möchten, weisen Sie dem Cloud Storage-Dienstkonto die IAM-Rolle pubsub.publisher
zu:
SERVICE_ACCOUNT=$(gsutil kms serviceaccount -p $PROJECT_NUMBER) gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:$SERVICE_ACCOUNT \ --role roles/pubsub.publisher
Erstellen
Erstellen Sie einen Ordner für die App und wechseln Sie zu diesem Ordner:
mkdir ../hello-storage cd ../hello-storage
Erstellen Sie eine index.js
-Datei, die einfach auf Cloud Storage-Ereignisse reagiert:
const functions = require('@google-cloud/functions-framework'); functions.cloudEvent('helloStorage', (cloudevent) => { console.log('Cloud Storage event with Node.js in Cloud Run functions!'); console.log(cloudevent); });
Erstellen Sie eine package.json
-Datei, um die Abhängigkeiten anzugeben:
{ "name": "nodejs-crf-cloud-storage", "version": "0.0.1", "main": "index.js", "dependencies": { "@google-cloud/functions-framework": "^2.0.0" } }
Bereitstellen
Erstellen Sie zuerst einen Cloud Storage-Bucket oder verwenden Sie einen vorhandenen Bucket:
export BUCKET_NAME="gcf-storage-$PROJECT_ID" export BUCKET="gs://gcf-storage-$PROJECT_ID" gsutil mb -l $REGION $BUCKET
Die Funktion bereitstellen:
gcloud run deploy nodejs-crf-cloud-storage \ --source . \ --base-image nodejs22 \ --function helloStorage \ --region $REGION \ --no-allow-unauthenticated
Nachdem die Funktion bereitgestellt wurde, können Sie sie im Cloud Run-Bereich der Cloud Console sehen.
Erstellen Sie nun den Eventarc-Trigger.
BUCKET_REGION=$REGION gcloud eventarc triggers create nodejs-crf-cloud-storage-trigger \ --location=$BUCKET_REGION \ --destination-run-service=nodejs-crf-cloud-storage \ --destination-run-region=$REGION \ --event-filters="type=google.cloud.storage.object.v1.finalized" \ --event-filters="bucket=$BUCKET_NAME" \ --service-account=$PROJECT_NUMBER-compute@developer.gserviceaccount.com
Test
Testen Sie die Funktion. Laden Sie dazu eine Datei in den Bucket hoch:
echo "Hello World" > random.txt gsutil cp random.txt $BUCKET/random.txt
Das empfangene CloudEvent sollte in den Logs angezeigt werden:
gcloud run services logs read nodejs-crf-cloud-storage --region $REGION --limit=10
6. Cloud-Audit-Logs
Als Nächstes erstellen wir eine Node.js-Funktion, die ein Cloud-Audit-Log-Ereignis empfängt, wenn eine Compute Engine-VM-Instanz erstellt wird. Als Reaktion darauf wird der neu erstellten VM ein Label hinzugefügt, das den Ersteller der VM angibt.
Neu erstellte Compute Engine-VMs ermitteln
Compute Engine gibt beim Erstellen einer VM zwei Audit-Logs aus.
Das erste wird zu Beginn der VM-Erstellung ausgegeben. Das zweite wird ausgegeben, nachdem die VM erstellt wurde.
In den Audit-Logs sind die Vorgangsfelder unterschiedlich und enthalten die Werte first: true
und last: true
. Das zweite Audit-Log enthält alle Informationen, die wir zum Labeln einer Instanz benötigen. Daher verwenden wir das Flag last: true
, um es in Cloud Run Functions zu erkennen.
Einrichten
Wenn Sie Cloud-Audit-Log-Funktionen verwenden möchten, müssen Sie Audit-Logs für Eventarc aktivieren. Außerdem müssen Sie ein Dienstkonto mit der Rolle eventarc.eventReceiver
verwenden.
- Aktivieren Sie Cloud-Audit-Logs für die Logtypen Administratorlesevorgänge, Datenlesevorgänge und Datenschreibvorgänge für die Compute Engine API.
- Weisen Sie dem Compute Engine-Standarddienstkonto die IAM-Rolle
eventarc.eventReceiver
zu:
gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com \ --role roles/eventarc.eventReceiver
Funktion erstellen
In diesem Codelab wird Node.js verwendet. Weitere Beispiele finden Sie unter https://github.com/GoogleCloudPlatform/eventarc-samples.
package.json
-Datei erstellen
{
"dependencies": {
"googleapis": "^84.0.0"
}
}
node.js
-Datei erstellen
// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
const { google } = require("googleapis");
var compute = google.compute("v1");
exports.labelVmCreation = async (cloudevent) => {
const data = cloudevent.body;
// in case an event has >1 audit log
// make sure we respond to the last event
if (!data.operation || !data.operation.last) {
console.log("Operation is not last, skipping event");
return;
}
// projects/dogfood-gcf-saraford/zones/us-central1-a/instances/instance-1
var resourceName = data.protoPayload.resourceName;
var resourceParts = resourceName.split("/");
var project = resourceParts[1];
var zone = resourceParts[3];
var instanceName = resourceParts[5];
var username = data.protoPayload.authenticationInfo.principalEmail.split("@")[0];
console.log(`Setting label username: ${username} to instance ${instanceName} for zone ${zone}`);
var authClient = await google.auth.getClient({
scopes: ["https://www.googleapis.com/auth/cloud-platform"]
});
// per docs: When updating or adding labels in the API,
// you need to provide the latest labels fingerprint with your request,
// to prevent any conflicts with other requests.
var labelFingerprint = await getInstanceLabelFingerprint(authClient, project, zone, instanceName);
var responseStatus = await setVmLabel(
authClient,
labelFingerprint,
username,
project,
zone,
instanceName
);
// log results of setting VM label
console.log(JSON.stringify(responseStatus, null, 2));
};
async function getInstanceLabelFingerprint(authClient, project, zone, instanceName) {
var request = {
project: project,
zone: zone,
instance: instanceName,
auth: authClient
};
var response = await compute.instances.get(request);
var labelFingerprint = response.data.labelFingerprint;
return labelFingerprint;
}
async function setVmLabel(authClient, labelFingerprint, username, project, zone, instanceName) {
var request = {
project: project,
zone: zone,
instance: instanceName,
resource: {
labels: { "creator": username },
labelFingerprint: labelFingerprint
},
auth: authClient
};
var response = await compute.instances.setLabels(request);
return response.statusText;
}
Bereitstellen
Die Funktion bereitstellen:
gcloud run deploy gce-vm-labeler \ --source . \ --function labelVmCreation \ --region $REGION \ --no-allow-unauthenticated
Erstellen Sie nun den Trigger. Beachten Sie, dass die Funktion Audit-Logs für Compute Engine-Einfügungen mit dem Flag --trigger-event-filters
filtert.
gcloud eventarc triggers create gce-vm-labeler-trigger \ --location=$REGION \ --destination-run-service=gce-vm-labeler \ --destination-run-region=$REGION \ --event-filters="type=google.cloud.audit.log.v1.written,serviceName=compute.googleapis.com,methodName=v1.compute.instances.insert" \ --service-account=$ROJECT_NUMBER-compute@developer.gserviceaccount.com
Test
Umgebungsvariablen festlegen:
# if you're using europe-west1 as your region
ZONE=europe-west1-d
VM_NAME=codelab-crf-auditlog
Mit dem folgenden Befehl erstellen Sie eine VM:
gcloud compute instances create $VM_NAME --zone=$ZONE --machine-type=e2-medium --image-family=debian-11 --image-project=debian-cloud
Nachdem die VM erstellt wurde, sollte das hinzugefügte creator
-Label in der Cloud Console im Abschnitt Grundlegende Informationen oder mit dem folgenden Befehl angezeigt werden:
gcloud compute instances describe $VM_NAME --zone=$ZONE
Das Label sollte in der Ausgabe wie im folgenden Beispiel zu sehen sein:
... labelFingerprint: ULU6pAy2C7s= labels: creator: atameldev ...
Bereinigen
Löschen Sie die VM-Instanz. Es wird in diesem Lab nicht noch einmal verwendet.
gcloud compute instances delete $VM_NAME --zone=$ZONE
7. Traffic-Aufteilung
Cloud Run Functions unterstützt mehrere Überarbeitungen Ihrer Funktionen, sodass Sie den Traffic auf verschiedene Überarbeitungen aufteilen und Ihre Funktion auf eine frühere Version zurücksetzen können.
In diesem Schritt stellen Sie zwei Überarbeitungen einer Funktion bereit und teilen den Traffic dann 50 : 50 auf.
Erstellen
Erstellen Sie einen Ordner für die App und wechseln Sie zu diesem Ordner:
mkdir ../traffic-splitting cd ../traffic-splitting
Erstellen Sie eine main.py
-Datei mit einer Python-Funktion, die eine Umgebungsvariable für die Farbe liest und mit Hello World
in dieser Hintergrundfarbe antwortet:
import os color = os.environ.get('COLOR') def hello_world(request): return f'<body style="background-color:{color}"><h1>Hello World!</h1></body>'
Erstellen Sie eine requirements.txt
-Datei mit folgendem Inhalt, um die Abhängigkeiten anzugeben:
functions-framework==3.*
Bereitstellen
Stellen Sie die erste Version der Funktion mit einem orangefarbenen Hintergrund bereit:
COLOR=orange gcloud run deploy hello-world-colors \ --source . \ --base-image python313 \ --function hello_world \ --region $REGION \ --allow-unauthenticated \ --update-env-vars COLOR=$COLOR
Wenn Sie die Funktion jetzt testen, indem Sie den HTTP-Trigger (die URI-Ausgabe des obigen Bereitstellungsbefehls) in Ihrem Browser aufrufen, sollte Hello World
mit einem orangefarbenen Hintergrund angezeigt werden:
Stellen Sie die zweite Überarbeitung mit einem gelben Hintergrund bereit:
COLOR=yellow gcloud run deploy hello-world-colors \ --source . \ --base-image python313 \ --function hello_world \ --region $REGION \ --allow-unauthenticated \ --update-env-vars COLOR=$COLOR
Da dies die letzte Überarbeitung ist, sollten Sie beim Testen der Funktion Hello World
mit einem gelben Hintergrund sehen:
Traffic 50 : 50 aufteilen
Um den Traffic zwischen den orangefarbenen und gelben Überarbeitungen aufzuteilen, müssen Sie die Überarbeitungs-IDs der Cloud Run-Dienste ermitteln. Mit diesem Befehl können Sie die Revisions-IDs aufrufen:
gcloud run revisions list --service hello-world-colors \ --region $REGION --format 'value(REVISION)'
Die Ausgabe sollte in etwa so aussehen:
hello-world-colors-00001-man hello-world-colors-00002-wok
Teilen Sie den Traffic jetzt so auf die beiden Überarbeitungen auf (aktualisieren Sie X-XXX
entsprechend Ihren Überarbeitungsnamen):
gcloud run services update-traffic hello-world-colors \ --region $REGION \ --to-revisions hello-world-colors-0000X-XXX=50,hello-world-colors-0000X-XXX=50
Test
Testen Sie die Funktion, indem Sie die öffentliche URL aufrufen. Die orangefarbene und die gelbe Überarbeitung sollten jeweils etwa halb so oft angezeigt werden:
Weitere Informationen finden Sie unter Rollbacks, graduelle Einführungen und Trafficmigration.
8. Mindestanzahl von Instanzen
In Cloud Run Functions können Sie eine Mindestanzahl von Funktionsinstanzen angeben, die einsatzbereit gehalten werden und zum Verarbeiten von Anfragen bereit sein sollen. Dies ist nützlich, um die Anzahl der Kaltstarts zu begrenzen.
In diesem Schritt stellen Sie eine Funktion mit langsamer Initialisierung bereit. Sie werden das Kaltstartproblem beobachten. Anschließend stellen Sie die Funktion mit dem Mindestinstanzwert 1 bereit, um den Kaltstart zu vermeiden.
Erstellen
Erstellen Sie einen Ordner für die App und wechseln Sie zu diesem Ordner:
mkdir ../min-instances cd ../min-instances
Erstellen Sie eine main.go
-Datei. Dieser Go-Dienst hat eine init
-Funktion, die 10 Sekunden lang in den Ruhemodus wechselt, um eine lange Initialisierung zu simulieren. Sie enthält auch eine HelloWorld
-Funktion, die auf HTTP-Aufrufe reagiert:
package p import ( "fmt" "net/http" "time" ) func init() { time.Sleep(10 * time.Second) } func HelloWorld(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Slow HTTP Go in Cloud Run functions!") }
Bereitstellen
Stellen Sie die erste Überarbeitung der Funktion mit dem Standardwert für die Mindestanzahl von Instanzen (0) bereit:
gcloud run deploy go-slow-function \ --source . \ --base-image go123 \ --function HelloWorld \ --region $REGION \ --no-allow-unauthenticated
Testen Sie die Funktion mit diesem Befehl:
# get the Service URL SERVICE_URL="$(gcloud run services describe go-slow-function --region $REGION --format 'value(status.url)')" # invoke the service curl -H "Authorization: bearer $(gcloud auth print-identity-token)" -X GET $SERVICE_URL
Beim ersten Aufruf kommt es zu einer Verzögerung von 10 Sekunden (Kaltstart), bevor die Meldung angezeigt wird. Nachfolgende Aufrufe sollten sofort zurückgegeben werden.
Mindestanzahl von Instanzen festlegen
Um den Kaltstart bei der ersten Anfrage zu vermeiden, stellen Sie die Funktion mit dem Flag --min-instances
auf 1 noch einmal bereit:
gcloud run deploy go-slow-function \ --source . \ --base-image go123 \ --function HelloWorld \ --region $REGION \ --no-allow-unauthenticated \ --min-instances 1
Test
Testen Sie die Funktion noch einmal:
curl -H "Authorization: bearer $(gcloud auth print-identity-token)" -X GET $SERVICE_URL
Bei der ersten Anfrage sollte es nicht mehr zu einer Verzögerung von 10 Sekunden kommen. Das Kaltstartproblem für den ersten Aufruf (nach langer Zeit ohne Aufrufe) ist dank der Mindestanzahl von Instanzen behoben.
Weitere Informationen finden Sie unter Mindestinstanzen verwenden.
9. Glückwunsch!
Herzlichen Glückwunsch zum Abschluss des Codelabs!
Behandelte Themen
- Übersicht über Cloud Run-Funktionen und die Verwendung automatischer Basis-Image-Updates.
- So schreiben Sie eine Funktion, die auf HTTP-Aufrufe reagiert.
- So schreiben Sie eine Funktion, die auf Pub/Sub-Nachrichten reagiert.
- So schreiben Sie eine Funktion, die auf Cloud Storage-Ereignisse reagiert.
- So teilen Sie den Traffic auf zwei Überarbeitungen auf.
- Kaltstarts mit einer Mindestanzahl von Instanzen vermeiden