אירוח והתאמה לעומס של אפליקציית אינטרנט ב-Google Cloud באמצעות Compute Engine

1. מבוא

יש הרבה דרכים לפרוס אתרים ב-Google Cloud, וכל פתרון מציע תכונות, יכולות ורמות שליטה שונות. ‫Compute Engine מציע רמת שליטה גבוהה בתשתית שמשמשת להפעלת אתר, אבל הוא גם דורש קצת יותר ניהול תפעולי בהשוואה לפתרונות כמו Google Kubernetes Engine,‏ App Engine או אחרים. עם Compute Engine, יש לכם שליטה מדויקת בהיבטים של התשתית, כולל המכונות הווירטואליות, מאזן העומסים ועוד. במאמר הזה נסביר איך אפשר לפרוס אתר ולהתאים אותו בקלות לעומס באמצעות Compute Engine. לשם כך, נשתמש באפליקציה לדוגמה – אתר המסחר האלקטרוני של Fancy Store.

מה תלמדו

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

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

2. הגדרת הסביבה

הגדרת סביבה בקצב אישי

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

96a9c957bc475304.pngb9a10ebdf5b5a448.pnga1e3c01a38fa61c2.png

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

  1. לאחר מכן, תצטרכו להפעיל את החיוב ב-Cloud Console כדי להשתמש במשאבים של Google Cloud.

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

הפעלת Compute Engine API

בשלב הבא צריך להפעיל את Compute Engine API. כדי להפעיל API, צריך לאשר את התנאים וההגבלות שלו ולציין מי אחראי על החיוב של השימוש ב-API.

ב-Cloud Shell, מריצים את הפקודה הבאה כדי להפעיל את Compute Engine API:

gcloud services enable compute.googleapis.com

Cloud Shell

אפשר להפעיל את Google Cloud מרחוק מהמחשב הנייד, אבל ב-Codelab הזה נשתמש ב-Cloud Shell, סביבת שורת פקודה שפועלת בענן.

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

  1. כדי להפעיל את Cloud Shell ממסוף Cloud, פשוט לוחצים על הפעלת Cloud Shell a8460e837e9f5fda.png (הקצאת המשאבים והחיבור לסביבה אמורים להימשך רק כמה רגעים).

b532b2f19ab85dda.pngScreen Shot 2017-06-14 at 10.13.43 PM.png

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

gcloud auth list

פלט הפקודה

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

פלט הפקודה

[core]
project = <PROJECT_ID>

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

gcloud config set project <PROJECT_ID>

חיפשת את PROJECT_ID? בודקים באיזה מזהה השתמשתם בשלבי ההגדרה או מחפשים אותו בלוח הבקרה של Cloud Console:

2485e00c1223af09.png

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

echo $GOOGLE_CLOUD_PROJECT

פלט הפקודה

<PROJECT_ID>
  1. לבסוף, מגדירים את אזור ברירת המחדל ואת הגדרת הפרויקט.
gcloud config set compute/zone us-central1-f

אפשר לבחור מתוך מגוון אזורים שונים. מידע נוסף זמין במאמר בנושא אזורים ותחומים.

יצירת קטגוריה של Cloud Storage

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

gsutil mb gs://fancy-store-$DEVSHELL_PROJECT_ID

3. שכפול מאגר המקור

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

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

לחלופין, אפשר לשכפל את המאגר באופן ידני באמצעות הפקודות הבאות ב-Cloud Shell:

cd ~
git clone https://github.com/googlecodelabs/monolith-to-microservices.git
cd ~/monolith-to-microservices

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

./setup.sh

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

cd microservices
npm start

פלט:

Products microservice listening on port 8082!
Frontend microservice listening on port 8080!
Orders microservice listening on port 8081!

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

6634c06dd0b9172c.png

ייפתח חלון חדש שבו תוכלו לראות את חזית החנות של Fancy Store בפעולה.

abf2ca314bf80d03.png

אחרי שצופים באתר, אפשר לסגור את החלון הזה. כדי להפסיק את התהליך של שרת האינטרנט, מקישים על Control+C (Command+C ב-Macintosh) בחלון הטרמינל.

4. יצירת מכונות של Compute Engine

