1. Pengantar
Ringkasan
Fungsi Cloud Run adalah penawaran Functions-as-a-Service dari Google Cloud yang didukung oleh Cloud Run dan Eventarc, yang memberi Anda kontrol lanjutan atas performa dan skalabilitas, serta kontrol yang lebih besar atas runtime dan pemicu fungsi dari lebih dari 90 sumber peristiwa.
Codelab ini akan memandu Anda membuat fungsi Cloud Run yang merespons panggilan HTTP, dan dipicu oleh pesan Pub/Sub dan Cloud Audit Logs.
Codelab ini juga menggunakan update image dasar otomatis untuk deployment fungsi dengan menentukan image dasar menggunakan flag --base-image. Update image dasar otomatis untuk Cloud Run memungkinkan Google membuat patch keamanan pada komponen runtime bahasa dan sistem operasi image dasar secara otomatis. Anda tidak perlu membangun ulang atau men-deploy ulang layanan agar image dasar diperbarui. Untuk mengetahui informasi selengkapnya, lihat update image dasar otomatis
Jika Anda lebih memilih tidak menggunakan update otomatis gambar dasar, Anda dapat menghapus tanda --base-image dari contoh yang ditampilkan dalam codelab ini.
Yang akan Anda pelajari
- Ringkasan fungsi Cloud Run dan cara menggunakan update image dasar otomatis.
- Cara menulis fungsi yang merespons panggilan HTTP.
- Cara menulis fungsi yang merespons pesan Pub/Sub.
- Cara menulis fungsi yang merespons peristiwa Cloud Storage.
- Cara memisahkan traffic antara dua revisi.
- Cara menghilangkan cold start dengan instance minimum.
2. Penyiapan dan Persyaratan
Membuat folder root
Buat folder root untuk semua contoh.
mkdir crf-codelab cd crf-codelab
Menyiapkan variabel lingkungan
Tetapkan variabel lingkungan yang akan digunakan di seluruh codelab ini
gcloud config set project <YOUR-PROJECT-ID> REGION=<YOUR_REGION> PROJECT_ID=$(gcloud config get-value project)
Mengaktifkan API
Aktifkan semua layanan yang diperlukan:
gcloud services enable \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ eventarc.googleapis.com \ run.googleapis.com \ logging.googleapis.com \ pubsub.googleapis.com
3. Fungsi HTTP
Untuk fungsi pertama, mari buat fungsi Node.js terautentikasi yang merespons permintaan HTTP. Kita juga akan menggunakan waktu tunggu 10 menit untuk menunjukkan cara fungsi dapat memiliki lebih banyak waktu untuk merespons permintaan HTTP.
Berkreasi
Buat folder untuk aplikasi dan buka folder tersebut:
mkdir hello-http cd hello-http
Buat file index.js yang merespons permintaan HTTP:
const functions = require('@google-cloud/functions-framework');
functions.http('helloWorld', (req, res) => {
res.status(200).send('HTTP with Node.js in Cloud Run functions!');
});
Buat file package.json untuk menentukan dependensi:
{
"name": "nodejs-run-functions-codelab",
"version": "0.0.1",
"main": "index.js",
"dependencies": {
"@google-cloud/functions-framework": "^2.0.0"
}
}
Deploy
Deploy fungsi tersebut:
gcloud run deploy nodejs-run-function \
--source . \
--function helloWorld \
--base-image nodejs22 \
--region $REGION \
--timeout 600 \
--no-allow-unauthenticated
Perintah ini menggunakan buildpack untuk mengubah kode sumber fungsi Anda menjadi image container yang siap produksi.
Harap perhatikan hal berikut:
- Flag
--sourcedigunakan untuk memberi tahu Cloud Run agar membangun fungsi ke dalam layanan berbasis container yang dapat dijalankan - Flag
--function(baru) digunakan untuk menetapkan titik entri layanan baru menjadi tanda tangan fungsi yang ingin Anda panggil - Flag
--base-image(baru) menentukan lingkungan image dasar untuk fungsi Anda, sepertinodejs22,python312,go123,java21,dotnet8,ruby33, atauphp83. Untuk mengetahui detail selengkapnya tentang image dasar dan paket yang disertakan dalam setiap image, lihat Image dasar runtime. - (opsional) Flag
--timeoutmemungkinkan fungsi memiliki waktu tunggu yang lebih lama untuk merespons permintaan HTTP. Dalam contoh ini, 600 detik digunakan untuk mendemonstrasikan waktu respons 10 menit. - (opsional)
--no-allow-unauthenticateduntuk mencegah fungsi Anda dapat dipanggil secara publik
Uji
Uji fungsi dengan perintah berikut:
# 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
Anda akan melihat pesan HTTP with Node.js in Cloud Run functions! sebagai respons.
4. Fungsi Pub/Sub
Untuk fungsi kedua, mari buat fungsi Python yang dipicu oleh pesan Pub/Sub yang dipublikasikan ke topik tertentu.
Menyiapkan token autentikasi Pub/Sub
Jika Anda mengaktifkan akun layanan Pub/Sub pada atau sebelum 8 April 2021, berikan peran iam.serviceAccountTokenCreator ke akun layanan Pub/Sub:
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
Berkreasi
Buat topik Pub/Sub untuk digunakan dalam contoh:
TOPIC=cloud-run-functions-pubsub-topic gcloud pubsub topics create $TOPIC
Buat folder untuk aplikasi dan buka folder tersebut:
mkdir ../hello-pubsub cd ../hello-pubsub
Buat file main.py yang mencatat pesan yang berisi ID CloudEvent:
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'])
Buat file requirements.txt dengan konten berikut untuk menentukan dependensi:
functions-framework==3.*
Deploy
Deploy fungsi tersebut:
gcloud run deploy python-pubsub-function \
--source . \
--function hello_pubsub \
--base-image python313 \
--region $REGION \
--no-allow-unauthenticated
Ambil nomor project yang akan digunakan untuk identitas akun layanan.
PROJECT_NUMBER=$(gcloud projects list --filter="project_id:$PROJECT_ID" --format='value(project_number)')
Buat pemicu
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
Uji
Uji fungsi dengan mengirim pesan ke topik:
gcloud pubsub topics publish $TOPIC --message="Hello World"
Anda akan melihat CloudEvent yang diterima di log:
gcloud run services logs read python-pubsub-function --region $REGION --limit=10
5. Fungsi Cloud Storage
Untuk fungsi berikutnya, mari kita buat fungsi Node.js yang merespons peristiwa dari bucket Cloud Storage.
Siapkan
Untuk menggunakan fungsi Cloud Storage, berikan peran IAM pubsub.publisher ke akun layanan Cloud Storage:
SERVICE_ACCOUNT=$(gsutil kms serviceaccount -p $PROJECT_NUMBER) gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:$SERVICE_ACCOUNT \ --role roles/pubsub.publisher
Berkreasi
Buat folder untuk aplikasi dan buka folder tersebut:
mkdir ../hello-storage cd ../hello-storage
Buat file index.js yang hanya merespons peristiwa Cloud Storage:
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);
});
Buat file package.json untuk menentukan dependensi:
{
"name": "nodejs-crf-cloud-storage",
"version": "0.0.1",
"main": "index.js",
"dependencies": {
"@google-cloud/functions-framework": "^2.0.0"
}
}
Deploy
Pertama, buat bucket Cloud Storage (atau gunakan bucket yang sudah ada):
export BUCKET_NAME="gcf-storage-$PROJECT_ID" export BUCKET="gs://gcf-storage-$PROJECT_ID" gsutil mb -l $REGION $BUCKET
Deploy fungsi tersebut:
gcloud run deploy nodejs-crf-cloud-storage \ --source . \ --base-image nodejs22 \ --function helloStorage \ --region $REGION \ --no-allow-unauthenticated
Setelah fungsi di-deploy, Anda dapat melihatnya di bagian Cloud Run pada Konsol Cloud.
Sekarang buat pemicu Eventarc.
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
Uji
Uji fungsi dengan mengupload file ke bucket:
echo "Hello World" > random.txt gsutil cp random.txt $BUCKET/random.txt
Anda akan melihat CloudEvent yang diterima di log:
gcloud run services logs read nodejs-crf-cloud-storage --region $REGION --limit=10
6. Cloud Audit Logs
Untuk fungsi berikutnya, mari kita buat fungsi Node.js yang menerima peristiwa Cloud Audit Log saat instance VM Compute Engine dibuat. Sebagai respons, label ditambahkan ke VM yang baru dibuat, yang menentukan pembuat VM.
Menentukan VM Compute Engine yang baru dibuat
Compute Engine memancarkan 2 Log Audit saat VM dibuat.
Yang pertama dikeluarkan di awal pembuatan VM. Yang kedua dipancarkan setelah VM dibuat.
Di log audit, kolom operasi berbeda, berisi nilai first: true dan last: true. Log Audit kedua berisi semua informasi yang kita butuhkan untuk memberi label pada instance, jadi kita akan menggunakan tanda last: true untuk mendeteksinya di fungsi Cloud Run.
Siapkan
Untuk menggunakan fungsi Cloud Audit Log, Anda harus mengaktifkan Log Audit untuk Eventarc. Anda juga perlu menggunakan akun layanan dengan peran eventarc.eventReceiver.
- Aktifkan jenis log Pembacaan Admin, Pembacaan Data, dan Penulisan Data Cloud Audit Logs untuk Compute Engine API.
- Berikan peran IAM
eventarc.eventReceiverkepada akun layanan Compute Engine default:
gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com \ --role roles/eventarc.eventReceiver
Membuat fungsi
Codelab ini menggunakan node.js, tetapi Anda dapat menemukan contoh lainnya di https://github.com/GoogleCloudPlatform/eventarc-samples
Buat file package.json
{
"dependencies": {
"googleapis": "^84.0.0"
}
}
Buat file node.js
// 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;
}
Deploy
Deploy fungsi tersebut:
gcloud run deploy gce-vm-labeler \ --source . \ --function labelVmCreation \ --region $REGION \ --no-allow-unauthenticated
Sekarang buat pemicu. Perhatikan cara fungsi memfilter penyisipan Log Audit untuk Compute Engine dengan tanda --trigger-event-filters.
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
Uji
Tetapkan variabel lingkungan:
# if you're using europe-west1 as your region
ZONE=europe-west1-d
VM_NAME=codelab-crf-auditlog
Jalankan perintah berikut untuk membuat VM:
gcloud compute instances create $VM_NAME --zone=$ZONE --machine-type=e2-medium --image-family=debian-11 --image-project=debian-cloud
Setelah pembuatan VM selesai, Anda akan melihat label creator yang ditambahkan di VM di Konsol Cloud di bagian Informasi dasar atau menggunakan perintah berikut:
gcloud compute instances describe $VM_NAME --zone=$ZONE
Anda akan melihat label di output seperti contoh berikut:
... labelFingerprint: ULU6pAy2C7s= labels: creator: atameldev ...
Pembersihan
Pastikan untuk menghapus instance VM. Variabel ini tidak akan digunakan lagi di lab ini.
gcloud compute instances delete $VM_NAME --zone=$ZONE
7. Pemisahan traffic
Fungsi Cloud Run mendukung beberapa revisi fungsi Anda, memisahkan traffic antara revisi yang berbeda, dan mengembalikan fungsi Anda ke versi sebelumnya.
Pada langkah ini, Anda akan men-deploy 2 revisi fungsi, lalu membagi traffic di antara keduanya dengan rasio 50-50.
Berkreasi
Buat folder untuk aplikasi dan buka folder tersebut:
mkdir ../traffic-splitting cd ../traffic-splitting
Buat file main.py dengan fungsi Python yang membaca variabel lingkungan warna dan merespons kembali dengan Hello World dalam warna latar belakang tersebut:
import os
color = os.environ.get('COLOR')
def hello_world(request):
return f'<body style="background-color:{color}"><h1>Hello World!</h1></body>'
Buat file requirements.txt dengan konten berikut untuk menentukan dependensi:
functions-framework==3.*
Deploy
Deploy revisi pertama fungsi dengan latar belakang oranye:
COLOR=orange gcloud run deploy hello-world-colors \ --source . \ --base-image python313 \ --function hello_world \ --region $REGION \ --allow-unauthenticated \ --update-env-vars COLOR=$COLOR
Pada tahap ini, jika Anda menguji fungsi dengan melihat pemicu HTTP (output URI dari perintah deployment di atas) di browser, Anda akan melihat Hello World dengan latar belakang berwarna oranye:

