פיתוח עד הפקה בשלושה שלבים פשוטים עם Cloud Run

1. מבוא

למה כל כך קשה לנהל אפליקציות?

סיבה חשובה אחת היא שהרבה מפתחים צריכים להיות מנהלי מערכת במשרה חלקית. נבחן את רשימת החששות (חלקית) הבאה כדי לפתח, לפרוס ולנהל אפליקציית אינטרנט מודרנית ברמת הייצור :

4d018476b4a73b47.png

אני לא יודע מה איתך, אבל אלה כל הדברים שאני לא רוצה לדאוג! מה שאני ממש רוצה לחשוב עליו הוא הלוגיקה של הבקשה שלי:

6dfd143d20e5548b.png

זהו, בקיצור, Cloud Run מאפשר לכם להתמקד באפליקציה, ולהשאיר את כל פעולות הניהול והתחזוקה לאדם אחר, כלומר Google, שהשקיע מיליוני שעות בשיפור המיומנויות שלו בתחום הזה.

בנוסף לאתגרים הניהוליים שצוינו למעלה, צריך גם להתמודד עם:

  • תלות – הסביבה שבה האפליקציה פועלת צריכה להתאים במדויק לסביבה שבה היא נבדקה, במידת האפשר. יכולות להיות לכך כמה מאפיינים, כולל מערכת ההפעלה, ספריות תמיכה, תרגום שפה או מהדר, הגדרת החומרה וגורמים רבים אחרים.
  • הפצה – כדי לעבור מהטמעה מקומית של אפליקציה לאפליקציה שמשותפת באופן נרחב באינטרנט, לעיתים קרובות נדרשים שינוי בסביבת זמן הריצה, קפיצה קוונטית במורכבות ועקומה של למידה תלולה.

שירות Cloud Run מטפל בבעיות האלה ובהרבה בעיות אחרות. במקום להסתמך על המילה שלי, בואו ניצור אפליקציה ביחד ונראה עד כמה קל לעבור מסביבת פיתוח מקומית לאפליקציית ענן ברמת הייצור בכמה שלבים פשוטים.

מה עושים...

  • אתם תלמדו לפתח אפליקציית אינטרנט פשוטה ותוודאו שהיא פועלת כצפוי בסביבת הפיתוח שלכם.
  • לאחר מכן תועברו לגרסה בקונטיינרים של אותה האפליקציה. לאורך הדרך, תלמדו על המשמעות של יצירת קונטיינרים ולמה היא כל כך שימושית.
  • בשלב האחרון, תפרסו את האפליקציה בענן, ותוכלו לראות עד כמה קל לנהל את שירות Cloud Run באמצעות שורת הפקודה ומסוף Google Cloud.

מה תלמדו...

  • איך יוצרים אפליקציית שרת אינטרנט פשוטה ב-Python
  • איך לארוז את האפליקציה לקונטיינר של Docker שרץ בכל מקום
  • איך לפרוס את האפליקציה בענן כדי שכולם יוכלו לנסות את היצירה החדשה שיצרתם
  • איך אפשר לפשט את השלבים שלמעלה באמצעות Buildpacks
  • איך משתמשים בכלי שורת הפקודה של Google Cloud ובממשק המשתמש של Cloud Console באינטרנט

מה צריך...

  • בדפדפן אינטרנט
  • חשבון Google

שיעור ה-Lab הזה מיועד למפתחים בכל הרמות, כולל למתחילים. אתם משתמשים ב-Python, אבל לא צריך להכיר תכנות Python כדי להבין מה קורה, כי נסביר את כל הקוד שבו אתם משתמשים.

2. להגדרה

5110b5081a1e1c49.png

בחלק הזה נסביר את כל מה שצריך לעשות כדי להתחיל את שיעור ה-Lab הזה.

הגדרת סביבה בקצב עצמאי

  1. נכנסים למסוף Cloud ויוצרים פרויקט חדש או עושים שימוש חוזר בפרויקט קיים. (אם אין לכם עדיין חשבון Gmail או חשבון Google Workspace, עליכם ליצור חשבון).

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

חשוב לזכור את מזהה הפרויקט, שם ייחודי לכל הפרויקטים ב-Google Cloud (השם שלמעלה כבר תפוס ולא מתאים לכם, סליחה). בהמשך ב-Codelab הזה, היא תיקרא PROJECT_ID.

  1. בשלב הבא צריך להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבים של Google Cloud.

מעבר ב-Codelab הזה לא אמור לעלות הרבה, אם בכלל. חשוב לבצע את כל ההוראות בקטע 'ניקוי' שמסביר איך להשבית משאבים כדי שלא תצברו חיובים מעבר למדריך הזה. משתמשים חדשים ב-Google Cloud זכאים להצטרף לתוכנית תקופת ניסיון בחינם בשווי 1,200 ש"ח.

הפעלת Cloud Shell

בשיעור ה-Lab הזה תלמדו במסגרת סשן של Cloud Shell, שהוא תרגום פקודות שמתארח במכונה וירטואלית שפועלת בענן של Google. באותה מידה תוכלו להריץ את הקטע הזה באופן מקומי במחשב שלכם, אבל השימוש ב-Cloud Shell מאפשר לכולם ליהנות מחוויה שניתן לשחזר בסביבה עקבית. אחרי שיעור ה-Lab, אתם יכולים לנסות שוב את הקטע הזה במחשב.

704a7b7491bd157.png

הפעלת Cloud Shell

  1. במסוף Cloud, לוחצים על Activate Cloud Shell 4292cbf4971c9786.png.

bce75f34b2c53987.png