עכשיו, אחרי שיש לכם סביבת פיתוח פעילה, אתם יכולים לפרוס כמה מכונות וירטואליות של Compute Engine. בשלבים הבאים תלמדו:

  1. יוצרים סקריפט לטעינה בזמן ההפעלה כדי להגדיר מכונות.
  2. משכפלים את קוד המקור ומעלים אותו ל-Cloud Storage.
  3. פריסת מכונה של Compute Engine לאירוח המיקרו-שירותים של הקצה העורפי.
  4. מגדירים מחדש את קוד הקצה הקדמי כדי להשתמש במופע של מיקרו-שירותים בקצה העורפי.
  5. פורסים מכונה של Compute Engine לאירוח מיקרו-שירות של קצה קדמי.
  6. מגדירים את הרשת כך שתאפשר תקשורת.

יצירת סקריפט לטעינה בזמן ההפעלה

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

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

עוברים לתיקייה monolith-to-microservices. לוחצים על קובץ > קובץ חדש ויוצרים קובץ בשם startup-script.sh.

439553c934139b82.png

בקובץ החדש, מדביקים את הקוד הבא. חלק מהקוד צריך לערוך אחרי ההדבקה:

#!/bin/bash

# Install logging monitor. The monitor will automatically pick up logs sent to
# syslog.
curl -s "https://storage.googleapis.com/signals-agents/logging/google-fluentd-install.sh" | bash
service google-fluentd restart &

# Install dependencies from apt
apt-get update
apt-get install -yq ca-certificates git build-essential supervisor psmisc

# Install nodejs
mkdir /opt/nodejs
curl https://nodejs.org/dist/v8.12.0/node-v8.12.0-linux-x64.tar.gz | tar xvzf - -C /opt/nodejs --strip-components=1
ln -s /opt/nodejs/bin/node /usr/bin/node
ln -s /opt/nodejs/bin/npm /usr/bin/npm

# Get the application source code from the Google Cloud Storage bucket.
mkdir /fancy-store
gsutil -m cp -r gs://fancy-store-[DEVSHELL_PROJECT_ID]/monolith-to-microservices/microservices/* /fancy-store/

# Install app dependencies.
cd /fancy-store/
npm install

# Create a nodeapp user. The application will run as this user.
useradd -m -d /home/nodeapp nodeapp
chown -R nodeapp:nodeapp /opt/app

# Configure supervisor to run the node app.
cat >/etc/supervisor/conf.d/node-app.conf << EOF
[program:nodeapp]
directory=/fancy-store
command=npm start
autostart=true
autorestart=true
user=nodeapp
environment=HOME="/home/nodeapp",USER="nodeapp",NODE_ENV="production"
stdout_logfile=syslog
stderr_logfile=syslog
EOF

supervisorctl reread
supervisorctl update

עכשיו, בעורך הקוד, מחפשים את הטקסט [DEVSHELL_PROJECT_ID] ומחליפים אותו בפלט של הפקודה הבאה:

echo $DEVSHELL_PROJECT_ID

פלט לדוגמה:

my-gce-codelab-253520

שורה הקוד בקובץ startup-script.sh צריכה להיות דומה לשורה הבאה:

gs://fancy-store-my-gce-codelab-253520/monolith-to-microservices/microservices/* /fancy-store/

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

  • התקנה של סוכן Logging, שאוסף באופן אוטומטי יומנים מ-syslog
  • התקנה של Node.js ו-Supervisor, שמריצים את האפליקציה כדמון
  • שיבוט של קוד המקור של האפליקציה מקטגוריה של Cloud Storage והתקנה של יחסי תלות
  • הגדרת Supervisor, שמריץ את האפליקציה, מוודאת שהאפליקציה תופעל מחדש אם היא נסגרת באופן לא צפוי או אם אדמין או תהליך עוצרים אותה, ושולחת את stdout ו-stderr של האפליקציה ל-syslog כדי שסוכן Logging יאסוף אותם.

מעתיקים את קובץ startup-script.sh שנוצר לקטגוריה של Cloud Storage שיצרתם קודם:

gsutil cp ~/monolith-to-microservices/startup-script.sh gs://fancy-store-$DEVSHELL_PROJECT_ID

