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

1. מבוא

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

מה תלמדו

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

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

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

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

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

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.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.png

Screen 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 instance) כדי שתוכלו להחיל עליה כללי חומת אש ספציפיים בהמשך:

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 החיצונית של חזית האתר. אפשר לקבוע את הכתובת על ידי חיפוש של EXTERNAL_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] היא כתובת ה-IP החיצונית שנקבעה למעלה.

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

a11460a1fffb07d8.png

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

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

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

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

כדי ליצור קבוצת מופעי מכונה מנוהלים, צריך קודם ליצור תבנית של הגדרות מכונה שתשמש כבסיס לקבוצה. תבניות של הגדרות מכונה מאפשרות להגדיר את סוג המכונה, את קובץ האימג' של דיסק האתחול או את קובץ האימג' של קונטיינר, את הרשת ומאפיינים אחרים של המכונה שבהם רוצים להשתמש כשיוצרים מופעים חדשים של מכונה וירטואלית (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

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

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

מדיניות של תיקון תוכנה אוטומטי (autohealing) מסתמכת על בדיקת תקינות מבוססת-אפליקציה כדי לוודא שהאפליקציה מגיבה כמצופה. בדיקה של תגובת האפליקציה מדויקת יותר מאשר אימות פשוט של מופע במצב 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 כדי לקבוע את שירות הקצה העורפי המתאים לבקשה.
  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 החיצונית של שרת עורפי.

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

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

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

כדי ליצור את מדיניות ההתאמה האוטומטית לעומס, מריצים את הפקודות הבאות ב-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,הפעולה מוגדרת כ-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 שצוינה עבור איזון העומסים, שאפשר למצוא באמצעות הפקודה הבאה:

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, בקבוצות של מופעי מכונה מנוהלים, באיזון עומסים ובבדיקות תקינות.