אם לא הפעלתם את Cloud Shell בעבר, יוצג לכם מסך ביניים (בחלק הנגלל) שמתאר מהו. במקרה כזה, לוחצים על המשך (וזה לא יקרה שוב). כך נראה המסך החד-פעמי:

70f315d7b402b476.png

ההקצאה וההתחברות ל-Cloud Shell נמשכת כמה דקות.

fbe3a0674c982259.png

במכונה הווירטואלית הזו משולבת כל כלי הפיתוח שדרושים לכם. יש בה ספריית בית בנפח מתמיד של 5GB והיא פועלת ב-Google Cloud, מה שמשפר משמעותית את ביצועי הרשת והאימות. אם לא את כולן, ניתן לבצע חלק גדול מהעבודה ב-Codelab הזה באמצעות דפדפן או Chromebook.

אחרי ההתחברות ל-Cloud Shell, אתם אמורים לראות שכבר בוצע אימות ושהפרויקט כבר מוגדר למזהה הפרויקט שלכם.

  1. מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שהאימות בוצע:
gcloud auth list

פלט הפקודה

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שהפקודה ב-gcloud יודעת על הפרויקט שלכם:
gcloud config list project

פלט הפקודה

[core]
project = <PROJECT_ID>

אם היא לא נמצאת שם, תוכלו להגדיר אותה באמצעות הפקודה הבאה:

gcloud config set project <PROJECT_ID>

פלט הפקודה

Updated property [core/project].

מגדירים כמה משתני סביבה בטרמינל שיקלו על החיים בשלבים הבאים:

export PROJ=$GOOGLE_CLOUD_PROJECT 
export APP=hello 
export PORT=8080
export REGION="us-central1"
export TAG="gcr.io/$PROJ/$APP"

הפעלת ממשקי ה-API

בשלבים הבאים תראו איפה השירותים האלה נחוצים (ולמה), אבל בינתיים, מריצים את הפקודה הזו כדי לתת לפרויקט גישה לשירותים Cloud Build, Container Registry ו-Cloud Run:

gcloud services enable cloudbuild.googleapis.com         \
                       containerregistry.googleapis.com  \
                       run.googleapis.com          

אמורה ליצור מסר מוצלח שדומה להודעה הזו:

Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.

3. בנייה של אפליקציית אינטרנט פשוטה

eef530b56b8e93a3.png

כדי להתחיל, לוחצים על הלחצן Open Editor בחלק העליון של החלונית של Cloud Shell. כך הוא נראה:

9b81c8a37a6bcdd8.png

לאחר מכן תגיעו לסביבת IDE שדומה ל-Visual Studio Code, שבה אפשר ליצור פרויקטים, לערוך קוד מקור, להריץ תוכניות וכו'. אם המסך עמוס מדי, אפשר להרחיב או לכווץ את קו החלוקה בין המסוף לבין חלון העריכה/הסיום על ידי גרירת הסרגל האופקי בין שני האזורים האלה, שמודגש כאן:

8dea35450851af53.png

אפשר לעבור בין Editor לבין הטרמינל בלחיצה על הלחצנים Open Editor ו-Open Terminal, בהתאמה. נסו לעבור בין שתי הסביבות האלה עכשיו.

בשלב הבא יוצרים תיקייה שבה תשמרו את העבודה בשיעור ה-Lab הזה. לשם כך, בוחרים באפשרות File->New Folder (קובץ, תיקייה חדשה), מזינים hello ולוחצים על OK. כל הקבצים שתיצרו בשיעור ה-Lab הזה וכל העבודה שתבצעו ב-Cloud Shell יועברו לתיקייה הזו.

בשלב הזה יוצרים קובץ requirements.txt. הקוד הזה מורה ל-Python אילו ספריות האפליקציה תלויה. באפליקציית האינטרנט הפשוטה הזו, אתם עומדים להשתמש במודול Python פופולרי לבניית שרתי אינטרנט שנקרא Flask ו-framework של שרת אינטרנט בשם gunicorn. בחלון Cloud Editor, לוחצים על התפריט File->New File (קובץ חדש) כדי ליצור קובץ חדש. כשתתבקשו לתת שם לקובץ החדש, תצטרכו להזין requirements.txt וללחוץ על הלחצן OK. מוודאים שהקובץ החדש מסתיים בתיקיית הפרויקט hello.

מזינים את השורות הבאות בקובץ החדש כדי לציין שהאפליקציה תלויה בחבילת Flask של Python ובשרת האינטרנט gunicorn.

Flask
gunicorn

אין צורך לשמור באופן מפורש את הקובץ הזה כי Cloud Editor ישמור את השינויים באופן אוטומטי.

גרסה 1: Hello World!

באותה שיטה, יוצרים קובץ חדש נוסף בשם main.py. זה יהיה קובץ המקור הראשי (והיחיד) של האפליקציה ב-Python. שוב, מוודאים שהקובץ החדש נמצא בתיקיית הפרויקט hello.

מזינים את הקוד הבא בקובץ הזה:

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from the environment.

# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
@app.route("/", methods=["GET"])
def say_hello():
    html = "<h1>Hello world!</h1>"
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

חוזרים לטרמינל ומחליפים לתיקיית הפרויקט באמצעות הפקודה הבאה:

cd hello

מריצים את הפקודה הבאה כדי להתקין את יחסי התלות של הפרויקט:

pip3 install -r requirements.txt

עכשיו הפעילו את האפליקציה על ידי הרצת הפקודה הבאה בטרמינל:

python3 main.py

בשלב הזה, האפליקציה פועלת במכונה הווירטואלית שמיועדת לסשן של Cloud Shell. Cloud Shell כולל מנגנון לשרת proxy שמאפשר לכם לגשת לשרתי אינטרנט (כמו זה שהתחלתם כרגע) שפועלים במכונה הווירטואלית שלכם מכל מקום באינטרנט הגלובלי.