עכשיו אפשר לגשת אליו בכתובת https://storage.googleapis.com/[BUCKET_NAME]/startup-script.sh. ‫[BUCKET_NAME] מייצג את השם של קטגוריה של Cloud Storage. כברירת מחדל, רק משתמשים מורשים וחשבונות שירות יכולים לראות את הנתונים האלה, ולכן לא תהיה אליהם גישה דרך דפדפן אינטרנט. המכונות ב-Compute Engine יוכלו לגשת אליו באופן אוטומטי דרך חשבונות השירות שלהן.

העתקת קוד לקטגוריה של Cloud Storage

כשמפעילים מופעים, הם שולפים קוד מקטגוריית Cloud Storage, כדי שתוכלו לאחסן כמה משתני תצורה בקובץ ‎.env של הקוד.

מעתיקים את הקוד המשובט לקטגוריה של Cloud Storage:

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

פריסת מופע של הקצה העורפי

המופע הראשון שתפרסו יהיה שרת עורפי (backend instance), שיכיל את המיקרו-שירותים של ההזמנות והמוצרים.

מריצים את הפקודה הבאה ב-Cloud Shell כדי ליצור מכונה מסוג f1-micro שמוגדרת להשתמש בסקריפט לטעינה בזמן ההפעלה שיצרתם קודם, ומתויגת כמופע backend כדי שתוכלו להחיל עליה כללי חומת אש ספציפיים בהמשך:

gcloud compute instances create backend \
    --machine-type=f1-micro \
    --image=debian-9-stretch-v20190905 \
    --image-project=debian-cloud \
    --tags=backend \
    --metadata=startup-script-url=https://storage.googleapis.com/fancy-store-$DEVSHELL_PROJECT_ID/startup-script.sh

הגדרת חיבור לקצה העורפי

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

מאחזרים את כתובת ה-IP החיצונית של ה-Backend, שאפשר לראות אותה באמצעות הפקודה הבאה בכרטיסייה EXTERNAL_IP של שרת עורפי (backend instance):

gcloud compute instances list

פלט לדוגמה:

NAME     ZONE           MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP   STATUS
backend  us-central1-a  f1-micro                   10.128.0.2   34.68.223.88  RUNNING

בכלי לעריכת קוד של Cloud Shell, עוברים לתיקייה monolith-to-microservices > react-app. בתפריט של הכלי לעריכת קוד, בוחרים באפשרות View > Toggle Hidden Files (תצוגה > החלפת מצב של קבצים מוסתרים) כדי לראות את הקובץ ‎.env.

e7314ceda643e16.png

עורכים את הקובץ .env כדי להפנות לכתובת ה-IP החיצונית של ה-backend. ‫[BACKEND_ADDRESS] שבהמשך מייצג את כתובת ה-IP החיצונית של שרת עורפי (backend instance) שנקבעה מהפקודה הקודמת בכלי gcloud.

REACT_APP_ORDERS_URL=http://[BACKEND_ADDRESS]:8081/api/orders
REACT_APP_PRODUCTS_URL=http://[BACKEND_ADDRESS]:8082/api/products

שומרים את הקובץ.

כדי לבנות מחדש את react-app, שמעדכן את קוד ה-קצה קדמי, משתמשים ב-פקודה הבאה:

cd ~/monolith-to-microservices/react-app
npm install && npm run-script build

מעתיקים את קוד האפליקציה לקטגוריה של Cloud Storage:

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

פריסת שרת קצה (frontend instance)

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

gcloud compute instances create frontend \
    --machine-type=f1-micro \
    --image=debian-9-stretch-v20190905 \
    --image-project=debian-cloud \
    --tags=frontend \
    --metadata=startup-script-url=https://storage.googleapis.com/fancy-store-$DEVSHELL_PROJECT_ID/startup-script.sh 

הגדרת רשת

יוצרים כללים של חומת אש כדי לאפשר גישה ליציאה 8080 לחלק הקדמי, וליציאות 8081 ו-8082 לחלק האחורי. הפקודות של חומת האש משתמשות בתגים שהוקצו במהלך יצירת המופע לאפליקציה.

gcloud compute firewall-rules create fw-fe \
    --allow tcp:8080 \
    --target-tags=frontend
gcloud compute firewall-rules create fw-be \
    --allow tcp:8081-8082 \
    --target-tags=backend