Deploy revisi kedua dengan latar belakang kuning:
COLOR=yellow gcloud run deploy hello-world-colors \ --source . \ --base-image python313 \ --function hello_world \ --region $REGION \ --allow-unauthenticated \ --update-env-vars COLOR=$COLOR
Karena ini adalah revisi terbaru, jika Anda menguji fungsi, Anda akan melihat Hello World dengan latar belakang kuning:

Membagi traffic 50-50
Untuk memisahkan traffic antara revisi oranye dan kuning, Anda perlu menemukan ID revisi layanan Cloud Run. Berikut perintah untuk melihat ID revisi:
gcloud run revisions list --service hello-world-colors \ --region $REGION --format 'value(REVISION)'
Outputnya akan mirip dengan berikut ini:
hello-world-colors-00001-man hello-world-colors-00002-wok
Sekarang, pisahkan traffic di antara kedua revisi ini sebagai berikut (perbarui X-XXX sesuai dengan nama revisi Anda):
gcloud run services update-traffic hello-world-colors \ --region $REGION \ --to-revisions hello-world-colors-0000X-XXX=50,hello-world-colors-0000X-XXX=50
Uji
Uji fungsi dengan membuka URL publiknya. Setengah dari waktu, Anda akan melihat revisi oranye dan setengahnya lagi, revisi kuning:

