מדריך בנושא Workflows (דור ראשון)

במדריך הזה מוסבר איך להשתמש ב-Workflows כדי לקשר בין סדרה של שירותים. אפשר ליצור אפליקציה גמישה ללא שרת (serverless) על ידי חיבור של שני שירותי HTTP ציבוריים (באמצעות פונקציות Cloud Run), API חיצוני מסוג REST ושירות Cloud Run פרטי.

מטרות

במדריך הזה נשתמש ב-Google Cloud CLI כדי ליצור תהליך עבודה יחיד, שבו נחבר שירות אחד בכל פעם:

  1. פורסים שני שירותים של פונקציות Cloud Run: הפונקציה הראשונה יוצרת מספר אקראי, ואז מעבירה את המספר הזה לפונקציה השנייה שמכפילה אותו.
  2. באמצעות Workflows, מחברים את שתי פונקציות ה-HTTP. מריצים את תהליך העבודה ומחזירים תוצאה שמועברת ל-API חיצוני.
  3. באמצעות Workflows, מחברים API חיצוני של HTTP שמחזיר את log למספר נתון. הפעלת תהליך העבודה והחזרת תוצאה שמועברת לשירות Cloud Run.
  4. פריסה של שירות Cloud Run שמאפשר גישה מאומתת בלבד. השירות מחזיר את math.floor עבור מספר נתון.
  5. באמצעות Workflows, מקשרים את שירות Cloud Run, מריצים את כל תהליך העבודה ומחזירים תוצאה סופית.

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

המחשה ויזואלית של תהליכי עבודה

עלויות

במסמך הזה משתמשים ברכיבים הבאים של Google Cloud, והשימוש בהם כרוך בתשלום:

כדי להעריך את ההוצאות בהתאם לתחזית השימוש שלכם, אתם יכולים להיעזר במחשבון העלויות.

משתמשים חדשים של Google Cloud ? יכול להיות שאתם זכאים לתקופת ניסיון בחינם.