האתר אמור לפעול עכשיו. קובעים את כתובת ה-IP החיצונית של חזית האתר. אפשר לקבוע את הכתובת על ידי חיפוש כתובת IP חיצונית של שרת קצה (frontend instance):

gcloud compute instances list

פלט לדוגמה:

NAME      ZONE           MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP      STATUS
backend   us-central1-a  f1-micro                   10.128.0.2   104.198.235.171  RUNNING
frontend  us-central1-a  f1-micro                   10.128.0.3   34.69.141.9      RUNNING

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

watch -n 5 curl http://[EXTERNAL_IP]:8080 

אחרי שיוצג פלט שדומה לזה שמופיע בהמשך, האתר אמור להיות מוכן. מקישים על Control+C (Command+C ב-Macintosh) בשורת הפקודה כדי לבטל את הפקודה של השעון.

80dc8721dc08d7e4.png

עוברים לכתובת http://[FRONTEND_ADDRESS]:8080 בכרטיסייה חדשה בדפדפן האינטרנט כדי לגשת לאתר, כאשר [FRONTEND_ADDRESS] הוא ה-EXTERNAL_IP שנקבע למעלה.

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

a11460a1fffb07d8.png

5. יצירת קבוצות של מופעי מכונה מנוהלים

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

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

יצירת תבנית של הגדרות מכונה ממכונת מקור

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

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

קודם כול, צריך לעצור את שתי המכונות.

gcloud compute instances stop frontend
gcloud compute instances stop backend

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

gcloud compute instance-templates create fancy-fe \
    --source-instance=frontend
gcloud compute instance-templates create fancy-be \
    --source-instance=backend

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

gcloud compute instance-templates list

פלט לדוגמה:

NAME      MACHINE_TYPE  PREEMPTIBLE  CREATION_TIMESTAMP
fancy-be  f1-micro                   2019-09-12T07:52:57.544-07:00
fancy-fe  f1-micro                   2019-09-12T07:52:48.238-07:00

יצירת קבוצה של מופעי מכונה מנוהלים

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

gcloud compute instance-groups managed create fancy-fe-mig \
    --base-instance-name fancy-fe \
    --size 2 \
    --template fancy-fe
gcloud compute instance-groups managed create fancy-be-mig \
    --base-instance-name fancy-be \
    --size 2 \
    --template fancy-be

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

gcloud compute instance-groups set-named-ports fancy-fe-mig \ 
    --named-ports frontend:8080
gcloud compute instance-groups set-named-ports fancy-be-mig \
    --named-ports orders:8081,products:8082

הגדרת תיקון אוטומטי

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

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

יוצרים בדיקת תקינות שמתקנת את המופע אם הוא מוחזר כלא תקין שלוש פעמים ברציפות עבור חזית האתר והעורף:

gcloud compute health-checks create http fancy-fe-hc \
    --port 8080 \
    --check-interval 30s \
    --healthy-threshold 1 \
    --timeout 10s \
    --unhealthy-threshold 3
gcloud compute health-checks create http fancy-be-hc \
    --port 8081 \
    --request-path=/api/orders \
    --check-interval 30s \
    --healthy-threshold 1 \
    --timeout 10s \
    --unhealthy-threshold 3

יוצרים כלל חומת אש שמאפשר לבקשות לבדיקת תקינות להתחבר למיקרו-שירותים ביציאות 8080 ו-8081:

gcloud compute firewall-rules create allow-health-check \
    --allow tcp:8080-8081 \
    --source-ranges 130.211.0.0/22,35.191.0.0/16 \
    --network default

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

gcloud compute instance-groups managed update fancy-fe-mig \
    --health-check fancy-fe-hc \
    --initial-delay 300
gcloud compute instance-groups managed update fancy-be-mig \
    --health-check fancy-be-hc \
    --initial-delay 300

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

6. יצירת מאזן עומסים

כדי להשלים את קבוצות המופעים המנוהלות שלנו, תשתמשו באיזון עומסים של HTTP(S) כדי להעביר תעבורה למיקרו-שירותים של חזית האתר והבק-אנד, ותשתמשו במיפויים כדי לשלוח תעבורה לשירותי הבק-אנד המתאימים על סמך כללי ניתוב. כך תהיה לכם כתובת IP אחת עם איזון עומסים לכל השירותים.

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

יצירת איזון עומסים ב-HTTP(S)