לוחצים על הלחצן web preview ואז על האפשרות Preview on Port 8080 בתפריט:

fe45e0192080efd6.png

הפעולה הזו תפתח כרטיסייה בדפדפן אינטרנט שבה האפליקציה פועלת. האפליקציה אמורה להיראות כך:

b1f06501509aefb9.png

גרסה 2: הדהוד של נתיב כתובת האתר

חוזרים ל-Cloud Editor (לוחצים על הלחצן Open Editor) ומוסיפים תמיכה בהד סיומת של כתובת URL אופציונלית. לשם כך, מעדכנים את הקובץ main.py באופן הבא:

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from environment.

# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
# If something is specified as the URL path (after the '/'), say_hello()
# responds with "Hello X", where X is the string at the end of the URL.
@app.route("/", methods=["GET"])
@app.route("/<name>", methods=["GET"])     # ← NEW
def say_hello(name="world"):               # ← MODIFIED
    html = f"<h1>Hello {name}!</h1>"       # ← MODIFIED
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

חוזרים לטרמינל (באמצעות הלחצן Open Terminal) ומזינים control-C (לוחצים לחיצה ארוכה על מקש הבקרה בזמן הקשה על C) כדי להפסיק את האפליקציה שפועלת. אחר כך מפעילים אותו מחדש באמצעות כניסה:

python3 main.py

שוב, לוחצים על הלחצן web preview ואז על האפשרות Preview on Port 8080 בתפריט כדי לפתוח כרטיסייה בדפדפן אינטרנט באפליקציה שפועלת. אתם אמורים לראות שוב את ההודעה "Hello World! " אבל עכשיו צריך להחליף את הטקסט של כתובת ה-URL שמופיע אחרי התו הלוכסן בכל מחרוזת לבחירתכם (למשל: /your-name). אם אתם רואים משהו כזה:

93b87996f88fa370.png

גרסה 3: צבעים אקראיים

עכשיו אפשר להוסיף תמיכה בצבעי רקע אקראיים על ידי חזרה אל Cloud Editor (באמצעות הלחצן Open Editor) ועדכון קובץ main.py באופן הבא:

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from the environment.

# This function decides whether foreground text should be
# displayed in black or white, to maximize fg/bg contrast.
def set_text_color(rgb):                      # ← NEW
    sum = round(                              # ← NEW
        (int(rgb[0]) * 0.299)                 # ← NEW
        + (int(rgb[1]) * 0.587)               # ← NEW
        + (int(rgb[2]) * 0.114)               # ← NEW
    )                                         # ← NEW
    return "black" if sum > 186 else "white"  # ← NEW


# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
# If something is specified as the URL path (after the '/'), say_hello()
# responds with "Hello X", where X is the string at the end of the URL.
# To verify each new invocation of these requests, the HTML document
# includes CSS styling to produce a randomly colored background.
@app.route("/", methods=["GET"])
@app.route("/<name>", methods=["GET"])
def say_hello(name="world"):
    bg = random.sample(range(1, 255), 3)                       # ← NEW
    hex = (int(bg[0]) * 256) + (int(bg[1]) * 16) + int(bg[2])  # ← NEW
    fg_color = set_text_color(bg)                              # ← NEW
    bg_color = f"#{hex:06x}"                                   # ← NEW
    style = f"color:{fg_color}; background-color:{bg_color}"   # ← NEW
    html = f'<h1 style="{style}">Hello {name}!</h1>'           # ← MODIFIED
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

חוזרים לטרמינל (באמצעות הלחצן Open Terminal) ומזינים control-C (לוחצים לחיצה ארוכה על מקש הבקרה בזמן הקשה על C) כדי להפסיק את האפליקציה שפועלת. אחר כך מפעילים אותו מחדש באמצעות כניסה:

python3 main.py

שוב, לוחצים על הלחצן web preview ואז על האפשרות Preview on Port 8080 בתפריט כדי לפתוח כרטיסייה בדפדפן אינטרנט באפליקציה שפועלת. הטקסט שנוצר אמור להופיע עם כל סיומת שצוינה או עם ברירת המחדל 'שלום עולם!' מחרוזת, מוצגת לפני רקע בצבעים אקראיים, כך:

baf8d028f15ea7f4.png

צריך לטעון מחדש את הדף כמה פעמים כדי לראות שצבע הרקע האקראי משתנה בכל פעם שאתם נכנסים לאפליקציה.

זה הכול – הכל מוכן! בשלב הבא תלמדו איך לארוז את האפליקציה לקונטיינר ולמה כדאי לעשות את זה.

4. יצירת קונטיינרים לאפליקציה

17cc234ec3325a8a.png

מהו קונטיינר?

קונטיינרים באופן כללי, וב-Docker בפרט, נותנים לנו את היכולת ליצור תיבה מודולרית שבה אפשר להריץ אפליקציה עם כל יחסי התלות בחבילה אחת. התוצאה היא קובץ אימג' בקונטיינר. בקטע הזה יוצרים קובץ אימג' בקונטיינר שבו משתמשים כדי ליצור גבולות לאפליקציה ואת כל יחסי התלות שלה.

ואם כבר מדברים על תלות, בשלב קודם הפעלת את האפליקציה בסביבת מפתחים היה צריך להריץ את pip3 install -r requirements.txt ולוודא שקובץ הדרישות.txt מכיל את כל הספריות התלויות והגרסאות התואמות. כשמשתמשים בקונטיינרים, מתקינים את הדרישות האלה כשיוצרים את קובץ האימג' בקונטיינר, כך שהצרכן של הקונטיינר לא צריך לדאוג לגבי התקנה כלשהי.

