1. מבוא
סקירה כללית
ב-Codelab הזה תלמדו איך ליצור צינור עיבוד נתונים אסינכרוני מבוסס-אירועים של עיבוד באמצעות AI. תפרסו מודל קוד פתוח באמצעות Ollama במאגר עובדים של Cloud Run. מאגר העובדים שולף הודעות מנושא Pub/Sub ומעבד אותן באמצעות מודל gemma3:4b.
מה תלמדו
- איך משתמשים במאגרי worker עם מינוי שליפה של Pub/Sub
- איך משתמשים ב-Ollama כדי לבצע הסקה כמאגר עובדים
2. לפני שמתחילים
הפעלת ממשקי ה-API
לפני שמתחילים להשתמש ב-codelab הזה, מפעילים את ממשקי ה-API הבאים באמצעות הפקודה:
gcloud services enable run.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
pubsub.googleapis.com \
storage.googleapis.com
3. הגדרה ודרישות
כדי להגדיר את המשאבים הנדרשים, פועלים לפי השלבים הבאים:
- מגדירים את משתני הסביבה של ה-Codelab הזה:
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
- יצירת חשבון שירות למאגר העובדים
gcloud iam service-accounts create ${SERVICE_ACCOUNT_NAME} \
--display-name="Ollama Worker Service Account"
- הענקת גישה לחשבון השירות ל-Pub/Sub
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:${SERVICE_ACCOUNT_EMAIL}" \
--role="roles/pubsub.subscriber"
- יצירת מאגר AR לתמונה של מאגר העובדים
gcloud artifacts repositories create ${AR_REPO_NAME} \
--repository-format=docker \
--location=${REGION}
- יצירת נושא ומינוי ב-PubSub
gcloud pubsub topics create $TOPIC_NAME
gcloud pubsub subscriptions create $SUBSCRIPTION_NAME --topic $TOPIC_NAME
4. הורדה ואירוח של המודל ב-GCS
במקום לשלוף את המודל ישירות בתוך הקונטיינר במהלך תהליך build, מה שעלול להיות איטי ולא יעיל, נשלוף את המודל למכונה מקומית באמצעות Ollama CLI ואז נעלה את קובצי המודל לקטגוריית GCS. לאחר מכן, מאגר העובדים יטען את הקטגוריה הזו כדי לגשת למודל.
- מתקינים את Ollama במחשב המקומי:
מריצים את הפקודה הבאה כדי להתקין את Ollama ב-Linux. למערכות הפעלה אחרות, אפשר לעיין באתר Ollama.
curl -fsSL https://ollama.com/install.sh | sh
- מפעילים את שירות Ollama ומורידים את המודל:
קודם כול, מפעילים את שירות Ollama ברקע.
ollama serve &
ollama pull gemma3:4b
- יצירת קטגוריית GCS:
יוצרים את קטגוריית GCS באמצעות משתנה הסביבה BUCKET_NAME שהגדרתם קודם.
gsutil mb gs://${BUCKET_NAME}
- מעלים את קובצי המודל לקטגוריה של GCS:
Ollama מאחסן קבצים של מודלים בספרייה ~/.ollama/models. מעלים את התוכן של הספרייה הזו לקטגוריית GCS. כל המודלים שהורדתם יועתקו.
gsutil -m cp -r ~/.ollama/models/* gs://${BUCKET_NAME}/
- הענקת גישה לחשבון השירות לקטגוריה של Cloud Storage
gcloud storage buckets add-iam-policy-binding gs://${BUCKET_NAME} \
--member=serviceAccount:${SERVICE_ACCOUNT_EMAIL} \
--role=roles/storage.objectViewer
5. יצירת משימה ב-Cloud Run
הג'וב ב-Cloud Run משתמש ב-2 קונטיינרים:
- ollama-coordinator – לאירוח של ollama ולהצגת מודל gemma 3 4B
- pubsub-pull-msg – לשליפה ממינוי pubsub ולהעברת ההודעה לקונטיינר ollama-coordinator
קודם יוצרים את מאגר התגים ollama-coordinator.
- יוצרים ספריית אב בשביל ה-codelab:
mkdir codelab-ollama-wp
cd codelab-ollama-wp
- יוצרים ספרייה בשביל מאגר ollama-coordinator
mkdir ollama-coordinator
cd ollama-coordinator
- יוצרים קובץ
Dockerfileעם התוכן הבא
# 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
gcloud builds submit --tag ${REGION}-docker.pkg.dev/${PROJECT_ID}/${AR_REPO_NAME}/${OLLAMA_IMAGE_NAME} --timeout=20m
בשלב הבא, יוצרים את מאגר התגים pubsub-pull-msg.
- יצירת ספרייה לקונטיינר pubsub-pull-msg
cd ..
mkdir pubsub-pull-msg
cd pubsub-pull-msg
- צור
Dockerfile
# 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"]
- יוצרים קובץ
requirements.txtעם התוכן הבא
google-cloud-pubsub
requests
- יוצרים קובץ
main.pyעם התוכן הבא
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()
- עכשיו בונים את הקונטיינר pubsub-pull-msg
gcloud builds submit --tag ${REGION}-docker.pkg.dev/${PROJECT_ID}/${AR_REPO_NAME}/${PULL_MSG_IMAGE_NAME}
6. פריסה והפעלה של המשימה
בשלב הזה תיצרו את משימת Cloud Run על ידי פריסת קובץ YAML.
עוברים לתיקיית הבסיס כדי ליצור את קובץ ה-YAML.
cd ..
- יוצרים קובץ
worker-pool.template.yamlעם התוכן הבא
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
לאחר מכן, מגדירים את כתובות ה-URL המלאות של התמונות ומשתמשים ב-sed כדי להחליף את המשתנים בקובץ התבנית, וכך ליצור את worker-pool.yaml הסופי.
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
עכשיו אפשר לפרוס
gcloud beta run worker-pools replace worker-pool.yaml
בדיקה
gcloud pubsub topics publish ${TOPIC_NAME} --message="What is 1 + 1?"
ואז צופים ביומנים. יכול להיות שתצטרכו לחכות דקה, או שתוכלו לעבור אל דף מאגר העובדים במסוף Cloud ולצפות ביומנים בזמן אמת.
gcloud alpha run worker-pools logs read "codelab-ollama-wp" --limit 10
אמור להופיע משהו כמו
Ollama response: {"model": "gemma3:4b", "created_at": "2025-11-06T23:48:39.572079369Z", "response": "1 + 1 = 2\n", ...
7. מעולה!
כל הכבוד, סיימתם את ה-Codelab!
מומלץ לעיין במסמכי התיעוד של Cloud Run.
מה נכלל
- איך משתמשים במאגרי עובדים של Cloud Run עם מינוי Pub/Sub Pull
- איך משתמשים ב-Ollama כדי לבצע היסק כמאגר עובדים של Cloud Run
8. הסרת המשאבים
כדי להימנע מחיובים בחשבון Google Cloud בגלל השימוש במשאבים שנעשה במסגרת המדריך הזה, אפשר למחוק את הפרויקט שמכיל את המשאבים, או להשאיר את הפרויקט ולמחוק את המשאבים בנפרד.
מחיקת הפרויקט
הדרך הקלה ביותר לבטל את החיוב היא למחוק את הפרויקט שיצרתם בשביל המדריך.
כדי למחוק את הפרויקט:
- במסוף Google Cloud, עוברים לדף Manage resources.
- ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
- כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.
מחיקה של משאבים ספציפיים
כדי למחוק את המשאבים בנפרד, מריצים את הפקודות הבאות:
- מוחקים את מאגר העובדים של Cloud Run:
gcloud beta run worker-pools delete codelab-ollama-wp --region ${REGION}
- מוחקים את קטגוריית ה-GCS:
gsutil -m rm -r gs://${BUCKET_NAME}
- מחיקת המינוי והנושא ב-Pub/Sub:
gcloud pubsub subscriptions delete ${SUBSCRIPTION_NAME}
gcloud pubsub topics delete ${TOPIC_NAME}
- מחיקת המאגר ב-Artifact Registry:
gcloud artifacts repositories delete ${AR_REPO_NAME} --location=${REGION} --quiet
- מוחקים את חשבון השירות:
gcloud iam service-accounts delete ${SERVICE_ACCOUNT_EMAIL} --quiet
ניקוי קבצים מקומיים
כדי לנקות קבצים מקומיים:
- מפסיקים את שירות Ollama המקומי:אם הפעלתם את Ollama באמצעות
ollama serve &, תוכלו להפסיק אותו על ידי איתור מזהה התהליך (PID) שלו ואז שימוש בפקודהkill.# Find the process ID of the Ollama server pgrep ollama # Replace <PID> with the actual process ID obtained from the previous command kill <PID> - מחיקת המודלים שהורדתם:
rm -rf ~/.ollama/models
- מסירים את ההתקנה של Ollama:
פועלים לפי ההוראות באתר Ollama כדי להסיר את Ollama מהמחשב המקומי.