לפני שמתחילים

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

  1. נכנסים לחשבון Google Cloud . אם אתם משתמשים חדשים ב- Google Cloud, צרו חשבון כדי שתוכלו להעריך את הביצועים של המוצרים שלנו בתרחישים מהעולם האמיתי. לקוחות חדשים מקבלים בחינם גם קרדיט בשווי 300$ להרצה, לבדיקה ולפריסה של עומסי העבודה.
  2. התקינו את ה-CLI של Google Cloud.

  3. אם אתם משתמשים בספק זהויות חיצוני (IdP), קודם אתם צריכים להיכנס ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.

  4. כדי לאתחל את ה-CLI של gcloud, הריצו את הפקודה הבאה:

    gcloud init
  5. יוצרים או בוחרים Google Cloud פרויקט.

    תפקידים שנדרשים כדי לבחור או ליצור פרויקט

    • Select a project (בחירת פרויקט): כדי לבחור פרויקט לא צריך תפקיד IAM ספציפי – אפשר לבחור כל פרויקט שהוקצה לכם בו תפקיד.
    • יצירת פרויקט: כדי ליצור פרויקט, צריך את התפקיד Project Creator (יצירת פרויקטים) (roles/resourcemanager.projectCreator), שכולל את ההרשאה resourcemanager.projects.create. איך מקצים תפקידים
    • יוצרים Google Cloud פרויקט:

      gcloud projects create PROJECT_ID

      מחליפים את PROJECT_ID בשם של פרויקט Google Cloud שיוצרים.

    • בוחרים את הפרויקט שיצרתם: Google Cloud

      gcloud config set project PROJECT_ID

      מחליפים את PROJECT_ID בשם הפרויקט ב- Google Cloud .

  6. מוודאים שהחיוב מופעל בפרויקט Google Cloud .

  7. מפעילים את ממשקי ה-API של Artifact Registry,‏ Cloud Build,‏ Cloud Run Functions,‏ Cloud Run,‏ Cloud Storage ו-Workflows:

    תפקידים שנדרשים להפעלת ממשקי API

    כדי להפעיל ממשקי API, נדרשת ההרשאה serviceusage.services.enable. אם יצרתם את הפרויקט, סביר להניח שכבר יש לכם את ההרשאה הזו דרך התפקיד 'בעלים' (roles/owner). אחרת, תוכלו לקבל את ההרשאה הזו דרך התפקיד 'אדמין של Service Usage' (roles/serviceusage.serviceUsageAdmin). איך מקצים תפקידים

    gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com cloudfunctions.googleapis.com run.googleapis.com storage.googleapis.com workflows.googleapis.com
  8. התקינו את ה-CLI של Google Cloud.

  9. אם אתם משתמשים בספק זהויות חיצוני (IdP), קודם אתם צריכים להיכנס ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.

  10. כדי לאתחל את ה-CLI של gcloud, הריצו את הפקודה הבאה:

    gcloud init
  11. יוצרים או בוחרים Google Cloud פרויקט.

    תפקידים שנדרשים כדי לבחור או ליצור פרויקט

    • Select a project (בחירת פרויקט): כדי לבחור פרויקט לא צריך תפקיד IAM ספציפי – אפשר לבחור כל פרויקט שהוקצה לכם בו תפקיד.
    • יצירת פרויקט: כדי ליצור פרויקט, צריך את התפקיד Project Creator (יצירת פרויקטים) (roles/resourcemanager.projectCreator), שכולל את ההרשאה resourcemanager.projects.create. איך מקצים תפקידים
    • יוצרים Google Cloud פרויקט:

      gcloud projects create PROJECT_ID

      מחליפים את PROJECT_ID בשם של פרויקט Google Cloud שיוצרים.

    • בוחרים את הפרויקט שיצרתם: Google Cloud

      gcloud config set project PROJECT_ID

      מחליפים את PROJECT_ID בשם הפרויקט ב- Google Cloud .

  12. מוודאים שהחיוב מופעל בפרויקט Google Cloud .

  13. מפעילים את ממשקי ה-API של Artifact Registry,‏ Cloud Build,‏ Cloud Run Functions,‏ Cloud Run,‏ Cloud Storage ו-Workflows:

    תפקידים שנדרשים להפעלת ממשקי API

    כדי להפעיל ממשקי API, נדרשת ההרשאה serviceusage.services.enable. אם יצרתם את הפרויקט, סביר להניח שכבר יש לכם את ההרשאה הזו דרך התפקיד 'בעלים' (roles/owner). אחרת, תוכלו לקבל את ההרשאה הזו דרך התפקיד 'אדמין של Service Usage' (roles/serviceusage.serviceUsageAdmin). איך מקצים תפקידים

    gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com cloudfunctions.googleapis.com run.googleapis.com storage.googleapis.com workflows.googleapis.com
  14. מעדכנים את הרכיבים של Google Cloud CLI:
    gcloud components update
  15. אם אתם מריצים פקודות ב-Cloud Shell, אתם כבר מאומתים ב-CLI של gcloud. אחרת, אתם צריכים להיכנס באמצעות החשבון שלכם:
    gcloud auth login
  16. יוצרים חשבון שירות לשימוש ב-Workflows:

    export SERVICE_ACCOUNT=workflows-sa
    gcloud iam service-accounts create ${SERVICE_ACCOUNT}

  17. כדי לאפשר לחשבון השירות לקרוא לשירותי Cloud Run מאומתים, צריך לתת את התפקיד run.invoker לחשבון השירות של Workflows:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member "serviceAccount:${SERVICE_ACCOUNT}@PROJECT_ID.iam.gserviceaccount.com" \
        --role "roles/run.invoker"

    מחליפים את PROJECT_ID במזהה הפרויקט ב- Google Cloud .

  18. מגדירים את מיקום ברירת המחדל שבו משתמשים במדריך הזה:
    gcloud config set project PROJECT_ID
    export REGION=REGION
    gcloud config set functions/region ${REGION}
    gcloud config set run/region ${REGION}
    gcloud config set workflows/location ${REGION}

    מחליפים את REGION במיקום של Workflows שנתמך לבחירתכם.