קובץ האימג' בקונטיינר הזה ישמש בתור אבן הבניין הבסיסית לפריסת האפליקציה ב-Cloud Run. מכיוון שניתן להשתמש בקונטיינרים כמעט בכל שרת וירטואלי או אמיתי, כך יש לנו אפשרות לפרוס את האפליקציה שלכם בכל מקום שתרצו, ולהעביר את האפליקציה מספק שירות אחד לאחר או מהארגון לענן.

קונטיינרים עוזרים לאפליקציות:

  • ניתנים לשחזור – הקונטיינרים עומדים בפני עצמם ומלאים
  • ניידות – קונטיינרים הם אבני בניין בכל הענפים, שמאפשרים ניידות של אפליקציות בין ספקים וסביבות

לסיכום, קונטיינרים מציעים את היכולת, סוף סוף, "לכתוב פעם אחת ולהפעיל בכל מקום". חריג אחד לכלל הזה הוא שהמאגר שנוצר מוגבל לפעול בסוג המעבד שבו יצרתם אותו, אבל יש דרכים ליצור גרסאות של קונטיינרים גם לתצורות חומרה אחרות.

מספיק לדבר – בואו ניצור מאגר! אתם עומדים להשתמש בטכנולוגיה ספציפית כדי ליצור קונטיינר בשם Docker.

ב-Cloud Editor, יוצרים קובץ חדש בשם Dockerfile. הקובץ הזה הוא תוכנית כללית ליצירת התמונה. הוא מדריך ל-Docker על סביבת ההפעלה ועל קוד המקור, איך להתקין את יחסי התלות, לבנות את האפליקציה ולהריץ את הקוד.

# Use an official lightweight Python image.
FROM python:3.9-slim

# Copy local code to the container image.
WORKDIR /app
COPY main.py .
COPY requirements.txt .

# Install dependencies into this container so there's no need to 
# install anything at container run time.
RUN pip install -r requirements.txt

# Service must listen to $PORT environment variable.
# This default value facilitates local development.
ENV PORT 8080

# Run the web service on container startup. Here you use the gunicorn
# server, with one worker process and 8 threads. For environments 
# with multiple CPU cores, increase the number of workers to match 
# the number of cores available.
CMD exec gunicorn --bind 0.0.0.0:$PORT --workers 1 --threads 8 --timeout 0 main:app

ב-Cloud Terminal, יוצרים את קובץ האימג' של הקונטיינר באמצעות Cloud Build על ידי הרצת הפקודה הבאה:

gcloud builds submit --tag $TAG

לאחר הדחיפה למרשם, תופיע הודעה SUCCESS שמכילה את שם התמונה, שאמורה להיראות בערך כך: gcr.io/<project-id>/hello. התמונה מאוחסנת עכשיו ב-Container Registry ואפשר להשתמש בה שוב בכל זמן ובכל מקום.

כדי להציג את רשימת כל קובצי האימג' של הקונטיינרים שמשויכים לפרויקט הנוכחי, אפשר להשתמש בפקודה הבאה:

gcloud container images list

עכשיו מריצים את האפליקציה ובודקים אותה באופן מקומי מ-Cloud Shell באמצעות פקודות docker האלה:

docker run -p $PORT:$PORT -e PORT=$PORT $TAG

האפשרות -p $PORT:$PORT מנחה את Docker למפות את היציאה החיצונית $PORT (שמוגדרת ל-8080 למעלה) בסביבת המארח לאותו מספר יציאה בקונטיינר שפועל. הפעולה הזו הופכת את החיים לקלים יותר כי קוד השרת שכותבים ומספר היציאה החיצונית שאליהם מתחברים בזמן הבדיקה של האפליקציה יהיו זהים (8080), אבל אפשר להשתמש באותה מידה באפשרות -p כדי למפות כל יציאה חיצונית שרירותית במארח לכל יציאה פנימית רצויה בתוך הקונטיינר.

האפשרות -e PORT=$PORT מנחה את Docker להפוך את משתנה הסביבה $PORT (מוגדר ל-8080 למעלה) כזמין לאפליקציה שפועלת בתוך הקונטיינר.

עכשיו אתם מוכנים לבדוק את האפליקציה שלכם על ידי הפניית דפדפן אינטרנט אל קוד Python שפועל בקונטיינר. בחלון Cloud Shell, לוחצים על Web Preview. ובוחרים באפשרות 'תצוגה מקדימה ביציאה 8080', כפי שעשיתם בשלב הקודם.

התוצאה אמורה להיראות מוכרת – הטקסט שנוצר מופיע לפני רקע בצבעים אקראיים, בדיוק כמו שעשיתם כשהפעלתם את האפליקציה ישירות בטרמינל של Cloud Shell. צריך לטעון מחדש את הדף כמה פעמים כדי לראות שצבע הרקע האקראי משתנה בכל פעם שאתם נכנסים לאפליקציה.

מעולה! עכשיו אתם מריצים גרסה של האפליקציה שלכם בקונטיינרים. בקטע הבא, בלי לגעת בשורת קוד, אפשר להפוך את קובץ האימג' בקונטיינר לאפליקציית אינטרנט באיכות ייצור.

5. לענן...

1b0665d94750ded6.gif