ב-Google Cloud יש הרבה סוגים שונים של איזון עומסים, אבל אתם תשתמשו באיזון עומסים של HTTP(S) לתנועה שלכם. המבנה של איזון עומסים ב-HTTP(S) הוא כזה:

  1. כלל העברה מפנה בקשות נכנסות אל שרת proxy HTTP של יעד.
  2. שרת ה-proxy של יעד ה-HTTP בודק כל בקשה מול מיפוי של כתובות URL כדי לקבוע את שירות ה-Backend המתאים לבקשה.
  3. שירות הקצה העורפי מפנה כל בקשה לקצה עורפי מתאים על סמך קיבולת הפרסום, האזור והתקינות של המופעים של הקצוות העורפיים שמצורפים אליו. התקינות של כל שרת עורפי (backend instance) מאומתת באמצעות בדיקת תקינות של HTTP. אם שירות לקצה העורפי מוגדר להשתמש בבדיקת תקינות של HTTPS או HTTP/2, הבקשה תוצפן בדרך לשרת העורפי (backend instance).
  4. בסשנים בין מאזן העומסים לבין המופע אפשר להשתמש בפרוטוקול HTTP,‏ HTTPS או HTTP/2. אם אתם משתמשים ב-HTTPS או ב-HTTP/2, לכל מופע בשירותי הקצה העורפי צריך להיות אישור SSL.

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

gcloud compute http-health-checks create fancy-fe-frontend-hc \
  --request-path / \
  --port 8080
gcloud compute http-health-checks create fancy-be-orders-hc \
  --request-path /api/orders \
  --port 8081
gcloud compute http-health-checks create fancy-be-products-hc \
  --request-path /api/products \
  --port 8082

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

gcloud compute backend-services create fancy-fe-frontend \
  --http-health-checks fancy-fe-frontend-hc \
  --port-name frontend \
  --global
gcloud compute backend-services create fancy-be-orders \
  --http-health-checks fancy-be-orders-hc \
  --port-name orders \
  --global
gcloud compute backend-services create fancy-be-products \
  --http-health-checks fancy-be-products-hc \
  --port-name products \
  --global

מוסיפים את שירותי ה-Backend.

gcloud compute backend-services add-backend fancy-fe-frontend \
  --instance-group fancy-fe-mig \
  --instance-group-zone us-central1-f \
  --global
gcloud compute backend-services add-backend fancy-be-orders \
  --instance-group fancy-be-mig \
  --instance-group-zone us-central1-f \
  --global
gcloud compute backend-services add-backend fancy-be-products \
  --instance-group fancy-be-mig \
  --instance-group-zone us-central1-f \
  --global

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

gcloud compute url-maps create fancy-map \
  --default-service fancy-fe-frontend

יוצרים התאמה של נתיבים כדי לאפשר לנתיבים ‎ /api/orders ו-‎ /api/products להפנות לשירותים המתאימים.

gcloud compute url-maps add-path-matcher fancy-map \
   --default-service fancy-fe-frontend \
   --path-matcher-name orders \
   --path-rules "/api/orders=fancy-be-orders,/api/products=fancy-be-products"

יוצרים את ה-proxy שמקושר למפת ה-URL שנוצרה.

gcloud compute target-http-proxies create fancy-proxy \
  --url-map fancy-map

יוצרים כלל העברה גלובלי שמקשר בין כתובת IP ציבורית ובין יציאה לשרת ה-proxy.

gcloud compute forwarding-rules create fancy-http-rule \
  --global \
  --target-http-proxy fancy-proxy \
  --ports 80

עדכון ההגדרות

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

ב-Cloud Shell, עוברים לתיקייה react-app, שבה נמצא הקובץ ‎ .env שמכיל את ההגדרות.

cd ~/monolith-to-microservices/react-app/

מאתרים את כתובת ה-IP של מאזן העומסים:

gcloud compute forwarding-rules list --global

פלט לדוגמה:

NAME                    REGION  IP_ADDRESS     IP_PROTOCOL  TARGET
fancy-http-rule          34.102.237.51  TCP          fancy-proxy

עורכים את קובץ ‎ .env באמצעות עורך הטקסט המועדף (למשל GNU nano) כדי להפנות לכתובת ה-IP הציבורית של מאזן העומסים. ‫[LB_IP] מייצג את כתובת ה-IP החיצונית של שרת עורפי (backend instance).

