CREMA'yı kullanarak Cloud Run çalışan havuzlarını Pub/Sub kuyruk hacmine göre otomatik ölçeklendirme

1. Giriş

Genel Bakış

Bu eğitimde, Pub/Sub mesajlarını işlemek için Cloud Run işçi havuzunun (tüketici) nasıl dağıtılacağı ve Cloud Run Harici Metrikler Otomatik Ölçeklendirme (CREMA) kullanılarak tüketici örneklerinizin kuyruk derinliğine göre nasıl otomatik olarak ölçeklendirileceği gösterilmektedir.

Neler öğreneceksiniz?

Bu codelab'de şunları yapacaksınız:

  • Pub/Sub konusu ve aboneliği oluşturup bu konuya mesaj gönderme
  • Pub/Sub'dan mesaj tüketen bir Cloud Run işçi havuzu (tüketici) dağıtın.
  • Çalışan havuzunuzu Pub/Sub aboneliğindeki ileti sayısına göre otomatik olarak ölçeklendirmek için GitHub'daki CREMA projesini Cloud Run hizmeti olarak dağıtın.
  • Yerel olarak bir Python komut dosyası çalıştırarak yük oluşturup otomatik ölçeklendirme yapılandırmanızı test edin.

2. Ortam değişkenlerini yapılandırma

Bu codelab'de birçok ortam değişkeni kullanıldığından

set -u

Bu işlev, henüz ayarlanmamış bir ortam değişkeni kullanmaya çalıştığınızda sizi uyarır. Bu ayarı geri almak için set +u komutunu çalıştırın.

Öncelikle aşağıdaki değişkeni proje kimliğinizle değiştirin.

export PROJECT_ID=<YOUR_PROJECT_ID>

ve ardından bu codelab için proje olarak ayarlayın.

gcloud config set project $PROJECT_ID

Ardından, bu codelab'de kullanılan ortam değişkenlerini ayarlayın.

export REGION=us-central1
export TOPIC_ID=crema-pubsub-topic
export SUBSCRIPTION_ID=crema-pubsub-sub
export CREMA_SA_NAME=crema-service-account
export CONSUMER_SA_NAME=consumer-service-account
export CONSUMER_WORKER_POOL_NAME=worker-pool-consumer
export CREMA_SERVICE_NAME=my-crema-service

Bu codelab için bir dizin oluşturun

mkdir crema-pubsub-codelab
cd crema-pubsub-codelab

API'leri etkinleştir

gcloud services enable \
        artifactregistry.googleapis.com \
        cloudbuild.googleapis.com \
        run.googleapis.com \
        parametermanager.googleapis.com

Son olarak, gcloud'unuzun en son sürümü kullandığından emin olun.

gcloud components update

3. Pub/Sub kurulumu

Çalışan havuzunuzun işleyeceği konuyu ve çekme aboneliğini oluşturun. Bash

Konuyu oluşturun.

gcloud pubsub topics create $TOPIC_ID

Aboneliği oluşturun.

gcloud pubsub subscriptions create $SUBSCRIPTION_ID --topic=$TOPIC_ID

4. IAM ve Hizmet Hesapları

Her Cloud Run kaynağı için bir hizmet hesabı oluşturmanız önerilir. Bu codelab'de şunları oluşturacaksınız:

  • Tüketici SA: Pub/Sub mesajlarını işleyen çalışan havuzunun kimliği.
  • CREMA SA: CREMA otomatik ölçeklendirme hizmetinin kimliği.

Hizmet Hesapları Oluşturma

Çalışan havuzu tüketicisi SA'sını oluşturun:

gcloud iam service-accounts create $CONSUMER_SA_NAME \
  --display-name="PubSub Consumer Service Account"

Çalışan havuzu CREMA hizmeti SA'sını oluşturun:

gcloud iam service-accounts create $CREMA_SA_NAME \
  --display-name="CREMA Autoscaler Service Account"

Consumer SA'ya izin verme

Abonelikten mesaj çekmek için çalışan havuzu tüketicisi SA'ya izin verin.

gcloud pubsub subscriptions add-iam-policy-binding $SUBSCRIPTION_ID \
  --member="serviceAccount:$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/pubsub.subscriber"

CREMA SA'ya izin verme

CREMA'nın parametreleri okuması, çalışan havuzunu ölçeklendirmesi ve Pub/Sub metriklerini izlemesi için izinler gerekir.

  1. Parametre Yöneticisi'ne (Yapılandırma Okuyucu) erişme:
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/parametermanager.parameterViewer"
  1. Çalışan havuzunu ölçeklendirme (Cloud Run Geliştiricisi):
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/run.developer"
  1. Pub/Sub'ı izleme:

İzleme görüntüleyici rolünü verin.

gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/monitoring.viewer"

CREMA service SA aboneliğine bir politika ekleyerek politikayı görüntüleme

gcloud pubsub subscriptions add-iam-policy-binding $SUBSCRIPTION_ID \
  --member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/pubsub.viewer"

CREMA SA'nın, örnek sayısını değiştirmek için gerekli olan Hizmet Hesabı Kullanıcısı'na da ihtiyacı vardır:

gcloud iam service-accounts add-iam-policy-binding \
    $CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com \
    --member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
    --role="roles/iam.serviceAccountUser"

5. SA izinlerini doğrulama

Codelab'e devam etmeden önce CREMA hizmeti SA'sının doğru proje düzeyinde rollere sahip olduğunu doğrulayın.

gcloud projects get-iam-policy $PROJECT_ID \
  --flatten="bindings[].members" \
  --format="table(bindings.role)" \
  --filter="bindings.members:serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com"

Aşağıdaki sonuçlar elde edilmelidir:

roles/monitoring.viewer
roles/parametermanager.parameterViewer
roles/run.developer

Pub/Sub aboneliğinin, CREMA hizmeti SA'nın görüntülemesine izin veren bir politikası olduğunu doğrulayın.

gcloud pubsub subscriptions get-iam-policy $SUBSCRIPTION_ID \
  --flatten="bindings[].members" \
  --filter="bindings.members:serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
  --format="table(bindings.role)"

Şununla sonuçlanmalıdır:

roles/pubsub.viewer

ve CREMA SA'nın Hizmet Hesabı Kullanıcısı rolüne sahip olduğunu doğrulayın.

gcloud iam service-accounts get-iam-policy \
  $CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com \
  --flatten="bindings[].members" \
  --filter="bindings.members:serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com"

Aşağıdaki sonuçları vermelidir:

bindings:
  members: serviceAccount:crema-service-account@<PROJECT_ID>.iam.gserviceaccount.com
  role: roles/iam.serviceAccountUser

Worker Pool Consumer SA, Pub/Sub abonesi rolüne sahip olmalıdır.

gcloud pubsub subscriptions get-iam-policy $SUBSCRIPTION_ID \
  --flatten="bindings[].members" \
  --filter="bindings.members:serviceAccount:$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
  --format="table(bindings.role)"

Şununla sonuçlanmalıdır:

ROLE
roles/pubsub.subscriber

6. Tüketici Çalışan Havuzu'nu Oluşturma ve Dağıtma

Tüketici kodunuz için bir dizin oluşturun ve bu dizini girin.

mkdir consumer
cd consumer
  1. consumer.py dosyası oluşturma
import os
import time
from google.cloud import pubsub_v1
from concurrent.futures import TimeoutError

# Configuration
PROJECT_ID = os.environ.get('PROJECT_ID')
SUBSCRIPTION_ID = os.environ.get('SUBSCRIPTION_ID')

subscription_path = f"projects/{PROJECT_ID}/subscriptions/{SUBSCRIPTION_ID}"

print(f"Worker Pool instance starting. Watching {subscription_path}...")

subscriber = pubsub_v1.SubscriberClient()

def callback(message):
    try:
        data = message.data.decode("utf-8")
        print(f"Processing job: {data}")
        time.sleep(5)  # Simulate work
        print(f"Done {data}")
        message.ack()
    except Exception as e:
        print(f"Error processing message: {e}")
        message.nack()

streaming_pull_future = subscriber.subscribe(subscription_path, callback=callback)
print(f"Listening for messages on {subscription_path}...")

# Wrap subscriber in a 'with' block to automatically call close() when done.
with subscriber:
    try:
        # When `timeout` is not set, result() will block indefinitely,
        # unless an exception is encountered first.
        streaming_pull_future.result()
    except TimeoutError:
        streaming_pull_future.cancel()  # Trigger the shutdown.
        streaming_pull_future.result()  # Block until the shutdown is complete.
    except Exception as e:
        print(f"Streaming pull failed: {e}")
  1. Dockerfile oluşturun
FROM python:3.12-slim
RUN pip install google-cloud-pubsub
COPY consumer.py .
CMD ["python", "-u", "consumer.py"]
  1. Tüketici Çalışan Havuzunu Dağıtma

Bu codelab'de, başlangıçta 0 örnekle çalışan havuzunun dağıtılması önerilir. Böylece, abonelikteki Pub/Sub mesajlarını algıladığında CREMA'nın çalışan havuzunu ölçeklendirmesini izleyebilirsiniz.

gcloud beta run worker-pools deploy $CONSUMER_WORKER_POOL_NAME \
  --source . \
  --region $REGION \
  --service-account="$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
  --instances=0 \
  --set-env-vars PROJECT_ID=$PROJECT_ID,SUBSCRIPTION_ID=$SUBSCRIPTION_ID