Lihat rollback, peluncuran bertahap, dan migrasi traffic untuk mengetahui informasi selengkapnya.
8. Instance minimum
Di fungsi Cloud Run, Anda dapat menentukan jumlah minimum instance fungsi yang tetap aktif dan siap melayani permintaan. Hal ini berguna untuk membatasi jumlah cold start.
Pada langkah ini, Anda akan men-deploy fungsi dengan inisialisasi yang lambat. Anda akan mengamati masalah cold start. Kemudian, Anda akan men-deploy fungsi dengan nilai instance minimum yang ditetapkan ke 1 untuk menghilangkan cold start.
Berkreasi
Buat folder untuk aplikasi dan buka folder tersebut:
mkdir ../min-instances cd ../min-instances
Buat file main.go. Layanan Go ini memiliki fungsi init yang tidur selama 10 detik untuk menyimulasikan inisialisasi yang lama. Fungsi ini juga memiliki fungsi HelloWorld yang merespons panggilan HTTP:
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!")
}
Deploy
Deploy revisi pertama fungsi dengan nilai instance minimum default nol:
gcloud run deploy go-slow-function \ --source . \ --base-image go123 \ --function HelloWorld \ --region $REGION \ --no-allow-unauthenticated
Uji fungsi dengan perintah ini:
# 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
Anda akan melihat penundaan 10 detik (cold start) pada panggilan pertama, lalu melihat pesan. Panggilan berikutnya akan segera ditampilkan.
Menetapkan instance minimum
Untuk menghilangkan cold start pada permintaan pertama, deploy ulang fungsi dengan tanda --min-instances yang ditetapkan ke 1 sebagai berikut:
gcloud run deploy go-slow-function \ --source . \ --base-image go123 \ --function HelloWorld \ --region $REGION \ --no-allow-unauthenticated \ --min-instances 1
Uji
Uji fungsi lagi:
curl -H "Authorization: bearer $(gcloud auth print-identity-token)" -X GET $SERVICE_URL
Anda tidak akan melihat penundaan 10 detik lagi dalam permintaan pertama. Masalah cold start untuk pemanggilan pertama (setelah lama tidak ada) telah hilang, berkat instance minimum.
Lihat menggunakan instance minimum untuk mengetahui informasi selengkapnya.
9. Selamat!
Selamat, Anda telah menyelesaikan codelab.
Yang telah kita bahas
- Ringkasan fungsi Cloud Run dan cara menggunakan update image dasar otomatis.
- Cara menulis fungsi yang merespons panggilan HTTP.
- Cara menulis fungsi yang merespons pesan Pub/Sub.
- Cara menulis fungsi yang merespons peristiwa Cloud Storage.
- Cara memisahkan traffic antara dua revisi.
- Cara menghilangkan cold start dengan instance minimum.