1. Giriş
Genel Bakış
Cloud Run işlevleri, Google Cloud'un Cloud Run ve Eventarc tarafından desteklenen Hizmet Olarak İşlev (FaaS) teklifidir. Bu teklif, performans ve ölçeklenebilirlik üzerinde daha gelişmiş kontrolün yanı sıra 90'dan fazla etkinlik kaynağındaki işlevlerin çalışma zamanı ve tetikleyicileri üzerinde daha fazla kontrol sağlar.
Bu codelab'de, HTTP çağrılarına yanıt veren, Pub/Sub mesajları ve Cloud Denetleme Günlükleri tarafından tetiklenen Cloud Run işlevleri oluşturma adımları açıklanmaktadır.
Bu codelab'de, --base-image
işaretini kullanarak temel bir resim belirtilerek işlev dağıtımları için otomatik temel resim güncellemeleri de kullanılır. Cloud Run için otomatik temel görüntü güncellemeleri, Google'ın temel görüntünün işletim sistemi ve dil çalışma zamanı bileşenlerine otomatik olarak güvenlik yamaları uygulamasına olanak tanır. Temel görüntünün güncellenmesi için hizmetinizi yeniden oluşturmanız veya yeniden dağıtmanız gerekmez. Daha fazla bilgi için otomatik temel resim güncellemeleri başlıklı makaleyi inceleyin.
Otomatik temel resim güncellemelerini kullanmamayı tercih ederseniz bu codelab'de gösterilen örneklerden --base-image
işaretini kaldırabilirsiniz.
Neler öğreneceksiniz?
- Cloud Run işlevlerine genel bakış ve otomatik temel görüntü güncellemelerini kullanma
- HTTP çağrılarına yanıt veren bir işlev yazma
- Pub/Sub mesajlarına yanıt veren bir işlev yazma
- Cloud Storage etkinliklerine yanıt veren bir işlev yazma
- Trafiği iki düzeltme arasında bölme
- Minimum örneklerle soğuk başlatma sorununu nasıl ortadan kaldırabilirsiniz?
2. Kurulum ve Gereksinimler
Kök klasör oluşturma
Tüm örnekler için bir kök klasör oluşturun.
mkdir crf-codelab cd crf-codelab
Ortam değişkenlerini ayarlama
Bu codelab boyunca kullanılacak ortam değişkenlerini ayarlayın.
gcloud config set project <YOUR-PROJECT-ID> REGION=<YOUR_REGION> PROJECT_ID=$(gcloud config get-value project)
API'leri etkinleştir
Gerekli tüm hizmetleri etkinleştirin:
gcloud services enable \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ eventarc.googleapis.com \ run.googleapis.com \ logging.googleapis.com \ pubsub.googleapis.com
3. HTTP İşlevi
İlk işlev için HTTP isteklerine yanıt veren bir kimliği doğrulanmış Node.js işlevi oluşturalım. Ayrıca, bir işlevin HTTP isteklerine yanıt vermek için nasıl daha fazla zamanı olabileceğini göstermek amacıyla 10 dakikalık bir zaman aşımı kullanalım.
Oluştur
Uygulama için bir klasör oluşturun ve bu klasöre gidin:
mkdir hello-http cd hello-http
HTTP isteklerine yanıt veren bir index.js
dosyası oluşturun:
const functions = require('@google-cloud/functions-framework'); functions.http('helloWorld', (req, res) => { res.status(200).send('HTTP with Node.js in Cloud Run functions!'); });
Bağımlılıkları belirtmek için bir package.json
dosyası oluşturun:
{ "name": "nodejs-run-functions-codelab", "version": "0.0.1", "main": "index.js", "dependencies": { "@google-cloud/functions-framework": "^2.0.0" } }
Dağıt
İşlevi dağıtın:
gcloud run deploy nodejs-run-function \ --source . \ --function helloWorld \ --base-image nodejs22 \ --region $REGION \ --timeout 600 \ --no-allow-unauthenticated
Bu komut, işlev kaynak kodunuzu üretime hazır bir kapsayıcı görüntüsüne dönüştürmek için buildpack'leri kullanır.
Lütfen şunları unutmayın:
--source
işareti, Cloud Run'a işlevi çalıştırılabilir bir kapsayıcı tabanlı hizmet olarak oluşturmasını söylemek için kullanılır.--function
işareti (yeni), yeni hizmetin giriş noktasını çağrılmasını istediğiniz işlev imzası olarak ayarlamak için kullanılır.--base-image
işareti (yeni), işleviniz için temel resim ortamını (ör.nodejs22
,python312
,go123
,java21
,dotnet8
,ruby33
veyaphp83
) belirtir. Temel resimler ve her resimde bulunan paketler hakkında daha fazla bilgi için Çalışma zamanı temel resimleri başlıklı makaleyi inceleyin.- (isteğe bağlı)
--timeout
işareti, işlevin HTTP isteklerine yanıt vermek için daha uzun bir zaman aşımına sahip olmasına olanak tanır. Bu örnekte, 10 dakikalık yanıt süresini göstermek için 600 saniye kullanılmıştır. - (isteğe bağlı) İşlevinizin herkese açık olarak çağrılmasını önlemek için
--no-allow-unauthenticated
Test etme
Aşağıdaki komutlarla işlevi test edin:
# 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
Yanıt olarak HTTP with Node.js in Cloud Run functions!
mesajını görmeniz gerekir.
4. Pub/Sub işlevi
İkinci işlev için belirli bir konuda yayınlanan Pub/Sub mesajıyla tetiklenen bir Python işlevi oluşturalım.
Pub/Sub yetkilendirme jetonlarını ayarlama
Pub/Sub hizmet hesabını 8 Nisan 2021'de veya daha önce etkinleştirdiyseniz Pub/Sub hizmet hesabına iam.serviceAccountTokenCreator
rolünü verin:
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
Oluştur
Örnekte kullanılacak bir Pub/Sub konusu oluşturun:
TOPIC=cloud-run-functions-pubsub-topic gcloud pubsub topics create $TOPIC
Uygulama için bir klasör oluşturun ve bu klasöre gidin:
mkdir ../hello-pubsub cd ../hello-pubsub
CloudEvent kimliğini içeren bir mesajı kaydeden bir main.py
dosyası oluşturun:
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'])
Bağımlılıkları belirtmek için aşağıdaki içeriklere sahip bir requirements.txt
dosyası oluşturun:
functions-framework==3.*
Dağıt
İşlevi dağıtın:
gcloud run deploy python-pubsub-function \ --source . \ --function hello_pubsub \ --base-image python313 \ --region $REGION \ --no-allow-unauthenticated
Hizmet hesabı kimliği için kullanılacak proje numarasını alın.
PROJECT_NUMBER=$(gcloud projects list --filter="project_id:$PROJECT_ID" --format='value(project_number)')
Tetikleyiciyi oluşturma
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 etme
Konuya mesaj göndererek işlevi test edin:
gcloud pubsub topics publish $TOPIC --message="Hello World"
Alınan CloudEvent'i günlüklerde görmeniz gerekir:
gcloud run services logs read python-pubsub-function --region $REGION --limit=10
5. Cloud Storage işlevi
Bir sonraki işlev için Cloud Storage paketindeki etkinliklere yanıt veren bir Node.js işlevi oluşturalım.
Kur
Cloud Storage işlevlerini kullanmak için Cloud Storage hizmet hesabına pubsub.publisher
IAM rolünü verin:
SERVICE_ACCOUNT=$(gsutil kms serviceaccount -p $PROJECT_NUMBER) gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:$SERVICE_ACCOUNT \ --role roles/pubsub.publisher
Oluştur
Uygulama için bir klasör oluşturun ve bu klasöre gidin:
mkdir ../hello-storage cd ../hello-storage
Yalnızca Cloud Storage etkinliklerine yanıt veren bir index.js
dosyası oluşturun:
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); });
Bağımlılıkları belirtmek için bir package.json
dosyası oluşturun:
{ "name": "nodejs-crf-cloud-storage", "version": "0.0.1", "main": "index.js", "dependencies": { "@google-cloud/functions-framework": "^2.0.0" } }
Dağıt
Öncelikle bir Cloud Storage paketi oluşturun (veya mevcut bir paketi kullanın):
export BUCKET_NAME="gcf-storage-$PROJECT_ID" export BUCKET="gs://gcf-storage-$PROJECT_ID" gsutil mb -l $REGION $BUCKET
İşlevi dağıtın:
gcloud run deploy nodejs-crf-cloud-storage \ --source . \ --base-image nodejs22 \ --function helloStorage \ --region $REGION \ --no-allow-unauthenticated
İşlev dağıtıldıktan sonra Cloud Console'un Cloud Run bölümünde görebilirsiniz.
Şimdi Eventarc tetikleyicisini oluşturun.
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 etme
Pakete dosya yükleyerek işlevi test edin:
echo "Hello World" > random.txt gsutil cp random.txt $BUCKET/random.txt
Alınan CloudEvent'i günlüklerde görmeniz gerekir:
gcloud run services logs read nodejs-crf-cloud-storage --region $REGION --limit=10
6. Cloud Denetleme Günlükleri
Bir sonraki işlev için, Compute Engine sanal makine örneği oluşturulduğunda Cloud Denetleme Günlüğü etkinliği alan bir Node.js işlevi oluşturalım. Buna karşılık olarak, yeni oluşturulan sanal makineye sanal makinenin oluşturucusunu belirten bir etiket ekler.
Yeni oluşturulan Compute Engine VM'lerini belirleme
Compute Engine, bir sanal makine oluşturulduğunda 2 denetim günlüğü yayınlar.
İlki, sanal makine oluşturma işleminin başında yayınlanır. İkincisi, sanal makine oluşturulduktan sonra yayınlanır.
Denetleme günlüklerinde işlem alanları farklıdır ve first: true
ile last: true
değerlerini içerir. İkinci denetleme günlüğü, bir örneği etiketlemek için ihtiyaç duyduğumuz tüm bilgileri içerir. Bu nedenle, Cloud Run işlevlerinde bunu algılamak için last: true
işaretini kullanırız.
Kur
Cloud Audit Log işlevlerini kullanmak için Eventarc'ta denetleme günlüklerini etkinleştirmeniz gerekir. Ayrıca eventarc.eventReceiver
rolüne sahip bir hizmet hesabı kullanmanız gerekir.
- Compute Engine API için Cloud Audit Logs Admin Read, Data Read ve Data Write günlük türlerini etkinleştirin.
- Varsayılan Compute Engine hizmet hesabına
eventarc.eventReceiver
IAM rolünü verin:
gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com \ --role roles/eventarc.eventReceiver
İşlevi oluşturma
Bu codelab'de node.js kullanılmaktadır ancak https://github.com/GoogleCloudPlatform/eventarc-samples adresinde başka örnekler de bulabilirsiniz.
package.json
dosyası oluşturma
{
"dependencies": {
"googleapis": "^84.0.0"
}
}
node.js
dosyası oluşturma
// 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;
}
Dağıt
İşlevi dağıtın:
gcloud run deploy gce-vm-labeler \ --source . \ --function labelVmCreation \ --region $REGION \ --no-allow-unauthenticated
Şimdi tetikleyiciyi oluşturun. Fonksiyonun, --trigger-event-filters
işaretiyle Compute Engine eklemeleri için denetleme günlüklerini nasıl filtrelediğine dikkat edin.
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 etme
Ortam değişkenlerini ayarlayın:
# if you're using europe-west1 as your region
ZONE=europe-west1-d
VM_NAME=codelab-crf-auditlog
Sanal makine oluşturmak için aşağıdaki komutu çalıştırın:
gcloud compute instances create $VM_NAME --zone=$ZONE --machine-type=e2-medium --image-family=debian-11 --image-project=debian-cloud
Sanal makine oluşturma işlemi tamamlandıktan sonra, Cloud Console'daki sanal makinede Temel bilgiler bölümünde veya aşağıdaki komutu kullanarak eklenen creator
etiketini görmeniz gerekir:
gcloud compute instances describe $VM_NAME --zone=$ZONE
Çıkışta etiketi aşağıdaki örnekteki gibi görmeniz gerekir:
... labelFingerprint: ULU6pAy2C7s= labels: creator: atameldev ...
Temizleme
Sanal makine örneğini sildiğinizden emin olun. Bu laboratuvarda tekrar kullanılmayacaktır.
gcloud compute instances delete $VM_NAME --zone=$ZONE
7. Trafiği bölme
Cloud Run işlevleri, işlevlerinizin birden fazla revizyonunu destekler, trafiği farklı revizyonlar arasında böler ve işlevinizi önceki bir sürüme geri alır.
Bu adımda, bir işlevin 2 düzeltmesini dağıtacak ve ardından trafiği aralarında %50-%50 böleceksiniz.
Oluştur
Uygulama için bir klasör oluşturun ve bu klasöre gidin:
mkdir ../traffic-splitting cd ../traffic-splitting
Bir renk ortam değişkenini okuyan ve bu arka plan renginde Hello World
ile yanıt veren bir Python işlevi içeren bir main.py
dosyası oluşturun:
import os color = os.environ.get('COLOR') def hello_world(request): return f'<body style="background-color:{color}"><h1>Hello World!</h1></body>'
Bağımlılıkları belirtmek için aşağıdaki içeriklere sahip bir requirements.txt
dosyası oluşturun:
functions-framework==3.*
Dağıt
Fonksiyonun ilk düzeltmesini turuncu arka planla dağıtın:
COLOR=orange gcloud run deploy hello-world-colors \ --source . \ --base-image python313 \ --function hello_world \ --region $REGION \ --allow-unauthenticated \ --update-env-vars COLOR=$COLOR
Bu noktada, HTTP tetikleyiciyi (yukarıdaki dağıtım komutunun URI çıkışı) tarayıcınızda görüntüleyerek işlevi test ederseniz turuncu arka planlı Hello World
görmeniz gerekir:
İkinci düzeltmeyi sarı arka planla dağıtın:
COLOR=yellow gcloud run deploy hello-world-colors \ --source . \ --base-image python313 \ --function hello_world \ --region $REGION \ --allow-unauthenticated \ --update-env-vars COLOR=$COLOR
Bu en son düzeltme olduğundan işlevi test ederseniz sarı arka planlı Hello World
görmeniz gerekir:
Trafiği 50-50 bölme
Turuncu ve sarı revizyonlar arasında trafiği bölmek için Cloud Run hizmetlerinin revizyon kimliklerini bulmanız gerekir. Düzeltme kimliklerini görmek için kullanılan komut:
gcloud run revisions list --service hello-world-colors \ --region $REGION --format 'value(REVISION)'
Çıkış şu şekilde görünmelidir:
hello-world-colors-00001-man hello-world-colors-00002-wok
Şimdi trafiği bu iki düzeltme arasında aşağıdaki şekilde bölün (X-XXX
değerini düzeltme adlarınıza göre güncelleyin):
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 etme
Herkese açık URL'sini ziyaret ederek işlevi test edin. Yarı yarıya olacak şekilde turuncu ve sarı düzeltmeyi görmelisiniz:
Daha fazla bilgi için geri alma, kademeli kullanıma sunma ve trafik taşıma başlıklı makaleyi inceleyin.
8. Minimum örnek sayısı
Cloud Run işlevlerinde, sıcak tutulacak ve isteklere hizmet vermeye hazır olacak minimum işlev örneği sayısı belirtebilirsiniz. Bu, sıfırdan başlatma sayısını sınırlamak için kullanışlıdır.
Bu adımda, yavaş başlatılan bir işlevi dağıtacaksınız. Soğuk başlatma sorununu gözlemlersiniz. Ardından, sıfırdan başlatmayı ortadan kaldırmak için minimum örnek değerini 1 olarak ayarlayarak işlevi dağıtırsınız.
Oluştur
Uygulama için bir klasör oluşturun ve bu klasöre gidin:
mkdir ../min-instances cd ../min-instances
main.go
dosyası oluşturun. Bu Go hizmetinde, uzun bir başlatma işlemini simüle etmek için 10 saniye boyunca uyku modunda kalan bir init
işlevi var. Ayrıca, HTTP çağrılarına yanıt veren bir HelloWorld
işlevi de vardır:
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!") }
Dağıt
İşlevin ilk düzeltmesini varsayılan minimum örnek değeri olan sıfırla dağıtın:
gcloud run deploy go-slow-function \ --source . \ --base-image go123 \ --function HelloWorld \ --region $REGION \ --no-allow-unauthenticated
Aşağıdaki komutla işlevi test edin:
# 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
İlk aramada 10 saniyelik bir gecikme (soğuk başlatma) yaşarsınız ve ardından mesajı görürsünüz. Sonraki aramalar hemen döndürülmelidir.
Minimum örnek sayısını ayarlama
İlk istekte sıfırdan başlatma sorununu gidermek için işlevi aşağıdaki gibi --min-instances
bayrağı 1 olarak ayarlanmış şekilde yeniden dağıtın:
gcloud run deploy go-slow-function \ --source . \ --base-image go123 \ --function HelloWorld \ --region $REGION \ --no-allow-unauthenticated \ --min-instances 1
Test etme
İşlevi tekrar test edin:
curl -H "Authorization: bearer $(gcloud auth print-identity-token)" -X GET $SERVICE_URL
Artık ilk istekte 10 saniyelik gecikme görmemeniz gerekir. Minimum örnekler sayesinde, ilk çağırmada (uzun süre kullanılmadıktan sonra) karşılaşılan soğuk başlatma sorunu ortadan kalktı.
Daha fazla bilgi için minimum örnekleri kullanma başlıklı makaleyi inceleyin.
9. Tebrikler!
Codelab'i tamamladığınız için tebrikler.
İşlediğimiz konular
- Cloud Run işlevlerine genel bakış ve otomatik temel görüntü güncellemelerini kullanma
- HTTP çağrılarına yanıt veren bir işlev yazma
- Pub/Sub mesajlarına yanıt veren bir işlev yazma
- Cloud Storage etkinliklerine yanıt veren bir işlev yazma
- Trafiği iki düzeltme arasında bölme
- Minimum örneklerle soğuk başlatma sorununu nasıl ortadan kaldırabilirsiniz?