עכשיו, אחרי שיצרתם את האפליקציה בקונטיינרים, כדאי לשתף את הכיף הזה עם שאר העולם, ויגיע הזמן לפרוס אותה בענן. אבל אינך רק רוצה לשתף את זה, אלא גם לעשות דברים נוספים. עליך לוודא ש:

  • פועל באופן מהימן – מקבלים אוטומטית הגנה מפני כשלים במקרה שמחשב מריץ את האפליקציה
  • מותאמות לעומס (scaling) באופן אוטומטי – האפליקציה מתעדכנת בנפחים גדולים של תנועה ותצמצם את טביעת הרגל הפחמנית באופן אוטומטי כשהיא לא בשימוש
  • יפחית את העלויות שלך, בכך שלא תחייב אותך עבור משאבים שבהם אינך משתמש – תחויב רק עבור המשאבים שנעשה בהם שימוש בזמן התגובה לתנועה
  • ניתן לגשת אליו באמצעות שם דומיין מותאם אישית - יש לך גישה לפתרון בלחיצה אחת להקצאת שם דומיין מותאם אישית לשירות שלך
  • מציע זמן תגובה מצוין – הפעלות במצב התחלתי (cold start) מגיבות באופן סביר, אבל אפשר לכוונן זאת באמצעות ציון הגדרה של מופע מינימלי.
  • תמיכה בהצפנה מקצה לקצה באמצעות אבטחת אינטרנט סטנדרטית של SSL או TLS. כשפורסים שירות, מקבלים הצפנת אינטרנט סטנדרטית ואת האישורים הנדרשים התואמים, בחינם ובאופן אוטומטי.

פריסת האפליקציה ב-Google Cloud Run תעניק לכם את כל מה שהוזכר קודם ועוד.

פריסת האפליקציה ב-Cloud Run

קודם כל, צריך לשנות את האפליקציה כדי שאפשר יהיה להבדיל בין הגרסה החדשה לגרסה הישנה. כדי לעשות את זה, צריך לשנות את הקובץ main.py, כך שהודעת ברירת המחדל תשתנה מ"שלום עולם!" ל"שלום מ-Cloud Run!". במילים אחרות, צריך לשנות את השורה הזו ב-main.py מהשורה הזו:

def say_hello(name="world"):

לזה:

def say_hello(name="from Cloud Run"):

Cloud Run הוא אזור אזורי. כלומר, התשתית שמפעילה את שירותי Cloud Run ממוקמת באזור מסוים ומנוהלת על ידי Google כך שהיא תהיה זמינה באופן יתירות בכל התחומים (zones) באותו אזור. בקטע "הגדרה" שלמעלה, הגדרתם אזור ברירת מחדל באמצעות משתנה הסביבה REGION.

יוצרים מחדש את קובץ האימג' בקונטיינר ופורסים את האפליקציה בקונטיינרים ב-Cloud Run באמצעות הפקודה הבאה:

gcloud builds submit --tag $TAG
gcloud run deploy "$APP"   \
  --image "$TAG"           \
  --platform "managed"     \
  --region "$REGION"       \
  --allow-unauthenticated
  • אפשר גם להגדיר אזור ברירת מחדל באמצעות gcloud config set run/region $REGION.
  • האפשרות --allow-unauthenticated הופכת את השירות לזמין לציבור. כדי למנוע בקשות לא מאומתות, צריך להשתמש בפונקציה --no-allow-unauthenticated במקום זאת.

התמונה שמצוינת כאן היא תמונת ה-Docker שבנית בשלב האחרון. בזכות שירות Cloud Build ששמר את התמונה שנוצרה ב-Google Container Registry, שירות Cloud Run יכול למצוא אותה ולפרוס אותה בשבילכם.

ממתינים כמה דקות עד שהפריסה תושלם. לאחר הצלחה, שורת הפקודה תציג את כתובת ה-URL של השירות:

