פריסת אפליקציית JavaScript ב-Cloud Run באמצעות AlloyDB

1. סקירה כללית

Cloud Run היא פלטפורמה מנוהלת באופן מלא ללא שרת (serverless) שמאפשרת להריץ קונטיינרים ללא שמירת מצב שאפשר להפעיל באמצעות בקשות HTTP. Codelab זה ידגים איך לחבר אפליקציית Node.js ב-Cloud Run ל-AlloyDB בצורה מאובטחת באמצעות חשבון שירות ואימות IAM.

מה תלמדו

בשיעור ה-Lab הזה תלמדו איך:

  • יצירת מופע AlloyDB (שמוגדר לשימוש ב-Private Service Connect)
  • פריסת אפליקציה ב-Cloud Run שמתחברת למופע AlloyDB

2. דרישות מוקדמות

  1. אם אין לכם חשבון Google, אתם צריכים ליצור חשבון Google.
    • משתמשים בחשבון לשימוש אישי במקום בחשבון לצורכי עבודה או בחשבון בית ספרי. יכול להיות שבחשבונות לצורכי עבודה או בחשבונות בית ספריים יש הגבלות שימנעו מכם להפעיל את ממשקי ה-API שנדרשים למעבדה הזו.

3. הגדרת הפרויקט

  1. נכנסים ל-מסוף Google Cloud.
  2. מפעילים את החיוב במסוף Cloud.
    • העלות של השלמת ה-Lab הזה במשאבי Cloud צריכה להיות פחות מ-1$.
    • כדי למחוק משאבים ולמנוע חיובים נוספים, אפשר לבצע את השלבים בסוף ה-Lab הזה.
    • משתמשים חדשים זכאים לתקופת ניסיון בחינם בשווי 300$.
  3. יוצרים פרויקט חדש או בוחרים להשתמש מחדש בפרויקט קיים.

4. פתיחת Cloud Shell Editor

  1. עוברים אל Cloud Shell Editor.
  2. אם הטרמינל לא מופיע בתחתית המסך, פותחים אותו:
    • לוחצים על סמל האפשרויות הנוספות (3 קווים) סמל של תפריט האפשרויות הנוספות (3 קווים).
    • לוחצים על Terminal (מסוף).
    • לוחצים על New Terminal (טרמינל חדש)פתיחת טרמינל חדש ב-Cloud Shell Editor.
  3. בטרמינל, מגדירים את הפרויקט באמצעות הפקודה הבאה:
    • פורמט:
      gcloud config set project [PROJECT_ID]
      
    • דוגמה:
      gcloud config set project lab-project-id-example
      
    • אם אתם לא זוכרים את מזהה הפרויקט:
      • כדי לראות את כל מזהי הפרויקטים, מריצים את הפקודה:
        gcloud projects list | awk '/PROJECT_ID/{print $2}'
        
      הגדרת מזהה הפרויקט בטרמינל של Cloud Shell Editor
  4. אם מתבקשים לאשר, לוחצים על אישור כדי להמשיך. לוחצים כדי לתת הרשאה ל-Cloud Shell
  5. תוצג ההודעה הבאה:
    Updated property [core/project].
    
    אם מופיע WARNING ומוצגת השאלה Do you want to continue (Y/N)?, כנראה שהזנתם את מזהה הפרויקט בצורה שגויה. לוחצים על N, לוחצים על Enter ומנסים להריץ שוב את הפקודה gcloud config set project.

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

בטרמינל, מפעילים את ממשקי ה-API:

gcloud services enable \
  compute.googleapis.com \
  alloydb.googleapis.com \
  run.googleapis.com \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  cloudaicompanion.googleapis.com

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

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

Operation "operations/acf.p2-73d90d00-47ee-447a-b600" finished successfully.

6. הגדרה של חשבון שירות