7. CREMA'yı yapılandırma

  1. Projenizin kök dizinine geri dönün.
cd ..
  1. Yapılandırma dosyasını oluşturma crema-config.yaml adlı bir dosya oluşturun.
apiVersion: crema/v1
kind: CremaConfig
spec:
  pollingInterval: 30
  triggerAuthentications:
    - metadata:
        name: adc-trigger-auth
      spec:
        podIdentity:
          provider: gcp
  scaledObjects:
    - spec:
        scaleTargetRef:
          name: projects/PROJECT_ID_PLACEHOLDER/locations/REGION_PLACEHOLDER/workerpools/CONSUMER_WORKER_POOL_NAME_PLACEHOLDER
        triggers:
          - type: gcp-pubsub
            metadata:
              subscriptionName: "SUBSCRIPTION_ID_PLACEHOLDER"
              # Target number of undelivered messages per worker instance
              value: "10"
              mode: "SubscriptionSize"
            authenticationRef:
              name: adc-trigger-auth
  1. Değişkenleri Değiştirme
sed -i "s/PROJECT_ID_PLACEHOLDER/$PROJECT_ID/g" crema-config.yaml
sed -i "s/REGION_PLACEHOLDER/$REGION/g" crema-config.yaml
sed -i "s/CONSUMER_WORKER_POOL_NAME_PLACEHOLDER/$CONSUMER_WORKER_POOL_NAME/g" crema-config.yaml
sed -i "s/SUBSCRIPTION_ID_PLACEHOLDER/$SUBSCRIPTION_ID/g" crema-config.yaml
  1. crema-config.yaml adresinizin doğru olduğunu doğrulayın
if grep -q "_PLACEHOLDER" crema-config.yaml; then
  echo "❌ ERROR: Validations failed. '_PLACEHOLDER' was found in crema-config.yaml."
  echo "Please check your environment variables and run the 'sed' commands again."
else
  echo "✅ Config check passed: No placeholders found."
fi
  1. Parametre Yöneticisi'ne yükleme

Parametre Yöneticisi için ek ortam değişkenleri ayarlama

export PARAMETER_ID=crema-config
export PARAMETER_REGION=global
export PARAMETER_VERSION=1

Parametre kaynağını oluşturma

gcloud parametermanager parameters create $PARAMETER_ID \
  --location=$PARAMETER_REGION \
  --parameter-format=YAML

Parametre Sürümü 1 Oluşturma

gcloud parametermanager parameters versions create $PARAMETER_VERSION \
  --parameter=crema-config \
  --project=$PROJECT_ID \
  --location=$PARAMETER_REGION \
  --payload-data-from-file=crema-config.yaml

Parametrenin başarıyla eklendiğini doğrulama

gcloud parametermanager parameters versions list \
  --parameter=$PARAMETER_ID \
  --location=$PARAMETER_REGION

Aşağıdakine benzer bir ifade görürsünüz:

projects/<YOUR_PROJECT_ID>/locations/global/parameters/crema-config/versions/1

8. CREMA Hizmeti'ni dağıtma

Bu bölümde CREMA otomatik ölçeklendirici hizmetini dağıtacaksınız. Herkese açık olan resmi kullanırsınız.

  1. CREMA için gereken ortam değişkenlerini ayarlayın
CREMA_CONFIG_PARAM_VERSION=projects/$PROJECT_ID/locations/$PARAMETER_REGION/parameters/$PARAMETER_ID/versions/$PARAMETER_VERSION
  1. Sürüm adı yolunu doğrulayın
echo $CREMA_CONFIG_PARAM_VERSION

Şöyle görünmelidir:

projects/<YOUR_PROJECT>/locations/global/parameters/crema-config/versions/1
  1. CREMA görüntüsü için ortam değişkenini ayarlayın
IMAGE=us-central1-docker.pkg.dev/cloud-run-oss-images/crema-v1/autoscaler:1.0
  1. ve CREMA hizmetini dağıtma

Temel görüntünün gerekli olduğunu unutmayın.

gcloud beta run deploy $CREMA_SERVICE_NAME \
  --image=$IMAGE \
  --region=${REGION} \
  --service-account="${CREMA_SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --no-allow-unauthenticated \
  --no-cpu-throttling \
  --labels=created-by=crema \
  --base-image=us-central1-docker.pkg.dev/serverless-runtimes/google-24/runtimes/java25 \
  --set-env-vars="CREMA_CONFIG=${CREMA_CONFIG_PARAM_VERSION},OUTPUT_SCALER_METRICS=True,ENABLE_CLOUD_LOGGING=True"