פריסת שירות הפונקציות הראשון של Cloud Run

אחרי קבלת בקשת HTTP, פונקציית ה-HTTP הזו יוצרת מספר אקראי בין 1 ל-100, ואז מחזירה את המספר בפורמט JSON.

  1. יוצרים ספרייה בשם randomgen ועוברים אליה:

    mkdir ~/randomgen
    cd ~/randomgen
  2. יוצרים קובץ טקסט בשם main.py שמכיל את קוד Python הבא:

    import functions_framework
    import random
    from flask import jsonify
    
    
    @functions_framework.http
    def randomgen(request):
        randomNum = random.randint(1, 100)
        output = {"random": randomNum}
        return jsonify(output)
  3. כדי לתמוך בתלות ב-Flask לעיבוד HTTP, יוצרים קובץ טקסט עבור מנהל החבילות pip. נותנים לו את שם הקובץ requirements.txt ומוסיפים את הטקסט הבא:

    flask>=1.0.2
    functions-framework==3.0.0
  4. פורסים את הפונקציה עם טריגר HTTP ומאפשרים גישה ללא אימות:

    gcloud functions deploy randomgen \
        --runtime python37 \
        --trigger-http \
        --allow-unauthenticated

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

  1. אחרי הפריסה של הפונקציה, אפשר לאשר את המאפיין httpsTrigger.url:

    gcloud functions describe randomgen
  2. אפשר לנסות את הפונקציה באמצעות פקודת curl הבאה:

    curl $(gcloud functions describe randomgen --format='value(httpsTrigger.url)')

    מספר נוצר באופן אקראי ומוחזר.

פריסת שירות הפונקציות השני של Cloud Run

אחרי קבלת בקשת HTTP, פונקציית ה-HTTP הזו מחלצת את input מגוף ה-JSON, מכפילה אותו ב-2 ומחזירה את התוצאה בפורמט JSON.

  1. יוצרים ספרייה בשם multiply ועוברים אליה:

    mkdir ~/multiply
    cd ~/multiply
  2. יוצרים קובץ טקסט בשם main.py שמכיל את קוד Python הבא:

    import functions_framework
    from flask import jsonify
    
    
    @functions_framework.http
    def multiply(request):
        request_json = request.get_json()
        output = {"multiplied": 2 * request_json['input']}
        return jsonify(output)
  3. כדי לתמוך בתלות ב-Flask לעיבוד HTTP, יוצרים קובץ טקסט עבור מנהל החבילות pip. נותנים לו את שם הקובץ requirements.txt ומוסיפים את הטקסט הבא:

    flask>=1.0.2
    functions-framework==3.0.0
  4. פורסים את הפונקציה עם טריגר HTTP ומאפשרים גישה ללא אימות:

    gcloud functions deploy multiply \
        --runtime python37 \
        --trigger-http \
        --allow-unauthenticated

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

  1. אחרי הפריסה של הפונקציה, אפשר לאשר את המאפיין httpsTrigger.url:

    gcloud functions describe multiply
  2. אפשר לנסות את הפונקציה באמצעות פקודת curl הבאה:

    curl $(gcloud functions describe multiply --format='value(httpsTrigger.url)') \
        -X POST \
        -H "content-type: application/json" \
        -d '{"input": 5}'

    הפונקציה תחזיר את המספר 10.