יוצרים ומגדירים חשבון שירות ב-Google Cloud לשימוש ב-Cloud Run, כדי שיהיו לו ההרשאות הנכונות להתחבר ל-AlloyDB.

  1. כדי ליצור חשבון שירות חדש, מריצים את הפקודה gcloud iam service-accounts create באופן הבא:
    gcloud iam service-accounts create quickstart-service-account \
      --display-name="Quickstart Service Account"
    
  2. מריצים את הפקודה gcloud projects add-iam-policy-binding באופן הבא כדי להוסיף את התפקיד AlloyDB Database User לחשבון השירות של Google Cloud שיצרתם.
    gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
      --member="serviceAccount:quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
      --role="roles/alloydb.databaseUser"
    
  3. מריצים את הפקודה gcloud projects add-iam-policy-binding באופן הבא כדי להוסיף את התפקיד צרכן של שימוש בשירות לחשבון השירות ב-Google Cloud שיצרתם.
    gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
      --member="serviceAccount:quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
      --role="roles/serviceusage.serviceUsageConsumer"
    
  4. מריצים את הפקודה gcloud projects add-iam-policy-binding באופן הבא כדי להוסיף את התפקיד Log Writer לחשבון השירות ב-Google Cloud שיצרתם.
    gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
      --member="serviceAccount:quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
      --role="roles/logging.logWriter"
    

7. יצירת מסד נתונים של AlloyDB

  1. מריצים את הפקודה gcloud alloydb clusters create כדי ליצור מכונה של Cloud SQL
    gcloud alloydb clusters create quickstart-cluster \
      --password=$(openssl rand -base64 20) \
      --region=us-central1 \
      --project=${GOOGLE_CLOUD_PROJECT} \
      --enable-private-service-connect \
      --database-version=POSTGRES_16
    

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

  1. מריצים את הפקודה gcloud alloydb instances create כדי ליצור מכונה של Cloud SQL
    gcloud alloydb instances create quickstart-instance \
      --project=${GOOGLE_CLOUD_PROJECT} \
      --instance-type=PRIMARY \
      --cpu-count=2 \
      --region=us-central1 \
      --cluster=quickstart-cluster \
      --allowed-psc-projects=${GOOGLE_CLOUD_PROJECT} \
      --database-flags=alloydb.iam_authentication=on
    
  2. מריצים את הפקודה gcloud alloydb instances describe כדי לקבל את הקישור של שירות ה-PSC ולייצא אותו למשתנה.
    export SERVICE_ATTACHMENT=$(gcloud alloydb instances describe quickstart-instance \
        --cluster=quickstart-cluster --region=us-central1 \
        --format="value(pscInstanceConfig.serviceAttachmentLink)")
    
  3. gcloud compute addresses create quickstart-address \
      --region=us-central1 \
      --subnet=default
    
  4. gcloud compute forwarding-rules create quickstart-endpoint \
      --region=us-central1 \
      --network=default \
      --address=quickstart-address \
      --target-service-attachment=${SERVICE_ATTACHMENT}
    

יוצרים משתמש במסד נתונים של PostgreSQL עבור חשבון השירות שיצרתם קודם כדי לגשת למסד הנתונים.

gcloud alloydb users create quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam \
  --cluster=quickstart-cluster \
  --region=us-central1 \
  --type=IAM_BASED \
  --superuser=true

8. הכנת הבקשה