Deploying container to Cloud Run service [hello] in project [PROJECT_ID...
✓ Deploying new service... Done.                                   
  ✓ Creating Revision... Revision deployment finished. Waiting for health check...
  ✓ Routing traffic...
  ✓ Setting IAM Policy...
Done.
Service [hello] revision [hello-...] has been deployed and is serving 100 percent of traffic.
Service URL: https://hello-....a.run.app

אפשר גם לאחזר את כתובת ה-URL של השירות באמצעות הפקודה הבאה:

gcloud run services describe hello  \
  --platform managed                \
  --region $REGION                  \
  --format "value(status.url)"

זה אמור להראות משהו כמו:

https://hello-....a.run.app

הקישור הזה הוא כתובת URL ייעודית, עם אבטחת TLS, לשירות Cloud Run שלך. הקישור הזה הוא קבוע (כל עוד לא משביתים את השירות) ואפשר להשתמש בו בכל מקום באינטרנט. היא לא משתמשת במנגנון שרת ה-proxy של Cloud Shell שצוין קודם, שתלוי במכונה וירטואלית זמנית.

לוחצים על Service URL המודגש כדי לפתוח כרטיסייה בדפדפן אינטרנט לאפליקציה שפועלת. בתוצאה אמורה להופיע ההודעה "Hello from Cloud Run! " הודעה על רקע רקע בצבעים אקראיים.

מעולה! האפליקציה שלך פועלת עכשיו בענן של Google. האפליקציה שלכם זמינה לכולם, עם הצפנת TLS (HTTPS) והתאמה אוטומטית לעומס (auto-scaling) לרמות תנועה מדהימות.

אבל נראה לי שהתהליך הזה יכול להיות אפילו קל יותר...

6. יצירה אוטומטית של הקונטיינר

הכול די מגניב, אבל מה עושים אם לא רוצים אפילו לחשוב על קובצי Docker ועל קונטיינרים. מה אם, כמו רוב המפתחים, אני רוצה להתמקד בכתיבת קוד האפליקציה שלי ולאפשר למישהו אחר לדאוג ליצירת קונטיינרים שלו. יש לכם מזל כי Cloud Run תומך בתקן קוד פתוח בשם Buildpacks, שמתקיים בדיוק מהסיבה הזו: כדי להפוך את תהליך הייצור של קונטיינר מאוסף של קובצי מקור לאוטומטי.

שימו לב: יש מקרים שבהם המפתחים עשויים להעדיף להשתמש בקובץ Docker מפורש, לדוגמה, אם הם רוצים רמה גבוהה של התאמה אישית באופן הפיתוח של הקונטיינר. אבל במקרים נפוצים כמו התרגיל הזה, ה-buildpacks פועלים יפה ואין צורך ליצור Dockerfile באופן ידני. נשנה את הקוד כדי להשתמש ב-buildpacks.

קודם כל, צריך לשנות את האפליקציה כדי שאפשר יהיה להבדיל בין הגרסה החדשה לגרסה הישנה. כדי לעשות את זה, צריך לשנות את הקובץ main.py כך שהודעת ברירת המחדל תשתנה מ-"Hello from Cloud Run! " ל"שלום מ-Cloud Run with Buildpacks!". במילים אחרות, צריך לשנות את השורה הזו ב-main.py מהשורה הזו:

def say_hello(name="from Cloud Run"):

לזה:

def say_hello(name="from Cloud Run with Buildpacks"):

עכשיו אפשר ליצור קובץ חדש בשם Procfile כדי לנצל את ה-buildpacks. יוצרים את הקובץ ב-Cloud Editor ומוסיפים את שורת הטקסט הבאה:

web: python3 main.py

הפעולה הזו מנחה את מערכת ה-buildback להריץ את האפליקציה בקונטיינר שנוצר באופן אוטומטי. עם אותה הוראה, כבר לא צריך קובץ Docker. כדי לבדוק זאת, מוחקים את קובץ ה-Docker ומריצים את הפקודה הבאה בטרמינל של Cloud Shell:

gcloud beta run deploy "$APP"  \
    --source .                 \
    --platform "managed"       \
    --region "$REGION"         \
    --allow-unauthenticated

הפעולה הזו דומה לפקודה שהרצתם כדי לפרוס את האפליקציה בשלב האחרון, אבל הפעם החלפתם את האפשרות --image באפשרות --source .. הפקודה הזו מנחה את הפקודה gcloud שאתם רוצים שתשתמש ב-buildpacks כדי ליצור קובץ אימג' בקונטיינר, על סמך קובצי המקור שהוא מוצא בספרייה הנוכחית (ה-dot ב---source . הוא קיצור של הספרייה הנוכחית). מכיוון שהשירות מטפל באופן מרומז בקובץ האימג' של הקונטיינר, אין צורך לציין תמונה בפקודה gcloud הזו.

שוב, מוודאים שהפריסה הזו פועלת על ידי לחיצה על Service URL המודגש כדי לפתוח כרטיסייה בדפדפן אינטרנט לאפליקציה שפועלת. לאחר מכן צריך לוודא שבשירות מוצגת ההודעה "Hello from Cloud Run with Buildpacks!" לפני רקע שנצבע באופן אקראי.

שימו לב שהשימוש ב-buildpacks כדי לייצר את ה-Dockerfile מאפשר לצמצם את שלושת השלבים הקלים לשניים:

  1. יוצרים אפליקציה בסביבת הפיתוח.
  2. פורסים את אותו הקוד המדויק בענן באמצעות פקודה אחת.

7. האם צריך להשתמש בשורת הפקודה?

לא. כמו כמעט כל שירות של Google Cloud, יש שלוש דרכים לבצע אינטראקציה עם Cloud Run:

  • כלי שורת הפקודה של Google Cloud, שראיתם עכשיו.
  • ממשק משתמש עשיר באינטרנט, דרך מסוף Cloud, שתומך בסגנון אינטואיטיבי של אינטראקציה עם הצבעה ולחיצה.
  • באופן פרוגרמטי, שימוש בספריות הלקוח של Google שזמינות בשפות פופולריות רבות, כולל Java, C#, Python, Go, JavaScript, Ruby, C/C++ ואחרות.

עכשיו נפרוס מופע נוסף של אפליקציית Cloud Run באמצעות ממשק המשתמש של המסוף. נכנסים לדף הנחיתה של Cloud Run Service בתפריט הימני העליון:

e2b4983b38c81796.png

לאחר מכן אמור להופיע סיכום של שירותי Cloud Run, כמו:

b335e7bf0a3af845.png

לוחצים על "Create Service" (יצירת שירות). קישור להתחלת תהליך הפריסה:

51f61a8ddc7a4c0b.png

להזין שוב את המילה 'שלום' בתור שם השירות, לוקחים את ברירת המחדל של הפלטפורמה והאזור לפריסה ולוחצים על 'הבא'.

8a17baa45336c4c9.png

מזינים את כתובת ה-URL הזו לקובץ האימג' של הקונטיינר: gcr.io/cloudrun/hello, שהוא מאגר שנוצר על ידי Google למטרות בדיקה, ולוחצים על 'הגדרות מתקדמות'. כדי לראות חלק מהגדרות התצורה הרבות שזמינות לך. כדי לציין רק כמה דוגמאות, אפשר להתאים אישית:

  • מספר היציאה ונקודת הכניסה לקונטיינר (השינוי יבטל את נקודת הכניסה שצוינה כשיוצרים את הקונטיינר)
  • חומרה: זיכרון ומספר המעבדים (CPU)
  • התאמה לעומס (scaling): מכונות מינימליות ומקסימליות
  • משתני סביבה
  • אחרים: הגדרת זמן קצוב לתפוגה של בקשה, מספר הבקשות המקסימלי לכל מאגר, HTTP/2

לוחצים על 'הבא'. כדי להתקדם בתיבת הדו-שיח. בתיבת הדו-שיח הבאה ניתן לציין איך השירות יופעל. בשדה 'Ingress', בוחרים באפשרות 'אישור כל התנועה', ובאפשרות 'אימות' בוחרים באפשרות 'הרשאה לתנועה לא מאומתת'.

e78281d1cff3418.png

אלה ההגדרות הליברליות ביותר: הן מאפשרות לכל אחד לגשת לאפליקציית Cloud Run מכל מקום באינטרנט הציבורי, בלי לציין פרטי כניסה לאימות. יכול להיות שתרצו להגדיר הגדרות מגבילות יותר לאפליקציה, אבל חשוב לפשט את התרגיל הזה.

עכשיו עליכם ללחוץ על הלחצן Create כדי ליצור את השירות Cloud Run. לאחר מספר שניות, השירות החדש אמור להופיע ברשימת הסיכום של שירותי Cloud Run. שורת הסיכום מציגה את הפריסה האחרונה (תאריך/שעה ומי האנשים) יחד עם כמה הגדרות מפתח. אפשר ללחוץ על הקישור של שם השירות כדי להציג פירוט על השירות החדש.

כדי לאמת את השירות, צריך ללחוץ על כתובת ה-URL שמופיעה בחלק העליון של דף הסיכום, כמו בדוגמה הבאה:

6c35cf0636dddc51.png

אתם אמורים לראות משהו כזה:

3ba6ab4fe0da1f84.png

עכשיו, לאחר שפרסתם שירות חדש ב-Cloud Run, צריך לבחור בכרטיסייה REVISIONS כדי לראות דרכים לניהול מספר פריסות.

2351ee7ec4a356f0.png

כדי לפרוס גרסאות קודמות ישירות מהמסוף, אפשר ללחוץ על הלחצן EDIT & DEPLOY NEW REVISION, כפי שמודגש בצילום המסך לדוגמה:

a599fa88d00d6776.png

יש ללחוץ על הלחצן הזה כדי ליצור גרסה חדשה. ליד כתובת ה-URL של מאגר התגים, לוחצים על הלחצן SELECT כמו שמוצג בהמשך:

5fd1b1f8e1f11d40.png

בתיבת הדו-שיח שמופיעה, מאתרים את אפליקציית האינטרנט הפשוטה שפרסתם מ-Cloud Build באמצעות Buildpacks קודם לכן ולוחצים על 'בחירה'. הקפידו לבחור את קובץ האימג' של הקונטיינר מתחת

gcr.io/<project>/cloud-run-source-deploy

folder , כך:

8a756c6157face3a.png

לאחר הבחירה, גוללים לחלק התחתון ולוחצים על הלחצן DEPLOY. פרסתם גרסה חדשה של האפליקציה. כדי לאמת זאת, ניתן לעבור שוב לכתובת ה-URL של השירות ולוודא שעכשיו מופיע הטקסט הססגוני 'שלום מ-Cloud Run with Buildpacks'. בדפדפן.

כפי שניתן לראות, כרטיסיית התיקונים מספקת סיכום של כל גרסה שפרסתם, ועכשיו אתם אמורים לראות שתי גרסאות קודמות לשירות הזה. כדי לבחור גרסה קודמת כלשהי על ידי לחיצה על לחצן הבחירה שמימין לשם הגרסה, תראו סיכום של פרטי הגרסה בצד ימין של המסך. על ידי לחיצה על הלחצנים האלה, תוכלו לראות ששתי הגרסאות הקודמות נגזרות משתי תמונות שונות של קונטיינר.

הלחצן MANAGE TRAFFIC מאפשר לשנות את ההתפלגות של הבקשות הנכנסות שנשלחות לגרסה קודמת נתונה. היכולת הזו לכוונן בצורה עדינה את כמות התנועה שנשלחת לגרסה קודמת מסוימת מאפשרת להשתמש בכמה תרחישים חשובים לדוגמה:

  • בדיקת גרסה חדשה של האפליקציה עם חלק קטן מתנועת הגולשים הנכנסת
  • החזרת התנועה מגרסה בעייתית לגרסה קודמת
  • בדיקת A/B

הלחצן של MANAGE TRAFFIC נמצא כאן:

519d3c22ae028287.png

הגדר חלוקת תנועה של 50/50 בין שתי הגרסאות הקודמות שלך על ידי ציון חלוקת תנועה של 50/50 באופן הבא:

8c37d4f115d9ded4.png

עכשיו, לחצו על הלחצן 'שמירה' ובדקו את חלוקת ה-50/50 על ידי ביקור בכתובת ה-URL של השירות שוב ושוב. לאחר מכן בדקו שבממוצע, מחצית מהבקשות נשלחות על ידי הגרסה הנוכחית ('שלום מ-Cloud Run with Buildpacks!') וחצי מוצגות בגרסה הקודמת ('זה פועל!').

כרטיסיות אחרות בדף פרטי השירות מציעות את היכולת לעקוב אחר ביצועים, תנועה ויומנים, שמספקים תובנות חשובות לגבי רמת הקושי של השירות ומידת היעילות שלו. אפשר גם לשפר את הגישה לשירות דרך 'הרשאות' . כדאי להקדיש כמה דקות לעיון בכרטיסיות שבדף הזה כדי להכיר את היכולות שזמינות כאן.

ממשק פרוגרמטי

כפי שצוין קודם, יש לכם גם אפשרות ליצור, לפרוס ולנהל את שירותי Cloud Run באופן פרוגרמטי. במשימות ידניות, האפשרות הזו מתקדמת יותר משורת הפקודה או ממסוף האינטרנט, אבל זו בהחלט הדרך לאוטומציה של שירותי Cloud Run. אפשר להשתמש בספריות הלקוח של Google בכמה שפות תכנות פופולריות.

8. בדיקת האפליקציה

198ada162d1f0bf1.png

בשלב האחרון הזה, אתם עומדים להריץ בדיקה של עומס מלאכותי כדי לחץ על האפליקציה שלכם ולראות איך היא מתעדכנת בהתאם לביקוש הגדל. אתם עומדים להשתמש בכלי שנקרא hey, שמותקן מראש ב-Cloud Shell ומאפשר לנו להריץ בדיקות עומסים ולהציג את התוצאות.

הרצת הבדיקה

ב-Cloud Shell Terminal, מריצים את הפקודה הבאה כדי להריץ בדיקת עומס:

hey -q 1000 -c 200 -z 30s https://hello-...run.app

הארגומנטים של הפקודה מפורשים באופן הבא:

  • -q 1000 – להעלות את העומס בערך ב-1,000 בקשות לשנייה
  • -c 200 – הקצאת 200 עובדים במקביל
  • -z 30s – צריך להריץ בדיקת טעינה במשך 30 שניות
  • חשוב להשתמש בכתובת ה-URL של השירות כארגומנט האחרון בשורת הפקודה הזו

תוצאות הבדיקה אמורות להיראות כך:

 Summary:
 Total:        30.2767 secs
 Slowest:      3.3633 secs
 Fastest:      0.1071 secs
 Average:      0.1828 secs
 Requests/sec: 1087.2387
 Total data:   3028456 bytes
 Size/request: 92 bytes

Response time histogram:
 0.107 [1]     |
 0.433 [31346] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
 0.758 [1472]  |■■
 1.084 [82]    |
 1.410 [4]     |
...

Latency distribution:
...
 50% in 0.1528 secs
 75% in 0.1949 secs
 90% in 0.2442 secs
 95% in 0.4052 secs
 99% in 0.7062 secs

Details (average, fastest, slowest):
...
 req write:    0.0000 secs, 0.0000 secs, 0.0232 secs
 resp wait:    0.1824 secs, 0.1070 secs, 3.2953 secs
 resp read:    0.0000 secs, 0.0000 secs, 0.0010 secs
Status code distribution:
 [200] 32918 responses

הסיכום הזה מציין כמה פרטים מעניינים:

  • 32,918 בקשות נשלחו במהירות של 1,000 לשנייה בערך למשך 30 שניות.
  • לא היו שגיאות (רק 200 תגובות HTTP).
  • זמן האחזור הממוצע היה 180 אלפיות השנייה.
  • זמן האחזור המינימלי היה 107 אלפיות השנייה, והמקרה הגרוע ביותר היה 3.3 שנ'
  • זמן האחזור באחוזון ה-90 היה 244 אלפיות השנייה.

אם תבדקו את הכרטיסייה METRICS במסוף Cloud Run, תוכלו לראות את הצד של השרת בסיפור הביצועים:

e635c6831c468dd3.png

9. ניקוי

למרות ש-Cloud Run לא גובה תשלום כשהשירות לא בשימוש, יכול להיות שעדיין תחויבו על אחסון קובץ האימג' של הקונטיינר שנוצר.

תוכלו למחוק את פרויקט GCP כדי להימנע מחיובים, שיגרמו להפסקת החיוב של כל המשאבים באותו פרויקט, או פשוט למחוק את קובץ האימג' בקונטיינר באמצעות הפקודה הבאה:

gcloud container images delete $TAG

כדי למחוק את שירותי Cloud Run, משתמשים בפקודות הבאות:

gcloud run services delete hello --platform managed --region $REGION --quiet
gcloud run services delete hello-again --platform managed --region $REGION --quiet

10. עשית את זה!

9a31f4fdbbf1ddcb.png

כל הכבוד – פיתחתם ופרסתם בהצלחה אפליקציית Cloud Run בסביבת הייצור. לאורך הדרך, למדתם על קונטיינרים ואיך ליצור קונטיינר משלכם. כמו כן, ראיתם כמה קל לפרוס את האפליקציה שלכם באמצעות Cloud Run, באמצעות כלי שורת הפקודה gcloud וגם Cloud Console. עכשיו יודעים איך לשתף את היצירות המבריקות שלך עם העולם כולו!

אני רוצה להשאיר אותך עם שאלה חשובה אחת:

לאחר שהפעלתם את האפליקציה בסביבת הפיתוח, כמה שורות קוד צריך לשנות כדי לפרוס אותה בענן, עם כל המאפיינים ברמת הייצור שמוצעים על ידי Cloud Run?

התשובה היא כמובן אפס. :)

Codelabs שכדאי לבדוק...

עוד פיצ'רים מעניינים שכדאי לבדוק...

מסמכי עזר...

11. קריאה לפעולה

הלוגו של Google Cloud

אם נהניתם מה-Codelab הזה ויש סיכוי גבוה שתקדישו יותר זמן להתנסות ב-Google Cloud, כדאי לכם להצטרף ל-Google Cloud Innovators כבר היום.

לוגו של תג חבר/ה כללי של Innovators

שירות Google Cloud Innovators זמין בחינם וכולל:

  • דיונים, AMA ומפגשי מפת דרכים בשידור חי כדי ללמוד מה מה שחדש ישירות מהגוגלרים
  • החדשות האחרונות על Google Cloud ישירות לתיבת הדואר הנכנס
  • תג דיגיטלי ורקע של שיחת ועידה בווידאו
  • 500 קרדיטים של שיעורי Lab ולמידה ב-Skills Boost

אפשר ללחוץ כאן כדי להירשם.