חיבור בין שני שירותים של פונקציות Cloud Run בתהליך עבודה

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

  1. מנווטים חזרה לספריית הבית:

    cd ~
  2. יוצרים קובץ טקסט בשם workflow.yaml עם התוכן הבא:

    - randomgen_function:
        call: http.get
        args:
            url: https://REGION-PROJECT_ID.cloudfunctions.net/randomgen
        result: randomgen_result
    - multiply_function:
        call: http.post
        args:
            url: https://REGION-PROJECT_ID.cloudfunctions.net/multiply
            body:
                input: ${randomgen_result.body.random}
        result: multiply_result
    - return_result:
        return: ${multiply_result}
    

    הפונקציה הזו מקשרת בין שתי פונקציות HTTP ומחזירה תוצאה סופית.

  3. אחרי שיוצרים את תהליך העבודה, אפשר לפרוס אותו ולהכין אותו להרצה.

    gcloud workflows deploy WORKFLOW_NAME --source=workflow.yaml

    מחליפים את WORKFLOW_NAME בשם של זרימת העבודה.

  4. מריצים את תהליך העבודה:

    gcloud workflows run WORKFLOW_NAME

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

    אחרי הפעלת תהליך העבודה, הפלט אמור להיראות כך:

    result: '{"body":{"multiplied":120},"code":200,"headers":{"Alt-Svc":"h3-29=\":443\";
    ...
    startTime: '2021-05-05T14:17:39.135251700Z'
    state: SUCCEEDED
    ...
    

חיבור שירות REST ציבורי בתהליך העבודה

מעדכנים את תהליך העבודה הקיים ומקשרים API ציבורי ל-REST ‏(math.js) שיכול להעריך ביטויים מתמטיים. לדוגמה, curl https://api.mathjs.org/v4/?'expr=log(56)'.

שימו לב: אחרי שפורסים את תהליך העבודה, אפשר לערוך אותו גם דרך הדף Workflows במסוף Google Cloud .

  1. עורכים את קובץ המקור של תהליך העבודה ומחליפים אותו בתוכן הבא:

    - randomgen_function:
        call: http.get
        args:
            url: https://REGION-PROJECT_ID.cloudfunctions.net/randomgen
        result: randomgen_result
    - multiply_function:
        call: http.post
        args:
            url: https://REGION-PROJECT_ID.cloudfunctions.net/multiply
            body:
                input: ${randomgen_result.body.random}
        result: multiply_result
    - log_function:
        call: http.get
        args:
            url: https://api.mathjs.org/v4/
            query:
                expr: ${"log(" + string(multiply_result.body.multiplied) + ")"}
        result: log_result
    - return_result:
        return: ${log_result}
    

    הפעולה הזו מקשרת את שירות ה-REST החיצוני לשירותי הפונקציות של Cloud Run, ומחזירה תוצאה סופית.

  2. פורסים את תהליך העבודה ששיניתם:

    gcloud workflows deploy WORKFLOW_NAME --source=workflow.yaml

פריסת שירות Cloud Run

פריסת שירות Cloud Run, שאחרי קבלת בקשת HTTP, מחלץ את input מתוכן ה-JSON, מחשב את math.floor ומחזיר את התוצאה.

  1. יוצרים ספרייה בשם floor ועוברים אליה:

    mkdir ~/floor
    cd ~/floor
  2. יוצרים קובץ טקסט בשם app.py שמכיל את קוד Python הבא:

    import json
    import logging
    import os
    import math
    
    from flask import Flask, request
    
    app = Flask(__name__)
    
    
    @app.route('/', methods=['POST'])
    def handle_post():
        content = json.loads(request.data)
        input = float(content['input'])
        return f"{math.floor(input)}", 200
    
    
    if __name__ != '__main__':
        # Redirect Flask logs to Gunicorn logs
        gunicorn_logger = logging.getLogger('gunicorn.error')
        app.logger.handlers = gunicorn_logger.handlers
        app.logger.setLevel(gunicorn_logger.level)
        app.logger.info('Service started...')
    else:
        app.run(debug=True, host='0.0.0.0', port=int(os.environ.get('PORT', 8080)))

  3. באותה תיקייה, יוצרים קובץ Dockerfile עם התוכן הבא:

    # Use an official lightweight Python image.
    # https://hub.docker.com/_/python
    FROM python:3.7-slim
    
    # Install production dependencies.
    RUN pip install Flask gunicorn
    
    # Copy local code to the container image.
    WORKDIR /app
    COPY . .
    
    # Run the web service on container startup. Here we use the gunicorn
    # webserver, with one worker process and 8 threads.
    # For environments with multiple CPU cores, increase the number of workers
    # to be equal to the cores available.
    CMD exec gunicorn --bind 0.0.0.0:8080 --workers 1 --threads 8 app:app

  4. יוצרים מאגר רגיל של Artifact Registry שבו אפשר לאחסן את קובץ האימג' של קונטיינר Docker:

    gcloud artifacts repositories create REPOSITORY \
        --repository-format=docker \
        --location=${REGION}

    מחליפים את REPOSITORY בשם ייחודי למאגר.

  5. יוצרים את קובץ האימג' של הקונטיינר:

    export SERVICE_NAME=floor
    gcloud builds submit --tag ${REGION}-docker.pkg.dev/PROJECT_ID/REPOSITORY/${SERVICE_NAME}
  6. פורסים את קובץ האימג' של הקונטיינר ב-Cloud Run, ומוודאים שהוא מקבל רק קריאות מאומתות:

    gcloud run deploy ${SERVICE_NAME} \
        --image ${REGION}-docker.pkg.dev/PROJECT_ID/REPOSITORY/${SERVICE_NAME}:latest \
        --platform managed \
        --no-allow-unauthenticated

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