REACT_APP_ORDERS_URL=http://[LB_IP]/api/orders
REACT_APP_PRODUCTS_URL=http://[LB_IP]/api/products

בונים מחדש את react-app כדי לעדכן את קוד ה-frontend.

cd ~/monolith-to-microservices/react-app
npm install && npm run-script build

מעתיקים את קוד האפליקציה לדלי GCS.

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

עדכון המופעים של הקצה הקדמי

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

gcloud compute instance-groups managed rolling-action restart fancy-fe-mig \
    --max-unavailable 100%

בדיקת האתר

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

watch -n 5 gcloud compute instance-groups list-instances fancy-fe-mig

אחרי שהפריטים מופיעים ברשימה, יוצאים מהפקודה בשעון על ידי לחיצה על Control+C (Command+C ב-Macintosh).

מוודאים שהשירות מופיע כפעיל.

watch -n 5 gcloud compute backend-services get-health fancy-fe-frontend --global

פלט לדוגמה:

---
backend: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instanceGroups/fancy-fe-mig
status:
  healthStatus:
  - healthState: HEALTHY
    instance: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instances/fancy-fe-x151
    ipAddress: 10.128.0.7
    port: 8080
  - healthState: HEALTHY
    instance: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instances/fancy-fe-cgrt
    ipAddress: 10.128.0.11
    port: 8080
  kind: compute#backendServiceGroupHealth

אחרי שהפריטים מופיעים ברשימה, יוצאים מהפקודה watch על ידי הקשה על Control+C (Command+C ב-Macintosh).

לאחר מכן תהיה לאפליקציה גישה דרך http://[LB_IP], כאשר [LB_IP] הוא ה-IP_ADDRESS שצוין עבור איזון העומסים, שאפשר למצוא אותו באמצעות הפקודה הבאה:

gcloud compute forwarding-rules list --global

7. שינוי קנה מידה ב-Compute Engine

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

שינוי גודל אוטומטי לפי ניצול

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

gcloud compute instance-groups managed set-autoscaling \
  fancy-fe-mig \
  --max-num-replicas 5 \
  --target-load-balancing-utilization 0.60
gcloud compute instance-groups managed set-autoscaling \
  fancy-be-mig \
  --max-num-replicas 5 \
  --target-load-balancing-utilization 0.60

הפעלת רשת להעברת תוכן

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

gcloud compute backend-services update fancy-fe-frontend \
    --enable-cdn --global

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

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

8. עדכון האתר

עדכון של תבנית של הגדרות מכונה

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

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

תשנו את סוג המכונה של תבנית של הגדרות מכונה על ידי מעבר ממכונה לשימוש סטנדרטי (standard) f1-micro לסוג מכונה בהתאמה אישית עם 4 vCPU ו-3840MiB RAM.

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

gcloud compute instances set-machine-type frontend --machine-type custom-4-3840

יוצרים את תבנית המופע החדשה:

gcloud compute instance-templates create fancy-fe-new \
    --source-instance=frontend \
    --source-instance-zone=us-central1-a

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

gcloud compute instance-groups managed rolling-action start-update fancy-fe-mig \
    --version template=fancy-fe-new

עוקבים אחרי סטטוס העדכון:

watch -n 2 gcloud compute instance-groups managed list-instances fancy-fe-mig

אחרי שיש יותר ממופע אחד בסטטוס RUNNING,עם ACTION שמוגדר כ-None, ועם INSTANCE_TEMPLATE שמוגדר כשם התבנית החדש (fancy-fe-new), מעתיקים את השם של אחת מהמכונות שמופיעות ברשימה לשימוש בפקודה הבאה.

‫Control+S (Command+S ב-Macintosh) כדי לצאת מתהליך הצפייה.

מריצים את הפקודה הבאה כדי לראות אם המכונה הווירטואלית משתמשת בסוג המכונה החדש (custom-4-3840), כאשר [VM_NAME] הוא המופע שנוצר לאחרונה:

gcloud compute instances describe [VM_NAME] | grep machineType

פלט לדוגמה:

machineType: https://www.googleapis.com/compute/v1/projects/project-name/zones/us-central1-f/machineTypes/custom-4-3840