9. Yük Testi

  1. Pub/Sub konusuna mesaj yayınlayacak bir komut dosyası oluşturun.
touch load-pubsub.sh
  1. Aşağıdaki kodu load-pubsub.sh dosyasına ekleyin.
#!/bin/bash
TOPIC_ID=${TOPIC_ID} 
PROJECT_ID=${PROJECT_ID}
NUM_MESSAGES=100

echo "Publishing $NUM_MESSAGES messages to topic $TOPIC_ID..."

for i in $(seq 1 $NUM_MESSAGES); do
  gcloud pubsub topics publish $TOPIC_ID --message="job-$i" --project=$PROJECT_ID &
  if (( $i % 10 == 0 )); then
    wait
    echo "Published $i messages..."
  fi
done
wait
echo "Done. All messages published."
  1. Yük Testi Çalıştırma
chmod +x load-pubsub.sh
./load-pubsub.sh
  1. Ölçeklendirme işlemini izleyin. 3-4 dakika bekleyin. Yeni authenticationRef yapılandırmasına göre örnekler önerdiğini görmek için CREMA günlüklerini görüntüleyin.
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=$CREMA_SERVICE_NAME AND textPayload:SCALER" \
  --limit=20 \
  --format="value(textPayload)" \
  --freshness=5m
  1. İşleme İzleme: Kullanıcı günlüklerini görüntüleyerek başlatıldığını görebilirsiniz.
gcloud beta run worker-pools logs tail $CONSUMER_WORKER_POOL_NAME --region=$REGION

Aşağıdaki gibi günlükler görmeniz gerekir:

Done job-100

10. Sorun giderme

Öncelikle sorunun CREMA hizmet yapılandırmasıyla mı yoksa PubSub tüketici yapılandırmasıyla mı ilgili olduğunu belirlemeniz gerekir.

PubSub tüketici otomatik ölçeklendiricisini 0 yerine 1 olarak ayarlayın. Pub/sub iletilerini hemen işlemeye başlıyorsa bu, CREMA ile ilgili bir sorundur. Pubsub iletilerini işlemezse pubsub tüketicisiyle ilgili bir sorun vardır.

11. Tebrikler!

Codelab'i tamamladığınız için tebrikler.

Cloud Run belgelerini incelemenizi öneririz.

İşlediğimiz konular

  • Pub/Sub konusu ve aboneliği oluşturma ve bu konuya mesaj gönderme
  • Pub/Sub'dan mesaj tüketen bir Cloud Run işçi havuzu (tüketici) nasıl dağıtılır?
  • CREMA projesini GitHub'da Cloud Run hizmeti olarak dağıtarak çalışan havuzunuzu Pub/Sub aboneliğindeki ileti sayısına göre otomatik olarak ölçeklendirme
  • Yerel olarak bir Python komut dosyası çalıştırarak yük oluşturup otomatik ölçeklendirme yapılandırmanızı test etme

12. Temizleme

Bu eğiticide kullanılan kaynaklar için Google Cloud hesabınızın ücretlendirilmesini istemiyorsanız bu codelab'de oluşturduğunuz kaynakları veya projenin tamamını silebilirsiniz.

Bu codelab'de kullanılan kaynakları silme

  1. Cloud Run CREMA hizmetini silin.
gcloud run services delete $CREMA_SERVICE_NAME --region=$REGION --quiet
  1. Cloud Run çalışan havuzu tüketicisini silme
gcloud beta run worker-pools delete $CONSUMER_WORKER_POOL_NAME --region=$REGION --quiet
  1. Pub/Sub aboneliğini ve konusunu silme
gcloud pubsub subscriptions delete $SUBSCRIPTION_ID --quiet
gcloud pubsub topics delete $TOPIC_ID --quiet
  1. Parametre Yöneticisi yapılandırmasını silin.

Parametrenin içindeki sürümü silme

gcloud parametermanager parameters versions delete $PARAMETER_VERSION \
  --parameter=$PARAMETER_ID \
  --location=$PARAMETER_REGION \
  --quiet

Şimdi boş parametreyi silin.

gcloud parametermanager parameters delete $PARAMETER_ID \
  --location=$PARAMETER_REGION \
  --quiet
  1. Hizmet hesaplarını silme
gcloud iam service-accounts delete "$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" --quiet
gcloud iam service-accounts delete "$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" --quiet

Veya projenin tamamını silme

Projenin tamamını silmek için Kaynakları Yönet'e gidin, 2. adımda oluşturduğunuz projeyi seçin ve Sil'i tıklayın. Projeyi silerseniz Cloud SDK'nızda projeleri değiştirmeniz gerekir. gcloud projects list komutunu çalıştırarak kullanılabilir tüm projelerin listesini görüntüleyebilirsiniz.