חיבור שירות Cloud Run בתהליך העבודה

מעדכנים את תהליך העבודה הקיים ומציינים את כתובת ה-URL של שירות Cloud Run.

  1. עורכים את קובץ המקור של תהליך העבודה ומחליפים אותו בתוכן הבא:

    - randomgen_function:
        call: http.get
        args:
            url: https://REGION-PROJECT_ID.cloudfunctions.net/randomgen
        result: randomgen_result
    - multiply_function:
        call: http.post
        args:
            url: https://REGION-PROJECT_ID.cloudfunctions.net/multiply
            body:
                input: ${randomgen_result.body.random}
        result: multiply_result
    - log_function:
        call: http.get
        args:
            url: https://api.mathjs.org/v4/
            query:
                expr: ${"log(" + string(multiply_result.body.multiplied) + ")"}
        result: log_result
    - floor_function:
        call: http.post
        args:
            url: CLOUD_RUN_SERVICE_URL
            auth:
                type: OIDC
            body:
                input: ${log_result.body}
        result: floor_result
    - create_output_map:
        assign:
          - outputMap:
              randomResult: ${randomgen_result}
              multiplyResult: ${multiply_result}
              logResult: ${log_result}
              floorResult: ${floor_result}
    - return_output:
        return: ${outputMap}
    

    מחליפים את CLOUD_RUN_SERVICE_URL בכתובת ה-URL של שירות Cloud Run.

    הפעולה הזו מחברת את שירות Cloud Run לתהליך העבודה. שימו לב שהמפתח auth מוודא שאסימון אימות מועבר בקריאה לשירות Cloud Run. מידע נוסף זמין במאמר בנושא שליחת בקשות מאומתות מתהליך עבודה.

  2. פורסים את תהליך העבודה ששיניתם:

    gcloud workflows deploy WORKFLOW_NAME \
        --source=workflow.yaml
  3. מריצים את תהליך העבודה הסופי:

    gcloud workflows run WORKFLOW_NAME

    הפלט אמור להיראות כך:

    result: '{"Floor":{"body":"4","code":200
      ...
      "Log":{"body":"4.02535169073515","code":200
      ...
      "Multiply":{"body":{"multiplied":56},"code":200
      ...
      "Random":{"body":{"random":28},"code":200
      ...
    startTime: '2023-11-13T21:22:56.782669001Z'
    state: SUCCEEDED
    

כל הכבוד! פרסתם והפעלתם תהליך עבודה שמקשר בין סדרה של שירותים.

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

הסרת המשאבים

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

מחיקת הפרויקט

הדרך הקלה ביותר לבטל את החיוב היא למחוק את הפרויקט שיצרתם בשביל המדריך הזה.

כדי למחוק את הפרויקט:

  1. במסוף Google Cloud , נכנסים לדף Manage resources.

    כניסה לדף Manage resources

  2. ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
  3. כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.

מחיקת משאבי הדרכה

המאמרים הבאים