מכינים אפליקציית Node.js שמגיבה לבקשות HTTP.

  1. ב-Cloud Shell, יוצרים ספרייה חדשה בשם helloworld ועוברים אליה:
    mkdir helloworld
    cd helloworld
    
  2. מאתחלים קובץ package.json כמודול.
    npm init -y
    npm pkg set type="module"
    npm pkg set main="index.mjs"
    npm pkg set scripts.start="node index.mjs"
    
  3. מתקינים את ספריית האימות של Google Cloud.
    npm install google-auth-library
    
  4. מתקינים את pg כדי לבצע פעולות לגבי מסד הנתונים של PostgreSQL.
    npm install pg
    
  5. מתקינים את express כדי לאשר בקשות http נכנסות.
    npm install express
    
  6. יוצרים קובץ index.mjs עם קוד האפליקציה. הקוד הזה יכול:
    • אישור בקשות HTTP
    • התחברות למסד הנתונים
    • אחסון השעה של בקשת ה-HTTP במסד הנתונים
    • החזרת הזמנים של חמש הבקשות האחרונות
    מריצים את הפקודה הבאה ב-Cloud Shell:
    cat > index.mjs << "EOF"
    import express from 'express';
    import pg from 'pg';
    const { Pool } = pg;
    import {GoogleAuth} from 'google-auth-library';
    
    const auth = new GoogleAuth({
      scopes: ['https://www.googleapis.com/auth/alloydb.login'],
    });
    
    const pool = new Pool({
      host: process.env.DB_HOST,
      user: process.env.DB_USER,
      password: async () => {
        return await auth.getAccessToken();
      },
      database: process.env.DB_NAME,
      ssl: {
        require: true,
        rejectUnauthorized: false, // required for self-signed certs
        // https://node-postgres.com/features/ssl#self-signed-cert
      }
    });
    
    const app = express();
    
    app.get('/', async (req, res) => {
      await pool.query('INSERT INTO visits(created_at) VALUES(NOW())');
      const {rows} = await pool.query('SELECT created_at FROM visits ORDER BY created_at DESC LIMIT 5');
      console.table(rows); // prints the last 5 visits
      res.send(rows);
    });
    
    const port = parseInt(process.env.PORT) || 8080;
    app.listen(port, async () => {
      console.log('process.env: ', process.env);
      await pool.query(`CREATE TABLE IF NOT EXISTS visits (
        id SERIAL NOT NULL,
        created_at timestamp NOT NULL,
        PRIMARY KEY (id)
      );`);
      console.log(`helloworld: listening on port ${port}`);
    });
    
    EOF
    

הקוד הזה יוצר שרת אינטרנט בסיסי שמקשיב ליציאה שמוגדרת על ידי משתנה הסביבה PORT. האפליקציה מוכנה עכשיו לפריסה.

9. פריסת אפליקציית Cloud Run

  1. מריצים את הפקודה הבאה כדי לפרוס את האפליקציה ב-Cloud Run:
    gcloud run deploy helloworld \
      --region=us-central1 \
      --source=. \
      --set-env-vars DB_NAME="quickstart_db" \
      --set-env-vars DB_USER="postgres" \
      --set-env-vars DB_PASSWORD=${DB_PASSWORD} \
      --set-env-vars DB_HOST="$(gcloud sql instances describe quickstart-instance --project=${GOOGLE_CLOUD_PROJECT} --format='value(settings.ipConfiguration.pscConfig.pscAutoConnections.ipAddress)')" \
      --service-account="quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
      --network=default \
      --subnet=default \
      --allow-unauthenticated
    
  2. אם מוצגת הנחיה, מקישים על Y ועל Enter כדי לאשר שרוצים להמשיך:
    Do you want to continue (Y/n)? Y
    

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

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

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

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

10. מזל טוב

בשיעור ה-Lab הזה למדתם איך:

  • יצירת מופע AlloyDB (שמוגדר לשימוש ב-Private Service Connect)
  • פריסת אפליקציה ב-Cloud Run שמתחברת למופע AlloyDB

הסרת המשאבים

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

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

אם רוצים, אפשר למחוק את הפרויקט:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

אפשר גם למחוק משאבים מיותרים מהדיסק של Cloud Shell. אתם יכולים:

  1. מוחקים את ספריית הפרויקט של ה-codelab:
    rm -rf ~/task-app
    
  2. אזהרה! אי אפשר לבטל את הפעולה הבאה! אם רוצים למחוק את כל מה שיש ב-Cloud Shell כדי לפנות מקום, אפשר למחוק את כל ספריית הבית. חשוב לוודא שכל מה שרוצים לשמור נשמר במקום אחר.
    sudo rm -rf $HOME
    

לומדים בכיף