1. Einführung
Übersicht
In diesem Codelab erfahren Sie, wie Sie eine ereignisgesteuerte, asynchrone KI-Verarbeitungspipeline erstellen. Sie stellen ein Open-Source-Modell mit Ollama in einem Cloud Run-Worker-Pool bereit. Der Worker-Pool ruft Nachrichten aus einem Pub/Sub-Thema ab und verarbeitet sie mit einem gemma3:4b-Modell.
Lerninhalte
- Worker-Pools mit einem Pub/Sub-Pull-Abo verwenden
- Ollama für die Inferenz als Worker-Pool verwenden
2. Hinweis
APIs aktivieren
Bevor Sie mit diesem Codelab beginnen können, müssen Sie die folgenden APIs aktivieren. Führen Sie dazu folgenden Befehl aus:
gcloud services enable run.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
pubsub.googleapis.com \
storage.googleapis.com
3. Einrichtung und Anforderungen
So richten Sie die erforderlichen Ressourcen ein:
- Legen Sie Umgebungsvariablen für dieses Codelab fest:
export PROJECT_ID=<YOUR_PROJECT_ID>
export REGION=<YOUR_REGION>
export BUCKET_NAME=$PROJECT_ID-gemma3-4b
export SERVICE_ACCOUNT_NAME=ollama-worker-sa
export SERVICE_ACCOUNT_EMAIL=${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com
export TOPIC_NAME=ollama-prompts
export SUBSCRIPTION_NAME=ollama-prompts-sub
export AR_REPO_NAME=ollama-worker-repo
export PULL_MSG_IMAGE_NAME=pubsub-pull-msg
export OLLAMA_IMAGE_NAME=ollama-coordinator
- Dienstkonto für den Worker-Pool erstellen
gcloud iam service-accounts create ${SERVICE_ACCOUNT_NAME} \
--display-name="Ollama Worker Service Account"
- Dienstkonto Zugriff auf Pub/Sub gewähren
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:${SERVICE_ACCOUNT_EMAIL}" \
--role="roles/pubsub.subscriber"
- AR-Repository für das Worker-Pool-Image erstellen
gcloud artifacts repositories create ${AR_REPO_NAME} \
--repository-format=docker \
--location=${REGION}
- Pub/Sub-Thema und -Abo erstellen
gcloud pubsub topics create $TOPIC_NAME
gcloud pubsub subscriptions create $SUBSCRIPTION_NAME --topic $TOPIC_NAME
4. Modell herunterladen und auf GCS hosten
Anstatt das Modell während des Build-Prozesses direkt in den Container zu ziehen, was langsam und ineffizient sein kann, ziehen wir das Modell mit der Ollama-Befehlszeile auf einen lokalen Computer und laden die Modelldateien dann in einen GCS-Bucket hoch. Der Worker-Pool hängt diesen Bucket dann ein, um auf das Modell zuzugreifen.
- Ollama auf Ihrem lokalen Computer installieren:
Führen Sie den folgenden Befehl aus, um Ollama unter Linux zu installieren. Informationen zu anderen Betriebssystemen finden Sie auf der Ollama-Website.
curl -fsSL https://ollama.com/install.sh | sh
- Ollama-Dienst starten und Modell abrufen:
Starten Sie zuerst den Ollama-Dienst im Hintergrund.
ollama serve &
ollama pull gemma3:4b
- GCS-Bucket erstellen:
Erstellen Sie den GCS-Bucket mit der zuvor festgelegten Umgebungsvariable BUCKET_NAME.
gsutil mb gs://${BUCKET_NAME}
- Modell-Dateien in Ihren GCS-Bucket hochladen:
Ollama speichert Modelldateien im Verzeichnis ~/.ollama/models. Laden Sie den Inhalt dieses Verzeichnisses in Ihren GCS-Bucket hoch. Dadurch werden alle heruntergeladenen Modelle kopiert.
gsutil -m cp -r ~/.ollama/models/* gs://${BUCKET_NAME}/
- Dienstkonto Zugriff auf den Cloud Storage-Bucket gewähren
gcloud storage buckets add-iam-policy-binding gs://${BUCKET_NAME} \
--member=serviceAccount:${SERVICE_ACCOUNT_EMAIL} \
--role=roles/storage.objectViewer
5. Cloud Run-Job erstellen
Für den Cloud Run-Job werden zwei Container verwendet:
- ollama-coordinator – zum Hosten von Ollama und Bereitstellen des Gemma 3 4B-Modells
- pubsub-pull-msg – zum Abrufen von Nachrichten aus dem Pub/Sub-Abo und zum Übergeben der Nachricht an den ollama-coordinator-Container
Zuerst erstellen Sie den ollama-coordinator-Container.
- Erstellen Sie ein übergeordnetes Verzeichnis für das Codelab:
mkdir codelab-ollama-wp
cd codelab-ollama-wp
- Verzeichnis für den ollama-coordinator-Container erstellen
mkdir ollama-coordinator
cd ollama-coordinator
- Erstellen Sie ein
Dockerfilemit folgendem Inhalt:
# Use the official Ollama image as a base image
FROM ollama/ollama
# Expose the port that Ollama listens on
EXPOSE 11434
# Set the entrypoint to start the Ollama server
ENTRYPOINT ["ollama", "serve"]
- Ollama-Container erstellen
gcloud builds submit --tag ${REGION}-docker.pkg.dev/${PROJECT_ID}/${AR_REPO_NAME}/${OLLAMA_IMAGE_NAME} --timeout=20m
Als Nächstes erstellen Sie den Container „pubsub-pull-msg“.
- Verzeichnis für den Container „pubsub-pull-msg“ erstellen
cd ..
mkdir pubsub-pull-msg
cd pubsub-pull-msg
Dockerfileerstellen
# Use the official Python image as a base image
FROM python:3.9-slim
# Set the working directory in the container
WORKDIR /app
# Copy the requirements file into the container
COPY requirements.txt .
# Install the required Python packages
RUN pip install --no-cache-dir -r requirements.txt
# Copy the Python script into the container
COPY main.py .
# Set the entrypoint to run the Python script
CMD ["python", "main.py"]
- Erstellen Sie eine
requirements.txt-Datei mit folgendem Inhalt:
google-cloud-pubsub
requests
- Erstellen Sie eine
main.py-Datei mit folgendem Inhalt:
import os
import sys
import requests
import json
from google.cloud import pubsub_v1
# --- Main Application Logic ---
print("--- Sidecar container script started ---")
# --- Environment and Configuration ---
project_id = os.environ.get("PROJECT_ID")
subscription_name = os.environ.get("SUBSCRIPTION_NAME")
ollama_api_url = "http://localhost:11434/api/generate"
if not project_id or not subscription_name:
print("FATAL: PROJECT_ID and SUBSCRIPTION_NAME must be set.")
sys.exit(1)
print(f"PROJECT_ID: {project_id}")
print(f"SUBSCRIPTION_NAME: {subscription_name}")
def callback(message):
"""Processes a single Pub/Sub message."""
print(f"Received message ID: {message.message_id}")
try:
prompt = message.data.decode("utf-8")
print(f"Decoded prompt: '{prompt}'")
data = {"model": "gemma3:4b", "prompt": prompt, "stream": False}
print("Sending request to Ollama...")
response = requests.post(ollama_api_url, json=data, timeout=300)
response.raise_for_status()
print("Successfully received response from Ollama.")
ollama_response = response.json()
print(f"Ollama response: {json.dumps(ollama_response)[:200]}...")
message.ack()
print(f"Message {message.message_id} acknowledged.")
except requests.exceptions.RequestException as e:
print(f"Error calling Ollama API: {e}")
message.nack()
print(f"Message {message.message_id} not acknowledged.")
except Exception as e:
print(f"An unexpected error occurred in callback: {e}")
message.nack()
print(f"Message {message.message_id} not acknowledged.")
def main():
"""Starts the Pub/Sub subscriber."""
subscriber = pubsub_v1.SubscriberClient()
subscription_path = subscriber.subscription_path(project_id, subscription_name)
streaming_pull_future = subscriber.subscribe(subscription_path, callback=callback)
print(f"Subscribed to {subscription_path}. Listening for messages...")
try:
# .result() will block indefinitely.
streaming_pull_future.result()
except Exception as e:
print(f"A fatal error occurred in the subscriber: {e}")
streaming_pull_future.cancel()
streaming_pull_future.result()
if __name__ == "__main__":
main()
- Erstellen Sie nun den Container „pubsub-pull-msg“.
gcloud builds submit --tag ${REGION}-docker.pkg.dev/${PROJECT_ID}/${AR_REPO_NAME}/${PULL_MSG_IMAGE_NAME}
6. Job bereitstellen und ausführen
In diesem Schritt erstellen Sie den Cloud Run-Job, indem Sie eine YAML-Datei bereitstellen.
Wechseln Sie zum Stammordner, um die YAML-Datei zu erstellen.
cd ..
- Erstellen Sie eine
worker-pool.template.yaml-Datei mit folgendem Inhalt:
apiVersion: run.googleapis.com/v1
kind: WorkerPool
metadata:
name: codelab-ollama-wp
labels:
cloud.googleapis.com/location: europe-west1
annotations:
run.googleapis.com/launch-stage: BETA
run.googleapis.com/scalingMode: manual
run.googleapis.com/manualInstanceCount: '1'
run.googleapis.com/gcs-fuse-mounter-enabled: "true"
spec:
template:
metadata:
annotations:
run.googleapis.com/gpu: "1"
run.googleapis.com/gpu-zonal-redundancy-disabled: 'true'
spec:
serviceAccountName: ${SERVICE_ACCOUNT_EMAIL}
nodeSelector:
run.googleapis.com/accelerator: nvidia-l4
volumes:
- name: gcs-bucket
csi:
driver: gcsfuse.run.googleapis.com
readOnly: true
volumeAttributes:
bucketName: ${BUCKET_NAME}
containers:
- image: ${REGION}-docker.pkg.dev/${PROJECT_ID}/${AR_REPO_NAME}/${PULL_MSG_IMAGE_NAME}
name: pubsub-pull-msg
env:
- name: PROJECT_ID
value: ${PROJECT_ID}
- name: SUBSCRIPTION_NAME
value: "ollama-prompts-sub"
- name: PYTHONUNBUFFERED
value: "1"
resources:
limits:
cpu: '1'
memory: 1Gi
- image: ${REGION}-docker.pkg.dev/${PROJECT_ID}/${AR_REPO_NAME}/${OLLAMA_IMAGE_NAME}
name: ollama-coordinator
env:
- name: OLLAMA_MODELS
value: /mnt/models
volumeMounts:
- name: gcs-bucket
mountPath: /mnt/models
resources:
limits:
cpu: '6'
nvidia.com/gpu: '1'
memory: 16Gi
Definieren Sie dann die vollständigen Bild-URLs und verwenden Sie sed, um die Variablen in der Vorlagendatei zu ersetzen und die endgültige worker-pool.yaml zu erstellen.
sed -e "s|\${SERVICE_ACCOUNT_EMAIL}|${SERVICE_ACCOUNT_EMAIL}|g" \
-e "s|\${BUCKET_NAME}|${BUCKET_NAME}|g" \
-e "s|\${PULL_MSG_IMAGE_NAME}|${PULL_MSG_IMAGE_NAME}|g" \
-e "s|\${OLLAMA_IMAGE_NAME}|${OLLAMA_IMAGE_NAME}|g" \
-e "s|\${PROJECT_ID}|${PROJECT_ID}|g" \
-e "s|\${REGION}|${REGION}|g" \
-e "s|\${AR_REPO_NAME}|${AR_REPO_NAME}|g" \
worker-pool.template.yaml > worker-pool.yaml
Jetzt können Sie die Bereitstellung vornehmen.
gcloud beta run worker-pools replace worker-pool.yaml
Und Test
gcloud pubsub topics publish ${TOPIC_NAME} --message="What is 1 + 1?"
Sehen Sie sich dann die Logs an. Möglicherweise müssen Sie eine Minute warten. Alternativ können Sie die Logs in Echtzeit auf der Seite „Worker-Pool“ in der Cloud Console ansehen.
gcloud alpha run worker-pools logs read "codelab-ollama-wp" --limit 10
Sie sollten dann Folgendes sehen:
Ollama response: {"model": "gemma3:4b", "created_at": "2025-11-06T23:48:39.572079369Z", "response": "1 + 1 = 2\n", ...
7. Glückwunsch!
Herzlichen Glückwunsch zum Abschluss des Codelabs!
Wir empfehlen, die Cloud Run-Dokumentation zu lesen.
Behandelte Themen
- Cloud Run-Worker-Pools mit einem Pub/Sub-Pull-Abo verwenden
- Ollama für die Inferenz als Cloud Run-Worker-Pool verwenden
8. Bereinigen
Damit Ihrem Google Cloud-Konto die in dieser Anleitung verwendeten Ressourcen nicht in Rechnung gestellt werden, können Sie entweder das Projekt löschen, das die Ressourcen enthält, oder das Projekt beibehalten und die einzelnen Ressourcen löschen.
Projekt löschen
Am einfachsten vermeiden Sie weitere Kosten durch Löschen des für die Anleitung erstellten Projekts.
So löschen Sie das Projekt:
- Wechseln Sie in der Google Cloud Console zur Seite Ressourcen verwalten.
- Wählen Sie in der Projektliste das Projekt aus, das Sie löschen möchten, und klicken Sie auf Löschen.
- Geben Sie im Dialogfeld die Projekt-ID ein und klicken Sie auf Beenden, um das Projekt zu löschen.
Einzelne Ressourcen löschen
Führen Sie die folgenden Befehle aus, um die einzelnen Ressourcen zu löschen:
- Löschen Sie den Cloud Run-Worker-Pool:
gcloud beta run worker-pools delete codelab-ollama-wp --region ${REGION}
- Löschen Sie den GCS-Bucket:
gsutil -m rm -r gs://${BUCKET_NAME}
- Löschen Sie das Pub/Sub-Abo und -Thema:
gcloud pubsub subscriptions delete ${SUBSCRIPTION_NAME}
gcloud pubsub topics delete ${TOPIC_NAME}
- Löschen Sie das Artifact Registry-Repository:
gcloud artifacts repositories delete ${AR_REPO_NAME} --location=${REGION} --quiet
- Löschen Sie das Dienstkonto:
gcloud iam service-accounts delete ${SERVICE_ACCOUNT_EMAIL} --quiet
Lokale Dateien bereinigen
So bereinigen Sie lokale Dateien:
- Lokalen Ollama-Dienst beenden:Wenn Sie Ollama mit
ollama serve &gestartet haben, können Sie den Dienst beenden, indem Sie die Prozess-ID (PID) ermitteln und dann den Befehlkillverwenden.# Find the process ID of the Ollama server pgrep ollama # Replace <PID> with the actual process ID obtained from the previous command kill <PID> - Löschen Sie die heruntergeladenen Modelle:
rm -rf ~/.ollama/models
- Ollama deinstallieren:
Folgen Sie der Anleitung auf der Ollama-Website, um Ollama von Ihrem lokalen Computer zu deinstallieren.