1. Einführung
Übersicht
Cloud Run-Funktionen sind das FaaS-Angebot (Functions-as-a-Service) von Google Cloud, das auf Cloud Run und Eventarc basiert. So haben Sie mehr Kontrolle über Leistung und Skalierbarkeit sowie über die Laufzeit und Trigger der Funktionen 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.
- Funktion schreiben, 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 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 Reaktion auf HTTP-Anfragen erhalten 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
--sourcewird 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,ruby33oderphp83. Weitere Informationen zu Basis-Images und den in den einzelnen Images enthaltenen Paketen finden Sie unter Basis-Images für Laufzeiten. - (Optional) Mit dem Flag
--timeoutkann die Funktion länger auf HTTP-Anfragen reagieren. 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
Sobald die Funktion bereitgestellt wurde, können Sie sie im Cloud Run-Abschnitt 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, indem Sie eine Datei in den Bucket hochladen:
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 beim Erstellen einer Compute Engine-VM-Instanz ein Cloud-Audit-Log-Ereignis empfängt. Als Reaktion darauf wird der neu erstellten VM ein Label hinzugefügt, das den Ersteller der VM angibt.
Neu erstellte Compute Engine-VMs überprüfen
Compute Engine gibt beim Erstellen einer VM 2 Audit-Logs aus.
Das erste wird zu Beginn der VM-Erstellung ausgegeben. Das zweite wird nach der VM-Erstellung ausgegeben.
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 benötigen, um einer Instanz ein Label hinzuzufügen. Daher verwenden wir das Flag last: true, um es in Cloud Run-Funktionen zu erkennen.
Einrichten
Wenn Sie Cloud-Audit-Log-Funktionen verwenden möchten, müssen Sie für Eventarc Audit-Logs 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.eventReceiverzu:
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. Die Funktion filtert mit dem Flag --trigger-event-filters nach Audit-Logs für Compute Engine-Einfügungen:
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
Sobald die VM erstellt wurde, sollte für die VM in der Cloud Console im Bereich Allgemeine Informationen das hinzugefügte Label creator angezeigt werden. Alternativ können Sie den folgenden Befehl verwenden:
gcloud compute instances describe $VM_NAME --zone=$ZONE
Sie sollten in der Ausgabe das Label wie im folgenden Beispiel sehen:
... 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. Aufteilung des Traffics
Cloud Run Functions unterstützt mehrere Versionen Ihrer Funktionen. So können Sie Traffic auf verschiedene Versionen aufteilen und Ihre Funktion auf eine frühere Version zurücksetzen.
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 ausliest und Hello World in dieser Hintergrundfarbe zurückgibt:
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 durch Aufrufen des HTTP-Triggers (die URI-Ausgabe des oben ausgeführten Bereitstellungsbefehls) in Ihrem Browser testen, sollte Hello World mit einem orangefarbenen Hintergrund angezeigt werden:

Stellen Sie die zweite Version 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 neueste Version 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 Hälfte der Zeit sollten Sie die orangefarbene Version und die andere Hälfte die gelbe Version sehen:

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 festlegen, die einsatzbereit sind und Anfragen verarbeiten können. Dies ist nützlich, um die Anzahl der Kaltstarts zu begrenzen.
In diesem Schritt stellen Sie eine Funktion mit langsamer Initialisierung bereit. Sie beobachten ein Kaltstartproblem. Sie stellen dann 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. Er verfügt auch über 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 Version 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 sollte es zu einer Verzögerung von 10 Sekunden (Kaltstart) kommen, bevor die Meldung angezeigt wird. Weitere 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, festgelegt auf den Wert 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) wurde dank der Mindestanzahl von Instanzen behoben.
Weitere Informationen finden Sie unter Mindestanzahl von Instanzen für Dienste festlegen.
9. Glückwunsch!
Herzlichen Glückwunsch zum Abschluss des Codelabs!
Behandelte Themen
- Übersicht über Cloud Run-Funktionen und die Verwendung automatischer Basis-Image-Updates.
- Funktion schreiben, 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 Mindestanzahl von Instanzen vermeiden