ביצוע שינויים באתר

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

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

cd ~/monolith-to-microservices/react-app/src/pages/Home
mv index.js.new index.js
cat ~/monolith-to-microservices/react-app/src/pages/Home/index.js

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

/*
Copyright 2019 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Paper from "@material-ui/core/Paper";
import Typography from "@material-ui/core/Typography";
const useStyles = makeStyles(theme => ({
  root: {
    flexGrow: 1
  },
  paper: {
    width: "800px",
    margin: "0 auto",
    padding: theme.spacing(3, 2)
  }
}));
export default function Home() {
  const classes = useStyles();
  return (
    <div className={classes.root}>
      <Paper className={classes.paper}>
        <Typography variant="h5">
          Fancy Fashion &amp; Style Online
        </Typography>
        <br />
        <Typography variant="body1">
          Tired of mainstream fashion ideas, popular trends and societal norms?
          This line of lifestyle products will help you catch up with the Fancy trend and express your personal style.
          Start shopping Fancy items now!
        </Typography>
      </Paper>
    </div>
  );
}

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

cd ~/monolith-to-microservices/react-app
npm install && npm run-script build

לאחר מכן, מעבירים את הקוד שוב לקטגוריה שלכם ב-Cloud Storage.

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

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

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

gcloud compute instance-groups managed rolling-action restart fancy-fe-mig \
    --max-unavailable=100%

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

watch -n 5 gcloud compute instance-groups list-instances fancy-fe-mig

אחרי שהפריטים מופיעים ברשימה, יוצאים משורת הפקודה של השעון על ידי הקשה על Control+S (או על Command+S ב-Macintosh).

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

watch -n 5 gcloud compute backend-services get-health fancy-fe-frontend --global

פלט לדוגמה:

---
backend: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instanceGroups/fancy-fe-mig
status:
  healthStatus:
  - healthState: HEALTHY
    instance: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instances/fancy-fe-x151
    ipAddress: 10.128.0.7
    port: 8080
  - healthState: HEALTHY
    instance: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instances/fancy-fe-cgrt
    ipAddress: 10.128.0.11
    port: 8080
  kind: compute#backendServiceGroupHealth

אחרי שהפריטים מופיעים ברשימה, יוצאים מהפקודה בשעון על ידי לחיצה על Control+S (Command+S ב-Macintosh).

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

gcloud compute url-maps invalidate-cdn-cache fancy-map \
    --path "/*"

עוברים לאתר באמצעות http://[LB_IP] ‎, כאשר [LB_IP] ‎ הוא IP_ADDRESS שצוין עבור איזון העומסים, שאפשר למצוא באמצעות הפקודה הבאה:

gcloud compute forwarding-rules list --global

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

b081b8e885bf0723.png

סימולציה של כשל

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

gcloud compute instance-groups list-instances fancy-fe-mig

משם, מתחברים באמצעות Secure Shell לאחד מהמופעים, כאשר INSTANCE_NAME הוא אחד מהמופעים מהרשימה:

gcloud compute ssh [INSTANCE_NAME]

במופע, משתמשים ב-supervisorctl כדי לעצור את האפליקציה.

sudo supervisorctl stop nodeapp; sudo killall node

יוצאים מהמופע.

exit

לעקוב אחרי פעולות התיקון.

watch -n 5 gcloud compute operations list \
--filter='operationType~compute.instances.repair.*'

מחפשים פלט שדומה לדוגמה הבאה:

NAME                                                  TYPE                                       TARGET                                 HTTP_STATUS  STATUS  TIMESTAMP
repair-1568314034627-5925f90ee238d-fe645bf0-7becce15  compute.instances.repair.recreateInstance  us-central1-a/instances/fancy-fe-1vqq  200          DONE    2019-09-12T11:47:14.627-07:00

אחרי שרואים את התיקון, לוחצים על Control+C (Command+S ב-Macintosh) כדי לצאת מהפקודה של השעון. בשלב הזה, קבוצת מופעי מכונה מנוהלים יוצרת מחדש את המכונה כדי לתקן אותה.

9. הסרת המשאבים

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

gcloud projects delete [PROJECT_ID]

כשמוצגת בקשה לאישור המחיקה, מקלידים Y.

10. מעולה!

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