סדנה ל-Anthos Service Mesh: מדריך Lab

1. סדנת אלפא

קישור לסדנת ה-codelab bit.ly/asm-workshop

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

תרשים ארכיטקטורה

9a033157f44308f3.png

הסדנה הזו היא חוויה מעשית ואימרסיבית שבה נסביר איך להגדיר שירותים מבוזרים גלובלית ב-GCP בסביבת ייצור. הטכנולוגיות העיקריות שבהן נעשה שימוש הן Google Kubernetes Engine‏ (GKE) למחשוב ו-Istio service mesh ליצירת קישוריות מאובטחת, ניראות (observability) ועיצוב תנועה (Traffic Shaping) מתקדם. כל השיטות והכלים שבהם משתמשים בסדנה הזו הם אותם שיטות וכלים שבהם משתמשים בסביבת הייצור.

הנושאים לדיון

  • יחידת לימוד 0 – מבוא והגדרת הפלטפורמה
  • מבוא וארכיטקטורה
  • מבוא ל-Service Mesh ול-Istio/ASM
  • Lab: Infrastructure Setup: User workflow
  • הפסקה
  • QnA
  • מודול 1 – התקנה, אבטחה ומעקב של אפליקציות באמצעות ASM
  • מודל המאגר: הסבר על מאגרי תשתית ו-Kubernetes
  • שיעור Lab: פריסת אפליקציה לדוגמה
  • שירותים מבוזרים ויכולת צפייה
  • ארוחת צהריים
  • שיעור Lab: יכולת צפייה באמצעות Stackdriver
  • QNA
  • Module 2 - DevOps - Canary rollouts, policy/RBAC
  • זיהוי שירותים מרובי אשכולות ואבטחה/מדיניות
  • שיעור Lab: TLS דו-צדדי
  • פריסות של גרסה ראשונית (canary)
  • שיעור Lab: פריסות של גרסה ראשונית (canary)
  • איזון עומסים גלובלי מאובטח בין כמה אשכולות
  • הפסקה
  • שיעור Lab: מדיניות הרשאות
  • QNA
  • Module 3 - Infra Ops - Platform upgrades
  • אבני בניין של שירותים מבוזרים
  • שיעור Lab: Infrastructure Scaling
  • השלבים הבאים

Slides

השקפים של הסדנה הזו זמינים בקישור הבא:

שקפים של סדנת ASM

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

לפני שממשיכים בסדנה הזו, צריך:

  1. צומת של ארגון GCP
  2. מספר החשבון לחיוב (המשתמש צריך להיות אדמין לחיוב בחשבון לחיוב הזה)
  3. תפקיד אדמין ארגוני ב-IAM ברמת הארגון עבור המשתמש

3. הגדרת התשתית – תהליך עבודה לאדמינים

הסבר על סקריפט של סדנת Bootstrap

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

הסקריפט של סדנת ה-bootstrap דורש את הקלט הבא:

  • שם הארגון (לדוגמה yourcompany.com) – זהו הארגון שבו אתם יוצרים סביבות לסדנה.
  • מספר לקוח לחיוב (לדוגמה, 12345-12345-12345) – מספר לקוח לחיוב זה משמש לחיוב כל המשאבים שבהם נעשה שימוש במהלך הסדנה.
  • מספר הסדנה (לדוגמה 01) – מספר בן שתי ספרות. האפשרות הזו שימושית אם אתם מעבירים כמה סדנאות ביום אחד ורוצים לעקוב אחרי כל אחת מהן בנפרד. מספרי סדנאות משמשים גם כדי לגזור מזהי פרויקטים. מספרים נפרדים לסדנאות מקלים על קבלת מזהי פרויקטים ייחודיים בכל פעם. בנוסף למספר הסדנה, גם התאריך הנוכחי (בפורמט YYMMDD) משמש למזהי פרויקטים. השילוב של התאריך ומספר הסדנה מספק מזהי פרויקט ייחודיים.
  • נקודת הצירוף של המשתמש (לדוגמה 1) – המספר הזה מציין את המשתמש הראשון בסדנה. לדוגמה, אם רוצים ליצור סדנה ל-10 משתמשים, יכול להיות שמספר המשתמשים להתחלה יהיה 1 ומספר המשתמשים לסיום יהיה 10.
  • מספר משתמש הקצה (לדוגמה 10) – המספר הזה מציין את המשתמש האחרון בסדנה. לדוגמה, אם רוצים ליצור סדנה ל-10 משתמשים, יכול להיות שמספר המשתמשים להתחלה יהיה 1 ומספר המשתמשים לסיום יהיה 10. אם אתם מגדירים סביבה אחת (למשל, לעצמכם), צריך להזין את אותו מספר משתמש גם בשדה של מספר המשתמש להתחלה וגם בשדה של מספר המשתמש לסיום. כך נוצר סביבה אחת.
  • מאגר GCS של האדמין (לדוגמה, my-gcs-bucket-name) – מאגר GCS משמש לאחסון מידע שקשור לסדנה. המידע הזה משמש את הסקריפט cleanup_workshop.sh כדי למחוק בצורה מסודרת את כל המשאבים שנוצרו במהלך הסקריפט של סדנת האתחול. לאדמינים שיוצרים סדנאות צריכות להיות הרשאות קריאה וכתיבה לקטגוריה הזו.

סקריפט הסדנה של Bootstrap משתמש בערכים שצוינו למעלה ופועל כסקריפט wrapper שקורא לסקריפט setup-terraform-admin-project.sh. הסקריפט setup-terraform-admin-project.sh יוצר את סביבת הסדנה למשתמש יחיד.

נדרשות הרשאות אדמין כדי להפעיל את הסדנה

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

כדי להשתמש ב-ADMIN_USER, נדרשות ההרשאות הבאות ברמת הארגון:

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

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

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

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

  • user<3 digit user number>@<organization_name>

לדוגמה, אם מריצים את סקריפט הסדנה של bootstrap עם מספר משתמש התחלה 1 ומספר משתמש סיום 3, בארגון שנקרא yourcompany.com, סביבות הסדנה עבור המשתמשים הבאים נוצרות:

  • user001@yourcompany.com
  • user002@yourcompany.com
  • user003@yourcompany.com

לשמות המשתמש האלה מוקצים תפקידי בעלים בפרויקטים הספציפיים שנוצרו במהלך הפעלת הסקריפט setup_terraform_admin_project.sh. כשמשתמשים בסקריפט bootstrap, צריך לפעול לפי סכימת שמות המשתמשים הזו. כך מוסיפים כמה משתמשים בבת אחת ב-G Suite.

כלים שנדרשים לסדנה

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

  • gcloud (גרסה >= 270)
  • kubectl
  • sed (פועל עם sed ב-Cloud Shell/Linux ולא ב-Mac OS)
  • git (חשוב לוודא שהגרסה עדכנית)
  • sudo apt update
  • sudo apt install git
  • jq
  • envsubst
  • kustomize

הגדרת סדנה לעצמכם (הגדרה למשתמש יחיד)

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

Cloud Shell

  1. מוודאים שנכנסתם ל-gcloud עם משתמש האדמין הרצוי.
gcloud config list
 
  1. יוצרים WORKDIR ומשכפלים את מאגר הסדנה.
mkdir asm-workshop
cd asm-workshop
export WORKDIR=`pwd`
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git asm
 
  1. מגדירים את שם הארגון, את מספר הלקוח לחיוב, את מספר הסדנה ואת דליקת GCS של האדמין שבה רוצים להשתמש בסדנה. בקטעים שלמעלה מפורטות ההרשאות שנדרשות להגדרת הסדנה.
gcloud organizations list
export ORGANIZATION_NAME=<ORGANIZATION NAME>

gcloud beta billing accounts list
export ADMIN_BILLING_ID=<ADMIN_BILLING ID>

export WORKSHOP_NUMBER=<two digit number for example 01>

export ADMIN_STORAGE_BUCKET=<ADMIN CLOUD STORAGE BUCKET>
 
  1. מריצים את הסקריפט bootstrap_workshop.sh. יכול להיות שיחלפו כמה דקות עד שהסקריפט יסיים את הפעולה.
cd asm
./scripts/bootstrap_workshop.sh --org-name ${ORGANIZATION_NAME} --billing-id ${ADMIN_BILLING_ID} --workshop-num ${WORKSHOP_NUMBER} --admin-gcs-bucket ${ADMIN_STORAGE_BUCKET} --set-up-for-admin 
 

אחרי שהסקריפט bootstrap_workshop.sh מסתיים, נוצר תיקייה ב-GCP לכל משתמש בארגון. בתוך התיקייה נוצר פרויקט אדמין של Terraform. פרויקט האדמין של Terraform משמש ליצירת שאר המשאבים ב-GCP שנדרשים לסדנה הזו. מפעילים את ממשקי ה-API הנדרשים בפרויקט האדמין של Terraform. משתמשים ב-Cloud Build כדי להחיל תוכניות של Terraform. מקצים לחשבון השירות של Cloud Build תפקידי IAM מתאימים כדי שיוכל ליצור משאבים ב-GCP. לבסוף, מגדירים קצה עורפי מרוחק בקטגוריה של Google Cloud Storage ‏ (GCS) כדי לאחסן מצבים של Terraform לכל המשאבים ב-GCP.

כדי לראות את המשימות של Cloud Build בפרויקט האדמין של Terraform, צריך את מזהה פרויקט האדמין של Terraform. הוא מאוחסן בקובץ vars/vars.sh בספרייה asm. הספרייה הזו נשמרת רק אם אתם מגדירים את הסדנה בעצמכם כאדמינים.

  1. הפעלת קובץ המשתנים כדי להגדיר משתני סביבה
echo "export WORKDIR=$WORKDIR" >> $WORKDIR/asm/vars/vars.sh
source $WORKDIR/asm/vars/vars.sh 
 

הגדרת סדנה למספר משתמשים (הגדרה למספר משתמשים)

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

Cloud Shell

  1. מוודאים שנכנסתם ל-gcloud עם משתמש האדמין הרצוי.
gcloud config list
 
  1. יוצרים WORKDIR ומשכפלים את מאגר הסדנה.
mkdir asm-workshop
cd asm-workshop
export WORKDIR=`pwd`
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git asm
 
  1. מגדירים את שם הארגון, מספר לקוח לחיוב, מספר הסדנה, מספר משתמשי הקצה להתחלה ולסיום, ודלי GCS של אדמין לשימוש בסדנה. בקטעים שלמעלה מפורטות ההרשאות שנדרשות להגדרת הסדנה.
gcloud organizations list
export ORGANIZATION_NAME=<ORGANIZATION NAME>

gcloud beta billing accounts list
export ADMIN_BILLING_ID=<BILLING ID>

export WORKSHOP_NUMBER=<two digit number for example 01>

export START_USER_NUMBER=<number for example 1>

export END_USER_NUMBER=<number greater or equal to START_USER_NUM>

export ADMIN_STORAGE_BUCKET=<ADMIN CLOUD STORAGE BUCKET>
 
  1. מריצים את הסקריפט bootstrap_workshop.sh. יכול להיות שיחלפו כמה דקות עד שהסקריפט יסיים את הפעולה.
cd asm
./scripts/bootstrap_workshop.sh --org-name ${ORGANIZATION_NAME} --billing-id ${ADMIN_BILLING_ID} --workshop-num ${WORKSHOP_NUMBER} --start-user-num ${START_USER_NUMBER} --end-user-num ${END_USER_NUMBER} --admin-gcs-bucket ${ADMIN_STORAGE_BUCKET}
 
  1. מאחזרים את מזהי פרויקט Terraform ממאגר GCS של האדמין, בקובץ workshop.txt.
export WORKSHOP_ID="$(date '+%y%m%d')-${WORKSHOP_NUMBER}"
gsutil cp gs://${ADMIN_STORAGE_BUCKET}/${ORGANIZATION_NAME}/${WORKSHOP_ID}/workshop.txt .
 

4. הגדרת מעבדה והכנה

בחירת מסלול ה-Lab

אפשר לבצע את שיעורי ה-Lab בסדנה הזו באחת משתי דרכים:

  • הדרך של תסריטים אינטראקטיביים קלים ומהירים
  • הדרך של העתקה והדבקה ידנית של כל הוראה

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

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

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

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

הגדרה מהירה של סקריפט

קבלת פרטי משתמש

הסדנה הזו מתבצעת באמצעות חשבון משתמש זמני (או חשבון מעבדה) שנוצר על ידי האדמין של הסדנה. כל הפרויקטים בסדנה הם בבעלות של חשבון Lab. האדמין של הסדנה מספק למשתמש שמבצע את הסדנה את פרטי הכניסה לחשבון המעבדה (שם משתמש וסיסמה). לכל הפרויקטים של המשתמש יש קידומת של שם המשתמש בחשבון המעבדה. לדוגמה, בחשבון המעבדה user001@yourcompany.com, מזהה פרויקט האדמין של Terraform יהיה user001-200131-01-tf-abcde וכן הלאה לגבי שאר הפרויקטים. כל משתמש צריך להתחבר באמצעות חשבון המעבדה שסופק על ידי האדמין של הסדנה, ולבצע את הסדנה באמצעות חשבון המעבדה.

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

Cloud Shell

  1. מתחברים באמצעות פרטי הכניסה לחשבון המעבדה (לא מתחברים באמצעות החשבון הארגוני או חשבון לשימוש אישי). חשבון ה-Lab נראה כך: userXYZ@<workshop_domain>.com. 3101eca1fd3722bf.png
  2. מכיוון שזה חשבון חדש, תתבקשו לאשר את התנאים של Google. לוחצים על 'אישור'.

fb0219a89ece5168.png 4. במסך הבא, מסמנים את תיבת הסימון כדי לאשר את התנאים של Google ולוחצים על Start Cloud Shell.

7b198cf2e32cb457.png

בשלב הזה מוקצה לכם מכונה וירטואלית קטנה של Linux Debian, שתוכלו להשתמש בה כדי לגשת למשאבים של GCP. כל חשבון מקבל מכונה וירטואלית של Cloud Shell. כניסה באמצעות חשבון ה-Lab מספקת לכם את פרטי הכניסה לחשבון ה-Lab ומאפשרת לכם להיכנס לחשבון. בנוסף ל-Cloud Shell, מוקצה גם עורך קוד, שמקל על עריכת קובצי תצורה (terraform,‏ YAML וכו'). כברירת מחדל, המסך של Cloud Shell מחולק לסביבת מעטפת של Cloud Shell (בחלק התחתון) ול-Cloud Code Editor (בחלק העליון). 5643bb4ebeafd00a.png הסמל של העיפרון 8bca25ef1421c17e.pngוהסמל של שורת הפקודה eaeb4ac333783ba8.png בפינה השמאלית העליונה מאפשרים לעבור בין שתי האפשרויות (שורת פקודה ועורך קוד). אפשר גם לגרור את פס ההפרדה האמצעי (למעלה או למטה) ולשנות את הגודל של כל חלון באופן ידני. 5. יוצרים WORKDIR לסדנה הזו. ה-WORKDIR הוא תיקייה שממנה מבצעים את כל שיעורי ה-Lab בסדנה הזו. מריצים את הפקודות הבאות ב-Cloud Shell כדי ליצור את WORKDIR.

mkdir -p ${HOME}/asm-workshop
cd ${HOME}/asm-workshop
export WORKDIR=`pwd` 
 
  1. מייצאים את המשתמש בחשבון המעבדה כמשתנה לשימוש בסדנה הזו. זה אותו חשבון שדרכו נכנסתם אל Cloud Shell.
export MY_USER=<LAB ACCOUNT EMAIL PROVIDED BY THE WORKSHOP ADMIN>
# For example export MY_USER=user001@gcpworkshops.com 
 
  1. מריצים את הפקודות הבאות כדי להציג את המשתנים WORKDIR ו-MY_USER ולוודא שהם מוגדרים בצורה נכונה.
echo "WORKDIR set to ${WORKDIR}" && echo "MY_USER set to ${MY_USER}"
 
  1. משכפלים את מאגר הסדנה.
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git ${WORKDIR}/asm
 

5. הגדרת התשתית – תהליך עבודה של משתמש

מטרה: אימות התשתית וההתקנה של Istio

  • התקנת כלי עבודה
  • שכפול מאגר הסדנה
  • אימות ההתקנה של Infrastructure
  • אימות ההתקנה של k8s-repo
  • אימות ההתקנה של Istio

הוראות לשימוש ב-Labs בשיטת העתקה והדבקה

קבלת פרטי משתמש

האדמין שמגדיר את הסדנה צריך לספק למשתמש את שם המשתמש והסיסמה. לכל הפרויקטים של המשתמש יתווסף קידומת של שם המשתמש. לדוגמה, עבור המשתמש user001@yourcompany.com, מזהה פרויקט האדמין של Terraform יהיה user001-200131-01-tf-abcde, וכן הלאה לגבי שאר הפרויקטים. לכל משתמש יש גישה רק לסביבת הסדנה שלו.

כלים שנדרשים לסדנה

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

  • gcloud (גרסה >= 270)
  • kubectl
  • sed (פועל עם sed ב-Cloud Shell/Linux ולא ב-Mac OS)
  • git (חשוב לוודא שהגרסה עדכנית)
  • sudo apt update
  • sudo apt install git
  • jq
  • envsubst
  • kustomize
  • pv

גישה לפרויקט אדמין של Terraform

אחרי שהסקריפט bootstrap_workshop.sh מסתיים, נוצר תיקייה ב-GCP לכל משתמש בארגון. בתוך התיקייה נוצר פרויקט אדמין של Terraform. פרויקט האדמין של Terraform משמש ליצירת שאר המשאבים ב-GCP שנדרשים לסדנה הזו. הסקריפט setup-terraform-admin-project.sh מפעיל את ממשקי ה-API הנדרשים בפרויקט האדמין של Terraform. משתמשים ב-Cloud Build כדי להחיל תוכניות של Terraform. באמצעות הסקריפט, מקצים לחשבון השירות של Cloud Build תפקידי IAM מתאימים כדי שיוכל ליצור משאבים ב-GCP. לבסוף, מוגדר קצה עורפי מרוחק בקטגוריה של Google Cloud Storage ‏ (GCS) כדי לאחסן מצבים של Terraform לכל המשאבים ב-GCP.

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

  1. פותחים את Cloud Shell (אם הוא לא פתוח כבר מהקטע Lab Setup and Prep) על ידי לחיצה על הקישור שלמטה.

Cloud Shell

  1. מתקינים את kustomize (אם הוא עדיין לא מותקן) בתיקייה $HOME/bin ומוסיפים את התיקייה $HOME/bin ל-$PATH.
mkdir -p $HOME/bin
cd $HOME/bin
curl -s "https://raw.githubusercontent.com/\
kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"  | bash
cd $HOME
export PATH=$PATH:${HOME}/bin
echo "export PATH=$PATH:$HOME/bin" >> $HOME/.bashrc
 
  1. מתקינים את pv ומעבירים אותו אל $HOME/bin/pv.
sudo apt-get update && sudo apt-get -y install pv
sudo mv /usr/bin/pv ${HOME}/bin/pv
 
  1. מעדכנים את שורת הפקודה של bash.
cp $WORKDIR/asm/scripts/krompt.bash $HOME/.krompt.bash
echo "export PATH=\$PATH:\$HOME/bin" >> $HOME/.asm-workshop.bash
echo "source $HOME/.krompt.bash" >> $HOME/.asm-workshop.bash

alias asm-init='source $HOME/.asm-workshop.bash' >> $HOME/.bashrc
echo "source $HOME/.asm-workshop.bash" >> $HOME/.bashrc
source $HOME/.bashrc
 
  1. מוודאים שאתם מחוברים ל-gcloud באמצעות חשבון המשתמש הרצוי.
echo "Check logged in user output from the next command is $MY_USER"
gcloud config list account --format=json | jq -r .core.account
 
  1. מריצים את הפקודה הבאה כדי לקבל את מזהה פרויקט האדמין של Terraform:
export TF_ADMIN=$(gcloud projects list | grep tf- | awk '{ print $1 }')
echo $TF_ADMIN
 
  1. כל המשאבים שמשויכים לסדנה מאוחסנים כמשתנים בקובץ vars.sh שמאוחסן בקטגוריה של GCS בפרויקט האדמין של Terraform. מקבלים את הקובץ vars.sh עבור פרויקט האדמין של Terraform.
mkdir $WORKDIR/asm/vars
gsutil cp gs://$TF_ADMIN/vars/vars.sh $WORKDIR/asm/vars/vars.sh
echo "export WORKDIR=$WORKDIR" >> $WORKDIR/asm/vars/vars.sh
 
  1. לוחצים על הקישור שמוצג כדי לפתוח את הדף Cloud Build של פרויקט האדמין של Terraform ומוודאים שה-Build הושלם בהצלחה.
source $WORKDIR/asm/vars/vars.sh
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_ADMIN}"
 

אם זו הפעם הראשונה שאתם נכנסים למסוף Cloud, אתם צריכים לאשר את התנאים של Google.

  1. בדף Cloud Build, לוחצים על הקישור History בתפריט הניווט הימני ואז על הגרסה האחרונה של ה-build כדי לראות את הפרטים של הפקודה הראשונית Terraform apply. המשאבים הבאים נוצרים כחלק מסקריפט Terraform. אפשר גם לעיין בתרשים הארכיטקטורה שלמעלה.
  • 4 פרויקטים ב-GCP בארגון. החשבון לחיוב שצוין משויך לכל פרויקט.
  • פרויקט אחד הוא network host project של ה-VPC המשותף. לא נוצרו משאבים אחרים בפרויקט הזה.
  • פרויקט אחד הוא ops project שמשמש לאשכולות GKE של מישור הבקרה של Istio.
  • שני פרויקטים מייצגים שני צוותי פיתוח שונים שעובדים על השירותים שלהם.
  • שני אשכולות GKE נוצרים בכל אחד משלושת הפרויקטים ops, dev1 ו-dev2.
  • מאגר CSR בשם k8s-repo נוצר ומכיל שש תיקיות של קובצי מניפסט של Kubernetes. תיקייה אחת לכל אשכול GKE. המאגר הזה משמש לפריסת מניפסטים של Kubernetes באשכולות בשיטת GitOps.
  • נוצר טריגר לפיתוח גרסת Build של Cloud Build כך שבכל פעם שיש קומיט לענף הראשי של k8s-repo, הוא פורס את מניפסטי Kubernetes לאשכולות GKE מהתיקיות המתאימות שלהם.
  1. אחרי שה-build מסתיים ב-terraform admin project, יתחיל build נוסף בפרויקט התפעול. לוחצים על הקישור שמוצג כדי לפתוח את הדף Cloud Build של ops project ומוודאים ש-k8s-repo Cloud Build הסתיים בהצלחה.
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
 

אימות התקנה

  1. יוצרים קובצי kubeconfig לכל האשכולות. מריצים את הסקריפט הבא.
$WORKDIR/asm/scripts/setup-gke-vars-kubeconfig.sh
 

הסקריפט הזה יוצר קובץ kubeconfig חדש בתיקייה gke בשם kubemesh.

  1. משנים את המשתנה KUBECONFIG כך שיצביע על קובץ ה-kubeconfig החדש.
source $WORKDIR/asm/vars/vars.sh
export KUBECONFIG=$WORKDIR/asm/gke/kubemesh
 
  1. מוסיפים את vars.sh ואת המשתנה KUBECONFIG ל-‎ .bashrc ב-Cloud Shell כדי שהם יסופקו בכל הפעלה מחדש של Cloud Shell.
echo "source ${WORKDIR}/asm/vars/vars.sh" >> $HOME/.bashrc
echo "export KUBECONFIG=${WORKDIR}/asm/gke/kubemesh" >> $HOME/.bashrc
 
  1. מציינים את ההקשרים של האשכולות. אמורים להופיע שישה אוספים.
kubectl config view -ojson | jq -r '.clusters[].name'
 
    `Output (do not copy)`
gke_tf05-01-ops_us-central1_gke-asm-2-r2-prod
gke_tf05-01-ops_us-west1_gke-asm-1-r1-prod
gke_tf05-02-dev1_us-west1-a_gke-1-apps-r1a-prod
gke_tf05-02-dev1_us-west1-b_gke-2-apps-r1b-prod
gke_tf05-03-dev2_us-central1-a_gke-3-apps-r2a-prod
gke_tf05-03-dev2_us-central1-b_gke-4-apps-r2b-prod

אימות ההתקנה של Istio

  1. כדי לוודא ש-Istio מותקן בשני האשכולות, בודקים שכל הפודים פועלים ושהעבודות הושלמו.
kubectl --context ${OPS_GKE_1} get pods -n istio-system
kubectl --context ${OPS_GKE_2} get pods -n istio-system
 
    `Output (do not copy)`
NAME                                      READY   STATUS    RESTARTS   AGE
grafana-5f798469fd-z9f98                  1/1     Running   0          6m21s
istio-citadel-568747d88-qdw64             1/1     Running   0          6m26s
istio-egressgateway-8f454cf58-ckw7n       1/1     Running   0          6m25s
istio-galley-6b9495645d-m996v             2/2     Running   0          6m25s
istio-ingressgateway-5df799fdbd-8nqhj     1/1     Running   0          2m57s
istio-pilot-67fd786f65-nwmcb              2/2     Running   0          6m24s
istio-policy-74cf89cb66-4wrpl             2/2     Running   1          6m25s
istio-sidecar-injector-759bf6b4bc-mw4vf   1/1     Running   0          6m25s
istio-telemetry-77b6dfb4ff-zqxzz          2/2     Running   1          6m24s
istio-tracing-cd67ddf8-n4d7k              1/1     Running   0          6m25s
istiocoredns-5f7546c6f4-g7b5c             2/2     Running   0          6m39s
kiali-7964898d8c-5twln                    1/1     Running   0          6m23s
prometheus-586d4445c7-xhn8d               1/1     Running   0          6m25s
    `Output (do not copy)`
NAME                                      READY   STATUS    RESTARTS   AGE
grafana-5f798469fd-2s8k4                  1/1     Running   0          59m
istio-citadel-568747d88-87kdj             1/1     Running   0          59m
istio-egressgateway-8f454cf58-zj9fs       1/1     Running   0          60m
istio-galley-6b9495645d-qfdr6             2/2     Running   0          59m
istio-ingressgateway-5df799fdbd-2c9rc     1/1     Running   0          60m
istio-pilot-67fd786f65-nzhx4              2/2     Running   0          59m
istio-policy-74cf89cb66-4bc7f             2/2     Running   3          59m
istio-sidecar-injector-759bf6b4bc-grk24   1/1     Running   0          59m
istio-telemetry-77b6dfb4ff-6zr94          2/2     Running   4          60m
istio-tracing-cd67ddf8-grs9g              1/1     Running   0          60m
istiocoredns-5f7546c6f4-gxd66             2/2     Running   0          60m
kiali-7964898d8c-nhn52                    1/1     Running   0          59m
prometheus-586d4445c7-xr44v               1/1     Running   0          59m
  1. מוודאים ש-Istio מותקן בשני אשכולי dev1. רק Citadel, ‏ sidecar-injector ו-coredns פועלים באשכולות dev1. הם חולקים מישור בקרה של Istio שפועל באשכול ops-1.
kubectl --context ${DEV1_GKE_1} get pods -n istio-system
kubectl --context ${DEV1_GKE_2} get pods -n istio-system
 
  1. מוודאים ש-Istio מותקן בשני אשכולי dev2. רק Citadel, ‏ sidecar-injector ו-coredns פועלים באשכולות dev2. הם חולקים את מישור הבקרה של Istio שפועל באשכול ops-2.
kubectl --context ${DEV2_GKE_1} get pods -n istio-system
kubectl --context ${DEV2_GKE_2} get pods -n istio-system
 
    `Output (do not copy)`
NAME                                      READY   STATUS    RESTARTS   AGE
istio-citadel-568747d88-4lj9b             1/1     Running   0          66s
istio-sidecar-injector-759bf6b4bc-ks5br   1/1     Running   0          66s
istiocoredns-5f7546c6f4-qbsqm             2/2     Running   0          78s

אימות של גילוי שירותים עבור מישורי בקרה משותפים

  1. אופציונלי: מאמתים שהסודות נפרסו.
kubectl --context ${OPS_GKE_1} get secrets -l istio/multiCluster=true -n istio-system
kubectl --context ${OPS_GKE_2} get secrets -l istio/multiCluster=true -n istio-system
 
    `Output (do not copy)`
For OPS_GKE_1:
NAME                  TYPE     DATA   AGE
gke-1-apps-r1a-prod   Opaque   1      8m7s
gke-2-apps-r1b-prod   Opaque   1      8m7s
gke-3-apps-r2a-prod   Opaque   1      44s
gke-4-apps-r2b-prod   Opaque   1      43s

For OPS_GKE_2:
NAME                  TYPE     DATA   AGE
gke-1-apps-r1a-prod   Opaque   1      40s
gke-2-apps-r1b-prod   Opaque   1      40s
gke-3-apps-r2a-prod   Opaque   1      8m4s
gke-4-apps-r2b-prod   Opaque   1      8m4s

בסדנה הזו, תשתמשו ב-VPC משותף יחיד שבו ייצרו כל אשכולות GKE. כדי לגלות שירותים בכל האשכולות, משתמשים בקובצי kubeconfig (לכל אחד מאשכולות האפליקציות) שנוצרו כסודות באשכולות התפעול. ‫Pilot משתמש בסודות האלה כדי לגלות שירותים על ידי שליחת שאילתות לשרת Kube API של אשכולות האפליקציות (מאומת באמצעות הסודות שלמעלה). אפשר לראות ששני אשכולי ה-Ops יכולים לבצע אימות לכל אשכולי האפליקציות באמצעות סודות שנוצרו על ידי kubeconfig. אשכולות Ops יכולים לגלות שירותים באופן אוטומטי באמצעות קובצי kubeconfig כשיטה סודית. כדי לעשות את זה, ל-Pilot באשכולות של ה-ops צריכה להיות גישה לשרת Kube API של כל שאר האשכולות. אם Pilot לא יכול להגיע לשרתים של Kube API, צריך להוסיף שירותים מרוחקים באופן ידני כ-ServiceEntries. אפשר לחשוב על ServiceEntries כרשומות DNS במאגר רשומות השירות. רשומות ServiceEntry מגדירות שירות באמצעות שם DNS שמוגדר במלואו ( FQDN) וכתובת IP שאפשר להגיע אליה. מידע נוסף זמין במסמכי התיעוד בנושא Istio Multicluster.

6. הסבר על מאגר התשתית

Infrastructure Cloud Build

המשאבים של GCP לסדנה נוצרו באמצעות Cloud Build וinfrastructure מאגר CSR. הרצת כרגע סקריפט bootstrap (שנמצא בכתובת scripts/bootstrap_workshop.sh) מהטרמינל המקומי. סקריפט האתחול יוצר תיקייה ב-GCP, פרויקט אדמין של Terraform והרשאות IAM מתאימות עבור חשבון השירות של Cloud Build. פרויקט האדמין של Terraform משמש לאחסון מצבים, יומנים וסקריפטים שונים של Terraform. הוא מכיל את מאגרי ה-CSR של infrastructure ושל k8s_repo. המאגרים האלה מוסברים בפירוט בקטע הבא. אין משאבים אחרים לסדנה שנבנים בפרויקט הניהול של Terraform. חשבון השירות של Cloud Build בפרויקט האדמין של Terraform משמש ליצירת משאבים לסדנה.

קובץ cloudbuild.yaml שנמצא בתיקייה infrastructure משמש ליצירת משאבי GCP לסדנה. הוא יוצר קובץ אימג' של builder בהתאמה אישית עם כל הכלים שנדרשים ליצירת משאבי GCP. הכלים האלה כוללים את gcloud SDK, ‏ Terraform וכלי עזר אחרים כמו python, ‏ git, ‏ jq וכו'. תמונת ה-Builder המותאמת אישית מפעילה את terraform plan ואת apply לכל משאב. קבצי ה-Terraform של כל משאב נמצאים בתיקיות נפרדות (פרטים בקטע הבא). המשאבים נוצרים אחד אחרי השני, לפי הסדר שבו הם בדרך כלל נוצרים (לדוגמה, פרויקט ב-GCP נוצר לפני שהמשאבים נוצרים בתוך הפרויקט). פרטים נוספים מופיעים בקובץ cloudbuild.yaml.

‫Cloud Build מופעל בכל פעם שמתבצעת פעולת commit במאגר infrastructure. כל שינוי שמתבצע בתשתית מאוחסן כתשתית כקוד (IaC) ונשמר במאגר. המצב של הסדנה תמיד מאוחסן במאגר הזה.

מבנה התיקיות – צוותים, סביבות ומשאבים

מאגר התשתית מגדיר את משאבי התשתית של GCP לסדנה. הוא בנוי מתיקיות ותיקיות משנה. תיקיות הבסיס במאגר מייצגות את team שבבעלותן משאבי GCP ספציפיים. השכבה הבאה של התיקיות מייצגת את environment הספציפיים של הצוות (לדוגמה: dev, ‏ stage, ‏ prod). השכבה הבאה של תיקיות בסביבה מייצגת את resource הספציפי (לדוגמה host_project, ‏ gke_clusters וכו'). הסקריפטים וקובצי ה-Terraform הנדרשים נמצאים בתיקיות המשאבים.

434fc1769bb49b8c.png

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

  1. infrastructure – מייצג את צוות תשתית הענן. הם אחראים ליצירת משאבי GCP לכל שאר הצוותים. הם משתמשים בפרויקט הניהול של Terraform למשאבים שלהם. מאגר התשתית עצמו נמצא בפרויקט האדמין של Terraform, וגם קובצי המצב של Terraform (מוסבר בהמשך). המשאבים האלה נוצרים על ידי סקריפט bash במהלך תהליך האתחול (פרטים נוספים זמינים במודול 0 – תהליך העבודה של האדמין).
  2. network – מייצג את צוות הרשת. הם אחראים למשאבי VPC ורשת. הם הבעלים של משאבי GCP הבאים.
  3. host project – מייצג את הפרויקט המארח של ה-VPC המשותף.
  4. shared VPC – מייצג את ה-VPC המשותף, רשתות המשנה, טווחי כתובות ה-IP המשניים, המסלולים וכללי חומת האש.
  5. ops – מייצג את צוות התפעול או צוות ה-DevOps. הם הבעלים של המשאבים הבאים.
  6. ops project – מייצג פרויקט לכל משאבי ה-Ops.
  7. gke clusters – אשכול GKE לכל אזור. מישור הבקרה של Istio מותקן בכל אחד מאשכולות ה-GKE של פעולות ה-Ops.
  8. k8s-repo – מאגר CSR שמכיל מניפסטים של GKE לכל אשכולות GKE.
  9. apps – מייצג את צוותי האפליקציות. בסדנה הזו נדמה שתי קבוצות, app1 ו-app2. הם הבעלים של המשאבים הבאים.
  10. app projects – לכל צוות אפליקציות יש קבוצה משלו של פרויקטים. כך הם יכולים לשלוט בחיוב וב-IAM של הפרויקט הספציפי שלהם.
  11. gke clusters – אלה אשכולות של אפליקציות שבהם פועלים קונטיינרים או קבוצות Pod של אפליקציות.
  12. gce instances – אופציונלי, אם יש להם אפליקציות שפועלות במופעי GCE. בסדנה הזו, לאפליקציה app1 יש כמה מופעי GCE שבהם פועל חלק מהאפליקציה.

בסדנה הזו, אותה אפליקציה (Hipster shop app) מייצגת גם את app1 וגם את app2.

ספק, מצבים ותוצאות – קצה עורפי ומצבים משותפים

הספקים google ו-google-beta נמצאים בgcp/[environment]/gcp/provider.tf. הקובץ provider.tf הוא symlinked בכל תיקיית משאבים. כך תוכלו לשנות את הספק במקום אחד, במקום לנהל כל ספק בנפרד לכל משאב.

כל משאב מכיל קובץ backend.tf שמגדיר את המיקום של קובץ tfstate של המשאב. הקובץ backend.tf נוצר מתבנית (שנמצאת במיקום templates/backend.tf_tmpl) באמצעות סקריפט (שנמצא במיקום scripts/setup_terraform_admin_project), ואז הוא ממוקם בתיקיית המשאבים המתאימה. קטגוריות של Google Cloud Storage ‏ (GCS) משמשות כבק-אנד. שם התיקייה בקטגוריית GCS זהה לשם המשאב. כל קצוות העורף של המשאבים נמצאים בפרויקט האדמין של Terraform.

משאבים עם ערכים שתלויים זה בזה מכילים קובץ output.tf. ערכי הפלט הנדרשים מאוחסנים בקובץ tfstate שהוגדר ב-backend עבור המשאב הספציפי הזה. לדוגמה, כדי ליצור אשכול GKE בפרויקט, צריך לדעת את מזהה הפרויקט. מזהה הפרויקט מופיע כפלט דרך output.tf בקובץ tfstate שאפשר להשתמש בו דרך מקור נתונים terraform_remote_state במשאב של אשכול GKE.

קובץ shared_state הוא terraform_remote_state מקור נתונים שמפנה לקובץ tfstate של משאב. קובץ (או קבצים) shared_state_[resource_name].tf קיים בתיקיות המשאבים שנדרשים להם פלטים ממשאבים אחרים. לדוגמה, בתיקיית המשאבים ops_gke יש קבצים של shared_state ממשאבי ops_project ו-shared_vpc, כי צריך את מזהה הפרויקט ואת פרטי ה-VPC כדי ליצור אשכולות GKE בפרויקט התפעול. הקבצים shared_state נוצרים מתבנית (שנמצאת בכתובת templates/shared_state.tf_tmpl) באמצעות סקריפט (שנמצא בכתובת scripts/setup_terraform_admin_project). כל הקבצים shared_state של המשאבים ממוקמים בתיקייה gcp/[environment]/shared_states. קבצי shared_state הנדרשים הם קישורי סמלים בתיקיות המשאבים המתאימות. אם מכניסים את כל קובצי shared_state לתיקייה אחת ומקשרים אותם באמצעות קישור סמלי לתיקיות המשאבים המתאימות, קל לנהל את כל קובצי המצב במקום אחד.

משתנים

כל ערכי המשאבים מאוחסנים כמשתני סביבה. המשתנים האלה מאוחסנים (כמשפטי ייצוא) בקובץ שנקרא vars.sh שנמצא בקטגוריה של GCS בפרויקט האדמין של Terraform. הקובץ הזה מכיל את מזהה הארגון, החשבון לחיוב, מזהי הפרויקטים, פרטים על אשכול GKE וכו'. אפשר להוריד את הקובץ vars.sh מכל טרמינל כדי לקבל את הערכים להגדרה.

משתני Terraform מאוחסנים ב-vars.sh כ-TF_VAR_[variable name]. המשתנים האלה משמשים ליצירת קובץ variables.tfvars בתיקיית המשאבים המתאימה. קובץ variables.tfvars מכיל את כל המשתנים עם הערכים שלהם. קובץ variables.tfvars נוצר מקובץ תבנית באותה תיקייה באמצעות סקריפט (שנמצא במיקום scripts/setup_terraform_admin_project).

הסבר על מאגר K8s

k8s_repo הוא מאגר CSR (נפרד ממאגר התשתית) שנמצא בפרויקט הניהול של Terraform. הוא משמש לאחסון מניפסטים של GKE ולהחלתם על כל אשכולות GKE. ‫k8s_repo נוצר על ידי Cloud Build של התשתית (פרטים בקטע הקודם). במהלך תהליך Cloud Build הראשוני של התשתית, נוצרים שישה אשכולות GKE בסך הכול. בתיקייה k8s_repo נוצרות שש תיקיות. כל תיקייה (השם שלה זהה לשם אשכול GKE) תואמת לאשכול GKE שמכיל את קובצי המניפסט של המשאבים הרלוונטיים. בדומה לבניית תשתית, Cloud Build משמש להחלת מניפסטים של Kubernetes על כל אשכולות GKE באמצעות k8s_repo. הפעלת Cloud Build מתבצעת בכל פעם שיש קומיט למאגר k8s_repo. בדומה לתשתית, כל המניפסטים של Kubernetes מאוחסנים כקוד במאגר k8s_repo, והמצב של כל אשכול GKE מאוחסן תמיד בתיקייה המתאימה.

במסגרת בניית התשתית הראשונית, נוצר k8s_repo ו-Istio מותקן בכל האשכולות.

פרויקטים, אשכולות GKE ומרחבי שמות

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

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

  1. צוות התשתית שיוצר משאבי GCP משתמש ב-Terraform admin project. הם מנהלים את התשתית כקוד במאגר CSR (שנקרא infrastructure) ומאחסנים את כל נתוני המצב של Terraform שקשורים למשאבים שנבנו ב-GCP בדלי GCS. הם שולטים בגישה למאגר ה-CSR ולמאגרי ה-GCS של מצב Terraform.
  2. צוות הרשת שבונה את ה-VPC המשותף משתמש ב-host project. הפרויקט הזה מכיל את ה-VPC, רשתות המשנה, המסלולים וכללי חומת האש. השימוש ב-VPC משותף מאפשר להם לנהל באופן מרכזי את הרשתות של משאבי GCP. כל הפרויקטים השתמשו באותו VPC משותף לצורך יצירת רשתות.
  3. צוות התפעול או צוות הפלטפורמה שבונה אשכולות GKE ומישורי בקרה של ASM/Istio משתמש ב-ops project. הם מנהלים את מחזור החיים של אשכולות GKE ושל Service mesh. הם אחראים להקשחת האשכולות ולניהול החוסן וההתאמה לעומס של פלטפורמת Kubernetes. בסדנה הזו תשתמשו בשיטת ה-GitOps לפריסת משאבים ב-Kubernetes. מאגר CSR (שנקרא k8s_repo) קיים בפרויקט התפעול.
  4. לבסוף, צוות dev1 וצוות dev2 (שמייצגים שני צוותי פיתוח) שיוצרים אפליקציות משתמשים ב-dev1 וב-dev2 projects משלהם. אלה האפליקציות והשירותים שאתם מספקים ללקוחות שלכם. הם נבנים על הפלטפורמה שמנוהלת על ידי צוות ה-Ops. המשאבים (פריסות, שירותים וכו') נדחפים אל k8s_repo ונפרסים באשכולות המתאימים. חשוב לציין שהסדנה הזו לא מתמקדת בשיטות מומלצות ובכלים של CI/CD. אתם משתמשים ב-Cloud Build כדי להפוך את הפריסה של משאבי Kubernetes לאשכולות GKE לאוטומטית. בתרחישי ייצור בעולם האמיתי, צריך להשתמש בפתרון CI/CD מתאים כדי לפרוס אפליקציות לאשכולות GKE.

בסדנה הזו יש שני סוגים של אשכולות GKE.

  1. אשכולות של פעולות – משמשים את צוות הפעולות להפעלת כלי DevOps. בסדנה הזו, הם מפעילים את מישור הבקרה של ASM/Istio כדי לנהל את Service mesh.
  2. אשכולות של אפליקציות – משמשים את צוותי הפיתוח להרצת אפליקציות. בסדנה הזו נעשה שימוש באפליקציית Hipster shop.

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

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

האפליקציה שבה נעשה שימוש בסדנה הזו, אפליקציית Hipster Shop, נפרסת בכל ארבעת אשכולות האפליקציות. כל מיקרו-שירות נמצא במרחב שמות משלו בכל אשכול אפליקציות. פריסות (Pods) של אפליקציות בחנות היפסטרים לא נפרסות באשכולות של פעולות. עם זאת, מרחבי השמות ומשאבי השירות לכל המיקרו-שירותים נוצרים גם באשכולות של פעולות. רמת הבקרה של ASM/Istio משתמשת במרשמי השירותים של Kubernetes עבור זיהוי שירותים. אם אין שירותים (באשכולות התפעול), תצטרכו ליצור ידנית ServiceEntry לכל שירות שפועל באשכול האפליקציות.

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

מניפסטים של Kubernetes ו-k8s_repo

משתמשים ב-k8s_repo כדי להוסיף משאבי Kubernetes לכל אשכולות GKE. כדי לעשות את זה, מעתיקים את מניפסטים של Kubernetes ומבצעים קומיט ל-k8s_repo. כל פעולת קומיט אל k8s_repo מפעילה משימה ב-Cloud Build שמבצעת פריסה של מניפסטים של Kubernetes לאשכול המתאים. המניפסט של כל אשכול נמצא בתיקייה נפרדת שנקראת באותו שם כמו שם האשכול.

ששת השמות של האשכולות הם:

  1. gke-asm-1-r1-prod – אשכול הפעולות האזורי באזור 1
  2. gke-asm-2-r2-prod – אשכול הפעולות האזורי באזור 2
  3. gke-1-apps-r1a-prod – אשכול האפליקציות באזור 1, אזור a
  4. gke-2-apps-r1b-prod – אשכול האפליקציות באזור 1, אזור b
  5. gke-3-apps-r2a-prod – אשכול האפליקציות באזור 2, אזור a
  6. gke-4-apps-r2b-prod – אשכול האפליקציות באזור 2, אזור b

ב-k8s_repo יש תיקיות שמתאימות לאשכולות האלה. כל קובץ מניפסט שמוצב בתיקיות האלה מוחל על אשכול GKE המתאים. קובצי המניפסט של כל אשכול ממוקמים בתיקיות משנה (בתוך התיקייה הראשית של האשכול) כדי להקל על הניהול. בסדנה הזו תשתמשו ב-Kustomize כדי לעקוב אחרי המשאבים שנפרסים. פרטים נוספים מופיעים במסמכי התיעוד הרשמיים של Kustomize.

7. פריסת האפליקציה לדוגמה

יעד: פריסת אפליקציית Hipster shop באשכולות של אפליקציות

  • שכפול של k8s-repo
  • העתקת מניפסטים של חנות Hipster לכל אשכולות האפליקציות
  • יצירת שירותים לאפליקציית Hipster shop באשכולות של פעולות
  • הגדרה של loadgenerators באשכולות של פעולות כדי לבדוק קישוריות גלובלית
  • אימות קישוריות מאובטחת לאפליקציית החנות Hipster

הוראות לשימוש ב-Labs בשיטת העתקה והדבקה

שכפול מאגר המקור של פרויקט ה-Ops

במסגרת בניית התשתית הראשונית של Terraform, ה-k8s-repo כבר נוצר בפרויקט התפעול.

  1. יוצרים ספרייה ריקה למאגר git:
mkdir $WORKDIR/k8s-repo
 
  1. מאתחלים מאגר Git, מוסיפים מאגר מרוחק ומושכים את הענף הראשי מהמאגר המרוחק:
cd $WORKDIR/k8s-repo
git init && git remote add origin \
https://source.developers.google.com/p/$TF_VAR_ops_project_name/r/k8s-repo
 
  1. הגדרת תצורה מקומית של git.
git config --local user.email $MY_USER
git config --local user.name "K8s repo user"
git config --local \
credential.'https://source.developers.google.com'.helper gcloud.sh
git pull origin master

העתקה של קובצי מניפסט, ביצוע commit ודחיפה

  1. מעתיקים את מרחבי השמות והשירותים של Hipster Shop למאגר המקור לכל האשכולות.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/.

cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/.
 
  1. מעתיקים את הקובץ kustomization.yaml של תיקיית האפליקציה לכל האשכולות.
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/
 
  1. מעתיקים את Hipster Shop Deployments, ‏ RBAC ו-PodSecurityPolicy למאגר המקור של אשכולות האפליקציות.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/

cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/
  1. מסירים את הפריסה של cartservice, את rbac ואת podsecuritypolicy מכל מקבצי הפיתוח, למעט אחד. האפליקציה Hipstershop לא נועדה לפריסה בכמה אשכולות, ולכן כדי למנוע תוצאות לא עקביות, אנחנו משתמשים רק ב-cartservice אחד.
rm $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/deployments/app-cart-service.yaml
rm $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/podsecuritypolicies/cart-psp.yaml
rm $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/rbac/cart-rbac.yaml

rm $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/deployments/app-cart-service.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/podsecuritypolicies/cart-psp.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/rbac/cart-rbac.yaml

rm $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/deployments/app-cart-service.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/podsecuritypolicies/cart-psp.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/rbac/cart-rbac.yaml
 
  1. מוסיפים את הפריסה של cartservice, ‏ rbac ו-podsecuritypolicy אל kustomization.yaml רק באשכול הפיתוח הראשון.
cd ${WORKDIR}/k8s-repo/${DEV1_GKE_1_CLUSTER}/app
cd deployments && kustomize edit add resource app-cart-service.yaml
cd ../podsecuritypolicies && kustomize edit add resource cart-psp.yaml
cd ../rbac && kustomize edit add resource cart-rbac.yaml
cd ${WORKDIR}/asm
 
  1. מסירים את podsecuritypolicies, ‏ deployments ו-rbac directories מהקובץ kustomization.yaml של אשכולות ops.
sed -i -e '/- deployments\//d' -e '/- podsecuritypolicies\//d' \
  -e '/- rbac\//d' \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/kustomization.yaml
sed -i -e '/- deployments\//d' -e '/- podsecuritypolicies\//d' \
  -e '/- rbac\//d' \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/kustomization.yaml
  1. מחליפים את PROJECT_ID במניפסטים של RBAC.
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev1_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV1_GKE_1_CLUSTER}/app/rbac/*
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev1_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV1_GKE_2_CLUSTER}/app/rbac/*
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev2_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV2_GKE_1_CLUSTER}/app/rbac/*
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev2_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV2_GKE_2_CLUSTER}/app/rbac/*
  
  1. מעתיקים את המניפסטים של IngressGateway ו-VirtualService למאגר המקור של אשכולות ה-Ops.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-ingress/* \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-ingress/
cp -r $WORKDIR/asm/k8s_manifests/prod/app-ingress/* \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-ingress/
 
  1. מעתיקים את המשאבים של Config Connector לאחד מהאשכולות בכל פרויקט.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-cnrm/* \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-cnrm/
cp -r $WORKDIR/asm/k8s_manifests/prod/app-cnrm/* \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app-cnrm/
cp -r $WORKDIR/asm/k8s_manifests/prod/app-cnrm/* \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app-cnrm/
 
  1. מחליפים את PROJECT_ID במניפסטים של Config Connector.
sed -i 's/${PROJECT_ID}/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-cnrm/*
sed -i 's/${PROJECT_ID}/'$TF_VAR_dev1_project_name'/g' \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app-cnrm/*
sed -i 's/${PROJECT_ID}/'$TF_VAR_dev2_project_name'/g' \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app-cnrm/*
 
  1. מעתיקים את מניפסטים loadgenerator (Deployment, ‏ PodSecurityPolicy ו-RBAC) לאשכולות התפעול. אפליקציית Hipster shop נחשפת באמצעות מאזן עומסים גלובלי (GCLB) של Google Cloud. שירות GCLB מקבל תעבורת נתונים מלקוחות (שמיועדת ל-frontend) ושולח אותה למופע הקרוב ביותר של השירות. הצבת loadgenerator בשני אשכולי ה-Ops תבטיח שהתנועה תישלח לשני שערים של Istio Ingress שפועלים באשכולי ה-Ops. הסבר מפורט על איזון עומסים מופיע בקטע הבא.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-loadgenerator/. \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-loadgenerator/. \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/. 
 
  1. מחליפים את מזהה פרויקט ה-Ops במניפסטים של שני אשכולי ה-Ops.loadgenerator
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g'  \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/loadgenerator-deployment.yaml
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/loadgenerator-rbac.yaml
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/loadgenerator-deployment.yaml
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/loadgenerator-rbac.yaml
 

  1. מוסיפים את משאבי loadgenerator לקובץ kustomization.yaml בשני אשכולי ה-ops.
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/
kustomize edit add resource loadgenerator-psp.yaml
kustomize edit add resource loadgenerator-rbac.yaml
kustomize edit add resource loadgenerator-deployment.yaml

cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/
kustomize edit add resource loadgenerator-psp.yaml
kustomize edit add resource loadgenerator-rbac.yaml
kustomize edit add resource loadgenerator-deployment.yaml
 

  1. התחייבות ל-k8s-repo.
cd $WORKDIR/k8s-repo
git add . && git commit -am "create app namespaces and install hipster shop"
git push --set-upstream origin master 
 
  1. אפשר לראות את הסטטוס של פרויקט ה-Ops ב-Cloud Build בכרטיסייה שנפתחה קודם או בלחיצה על הקישור הבא:
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
  

אימות פריסת האפליקציה

  1. מוודאים שכל הפודים בכל מרחבי השמות של האפליקציות, מלבד עגלת הקניות, נמצאים במצב Running בכל אשכולי הפיתוח.
for ns in ad checkout currency email frontend payment product-catalog recommendation shipping; do
  kubectl --context $DEV1_GKE_1 get pods -n $ns;
  kubectl --context $DEV1_GKE_2 get pods -n $ns;
  kubectl --context $DEV2_GKE_1 get pods -n $ns;
  kubectl --context $DEV2_GKE_2 get pods -n $ns;
done;
 

Output (do not copy)

NAME                               READY   STATUS    RESTARTS   AGE
currencyservice-5c5b8876db-pvc6s   2/2     Running   0          13m
NAME                               READY   STATUS    RESTARTS   AGE
currencyservice-5c5b8876db-xlkl9   2/2     Running   0          13m
NAME                               READY   STATUS    RESTARTS   AGE
currencyservice-5c5b8876db-zdjkg   2/2     Running   0          115s
NAME                               READY   STATUS    RESTARTS   AGE
currencyservice-5c5b8876db-l748q   2/2     Running   0          82s

NAME                            READY   STATUS    RESTARTS   AGE
emailservice-588467b8c8-gk92n   2/2     Running   0          13m
NAME                            READY   STATUS    RESTARTS   AGE
emailservice-588467b8c8-rvzk9   2/2     Running   0          13m
NAME                            READY   STATUS    RESTARTS   AGE
emailservice-588467b8c8-mt925   2/2     Running   0          117s
NAME                            READY   STATUS    RESTARTS   AGE
emailservice-588467b8c8-klqn7   2/2     Running   0          84s

NAME                        READY   STATUS    RESTARTS   AGE
frontend-64b94cf46f-kkq7d   2/2     Running   0          13m
NAME                        READY   STATUS    RESTARTS   AGE
frontend-64b94cf46f-lwskf   2/2     Running   0          13m
NAME                        READY   STATUS    RESTARTS   AGE
frontend-64b94cf46f-zz7xs   2/2     Running   0          118s
NAME                        READY   STATUS    RESTARTS   AGE
frontend-64b94cf46f-2vtw5   2/2     Running   0          85s

NAME                              READY   STATUS    RESTARTS   AGE
paymentservice-777f6c74f8-df8ml   2/2     Running   0          13m
NAME                              READY   STATUS    RESTARTS   AGE
paymentservice-777f6c74f8-bdcvg   2/2     Running   0          13m
NAME                              READY   STATUS    RESTARTS   AGE
paymentservice-777f6c74f8-jqf28   2/2     Running   0          117s
NAME                              READY   STATUS    RESTARTS   AGE
paymentservice-777f6c74f8-95x2m   2/2     Running   0          86s

NAME                                     READY   STATUS    RESTARTS   AGE
productcatalogservice-786dc84f84-q5g9p   2/2     Running   0          13m
NAME                                     READY   STATUS    RESTARTS   AGE
productcatalogservice-786dc84f84-n6lp8   2/2     Running   0          13m
NAME                                     READY   STATUS    RESTARTS   AGE
productcatalogservice-786dc84f84-gf9xl   2/2     Running   0          119s
NAME                                     READY   STATUS    RESTARTS   AGE
productcatalogservice-786dc84f84-v7cbr   2/2     Running   0          86s

NAME                                     READY   STATUS    RESTARTS   AGE
recommendationservice-5fdf959f6b-2ltrk   2/2     Running   0          13m
NAME                                     READY   STATUS    RESTARTS   AGE
recommendationservice-5fdf959f6b-dqd55   2/2     Running   0          13m
NAME                                     READY   STATUS    RESTARTS   AGE
recommendationservice-5fdf959f6b-jghcl   2/2     Running   0          119s
NAME                                     READY   STATUS    RESTARTS   AGE
recommendationservice-5fdf959f6b-kkspz   2/2     Running   0          87s

NAME                              READY   STATUS    RESTARTS   AGE
shippingservice-7bd5f569d-qqd9n   2/2     Running   0          13m
NAME                              READY   STATUS    RESTARTS   AGE
shippingservice-7bd5f569d-xczg5   2/2     Running   0          13m
NAME                              READY   STATUS    RESTARTS   AGE
shippingservice-7bd5f569d-wfgfr   2/2     Running   0          2m
NAME                              READY   STATUS    RESTARTS   AGE
shippingservice-7bd5f569d-r6t8v   2/2     Running   0          88s
  1. מוודאים שה-pods במרחב השמות של העגלה נמצאים במצב Running רק באשכול הפיתוח הראשון.
kubectl --context $DEV1_GKE_1 get pods -n cart;
 

Output (do not copy)

NAME                           READY   STATUS    RESTARTS   AGE
cartservice-659c9749b4-vqnrd   2/2     Running   0          17m

גישה לאפליקציית Hipster Shop

איזון עומסים גלובלי

עכשיו אפליקציית Hipster Shop פרוסה בכל ארבעת אשכולות האפליקציות. האשכולות האלה נמצאים בשני אזורים ובארבעה תחומים. לקוחות יכולים לגשת לאפליקציית החנות של Hipster דרך השירות frontend. שירות frontend פועל בכל ארבעת אשכולות האפליקציות. מאזן עומסים של Google Cloud‏ ( GCLB) משמש להעברת תעבורת לקוחות לכל ארבעת המופעים של שירות frontend.

שערי כניסה של Istio פועלים רק באשכולות התפעול ומשמשים כמאזן עומסים אזורי לשני אשכולות האפליקציות של התחום באזור. שירות GCLB משתמש בשני שערים של Istio (שפועלים בשני אשכולות של פעולות) כשרתי קצה עורפיים לשירות הקצה הקדמי הגלובלי. שערי ה-Ingress של Istio מקבלים את תנועת הלקוחות מ-GCLB ואז שולחים את תנועת הלקוחות הלאה אל ה-Pods של הקצה הקדמי שפועלים באשכולות האפליקציות.

4c618df35cb928ee.png

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

GKE Autoneg controller

שירות Kubernetes של שער Istio Ingress נרשם כקצה עורפי ב-GCLB באמצעות קבוצות של נקודות קצה ברשת (NEGs). קבוצות NEG מאפשרות איזון עומסים שמקורם בקונטיינר באמצעות GCLB. קבוצות NEG נוצרות באמצעות הערה מיוחדת בשירות Kubernetes, כדי שהן יוכלו להירשם ב-NEG Controller. ‫Autoneg הוא בקר GKE מיוחד שמבצע אוטומציה של יצירת NEGs וגם של הקצאתם כבקאנד ל-GCLB באמצעות הערות שירות. מישורי הבקרה של Istio, כולל שערים של Istio לכניסת תנועה, נפרסים במהלך בניית התשתית הראשונית של Terraform Cloud. ההגדרה של GCLB ושל autoneg מתבצעת כחלק מהתשתית הראשונית של Terraform Cloud Build.

אבטחת Ingress באמצעות Cloud Endpoints ואישורים מנוהלים

אישורים מנוהלים ב-GCP משמשים לאבטחת תעבורת הלקוח לשירות frontend GCLB. ‫GCLB משתמש באישור מנוהל בשביל שירות frontend גלובלי, והאישור מסתיים ב-GCLB. בסדנה הזו תשתמשו ב-Cloud Endpoints כדומיין של האישור המנוהל. אפשרות אחרת היא להשתמש בדומיין ובשם DNS של frontend כדי ליצור אישורים מנוהלים ב-GCP.

  1. כדי לגשת לחנות Hipster, לוחצים על פלט הקישור של הפקודה הבאה.
echo "https://frontend.endpoints.$TF_VAR_ops_project_name.cloud.goog" 
 
  1. כדי לוודא שהאישור תקף, לוחצים על סמל הנעילה בסרגל כתובות ה-URL בכרטיסיית Chrome.

6c403a63caa06c84.png

אימות של איזון עומסים גלובלי

כחלק מפריסת האפליקציה, מחוללי עומסים נפרסו בשני אשכולות התפעול, והם מייצרים תנועת גולשים לבדיקה לקישור של Cloud Endpoints בחנות Hipster ב-GCLB. מוודאים ש-GCLB מקבל תנועה ושולח אותה לשני שערים של Istio Ingress.

  1. מקבלים את הקישור GCLB > Monitoring לפרויקט התפעול שבו נוצר GCLB של חנות Hipster.
echo "https://console.cloud.google.com/net-services/loadbalancing/details/http/istio-ingressgateway?project=$TF_VAR_ops_project_name&cloudshell=false&tab=monitoring&duration=PT1H" 
 
  1. משנים את האפשרות מ-All backends (כל ה-backends) ל-istio-ingressgateway בתפריט הנפתח Backend, כמו שמוצג בהמשך.

6697c9eb67998d27.png

  1. שימו לב לתנועה שמגיעה לשני המיקומים istio-ingressgateways.

ff8126e44cfd7f5e.png

נוצרים שלושה NEGs לכל istio-ingressgateway. מכיוון שאשכולות ה-ops הם אשכולות אזוריים, נוצר NEG אחד לכל אזור באזור. לעומת זאת, תרמילי istio-ingressgateway פועלים בתחום אחד לכל אזור. התנועה מוצגת כשהיא מגיעה אל istio-ingressgateway Pods.

מחוללי העומסים פועלים בשני אשכולות של פעולות, ומדמים תעבורת לקוחות משני האזורים שבהם הם נמצאים. העומס שנוצר באזור 1 של אשכול הפעולות נשלח אל istio-ingressgateway באזור 2. באופן דומה, העומס שנוצר באזור 2 של אשכול הפעולות נשלח אל istio-ingressgateway באזור 2.

8. ניראות (observability) באמצעות Stackdriver

המטרה: חיבור טלמטריה של Istio ל-Stackdriver ואימות.

  • התקנת משאבים istio-telemetry
  • יצירה או עדכון של לוחות בקרה של שירותי Istio
  • צפייה ביומני מאגרים
  • צפייה במעקב מבוזר ב-Stackdriver

הוראות לשימוש ב-Labs בשיטת העתקה והדבקה

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

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

  1. מתקינים את קובץ התצורה של istio ל-Stackdriver.
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/istio-telemetry
kustomize edit add resource istio-telemetry.yaml

cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/istio-telemetry
kustomize edit add resource istio-telemetry.yaml
 
  1. ביצוע Commit למאגר k8s.
cd $WORKDIR/k8s-repo
git add . && git commit -am "Install istio to stackdriver configuration"
git push 
 
  1. אפשר לראות את הסטטוס של פרויקט ה-Ops ב-Cloud Build בכרטיסייה שנפתחה קודם או בלחיצה על הקישור הבא:
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
 
  1. אימות השילוב של Istio ‏→ Stackdriver מקבלים את ה-CRD של Stackdriver Handler.
kubectl --context $OPS_GKE_1 get handler -n istio-system
 

הפלט צריך להציג handler בשם stackdriver:

NAME            AGE
kubernetesenv   12d
prometheus      12d
stackdriver     69s      # <== NEW!
  1. מוודאים שהייצוא של מדדי Istio אל Stackdriver פועל. לוחצים על הקישור שמופיע בפלט של הפקודה הזו:
echo "https://console.cloud.google.com/monitoring/metrics-explorer?cloudshell=false&project=$TF_VAR_ops_project_name"
 

תופיע בקשה ליצור Workspace חדש, שייקרא על שם פרויקט ה-Ops. פשוט לוחצים על אישור. אם מופיעה בקשה לעבור לממשק המשתמש החדש, פשוט סוגרים את תיבת הדו-שיח.

ב-Metrics Explorer, בקטע 'Find resource type and metric' (חיפוש סוג משאב ומדד), מקלידים istio כדי לראות שיש אפשרויות כמו 'Server Request Count' (מספר בקשות לשרת) בסוג המשאב 'Kubernetes Container' (מאגר Kubernetes). הנתונים האלה מראים שהמדדים זורמים מהרשת אל Stackdriver.

(כדי לראות את השורות שבהמשך, צריך לקבץ לפי התווית destination_service_name).

b9b59432ee68e695.png

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

עכשיו שהמדדים שלנו נמצאים במערכת Stackdriver APM, אנחנו רוצים דרך להציג אותם בצורה ויזואלית. בקטע הזה נתקין לוח בקרה מוכן מראש שמציג את שלושת המדדים מתוך ארבעת האותות המרכזיים: תנועה (בקשות לשנייה), זמן אחזור (במקרה הזה, האחוזון ה-99 וה-50) ושגיאות (בדוגמה הזו לא נכלל עומס).

פרוקסי Envoy של Istio מספק לנו כמה מדדים, אבל אלה מדדים טובים להתחיל איתם. (רשימה מלאה זמינה כאן). שימו לב שלכל מדד יש קבוצה של תוויות שאפשר להשתמש בהן לסינון, לצבירה וכו' (למשל: destination_service,‏ source_workload_namespace,‏ response_code,‏ istio_tcp_received_bytes_total וכו').

  1. עכשיו נוסיף את מרכז הבקרה עם המדדים המוכנים מראש. אנחנו נשתמש ישירות ב-Dashboard API. בדרך כלל לא עושים את זה על ידי יצירה ידנית של קריאות ל-API, אלא כחלק ממערכת אוטומטית, או על ידי בניית לוח הבקרה באופן ידני בממשק המשתמש האינטרנטי. כך נוכל להתחיל במהירות:
sed -i 's/OPS_PROJECT/'${TF_VAR_ops_project_name}'/g' \
$WORKDIR/asm/k8s_manifests/prod/app-telemetry/services-dashboard.json
OAUTH_TOKEN=$(gcloud auth application-default print-access-token)
curl -X POST -H "Authorization: Bearer $OAUTH_TOKEN" -H "Content-Type: application/json" \
https://monitoring.googleapis.com/v1/projects/$TF_VAR_ops_project_name/dashboards \
 -d @$WORKDIR/asm/k8s_manifests/prod/app-telemetry/services-dashboard.json
 
  1. כדי לראות את 'מרכז הבקרה של השירותים' שנוסף, עוברים לקישור הפלט שבהמשך.
echo "https://console.cloud.google.com/monitoring/dashboards/custom/servicesdash?cloudshell=false&project=$TF_VAR_ops_project_name"
 
 

יכולנו לערוך את לוח הבקרה במקום באמצעות חוויית המשתמש, אבל במקרה שלנו אנחנו רוצים להוסיף במהירות תרשים חדש באמצעות ה-API. כדי לעשות זאת, צריך לשלוף את הגרסה העדכנית של מרכז הבקרה, לבצע את העריכות ואז להעלות אותה בחזרה באמצעות שיטת ה-PATCH של HTTP.

  1. אפשר לקבל לוח בקרה קיים על ידי שליחת שאילתה ל-API של המעקב. מקבלים את לוח הבקרה הקיים שנוסף זה עתה:
curl -X GET -H "Authorization: Bearer $OAUTH_TOKEN" -H "Content-Type: application/json" \
https://monitoring.googleapis.com/v1/projects/$TF_VAR_ops_project_name/dashboards/servicesdash > /tmp/services-dashboard.json
 
  1. הוספת גרף חדש: (50th %ile latency): [ הפניית API] Now we can add a new widget to our מרכז בקרה in code. עמיתים יכולים לבדוק את השינוי הזה ולשמור אותו במערכת בקרת הגרסאות. זהו ווידג'ט שאפשר להוסיף כדי לראות את זמן האחזור של אחוזון 50 (זמן האחזור החציוני).

נסו לערוך את לוח הבקרה שקיבלתם, ולהוסיף לו בית חדש:

NEW_CHART=${WORKDIR}/asm/k8s_manifests/prod/app-telemetry/new-chart.json
jq --argjson newChart "$(<$NEW_CHART)" '.gridLayout.widgets += [$newChart]' /tmp/services-dashboard.json > /tmp/patched-services-dashboard.json
 
  1. עדכון לוח הבקרה של השירותים הקיימים:
curl -X PATCH -H "Authorization: Bearer $OAUTH_TOKEN" -H "Content-Type: application/json" \
https://monitoring.googleapis.com/v1/projects/$TF_VAR_ops_project_name/dashboards/servicesdash \
 -d @/tmp/patched-services-dashboard.json
 
  1. כדי לראות את מרכז הבקרה המעודכן, עוברים לקישור הפלט הבא:
echo "https://console.cloud.google.com/monitoring/dashboards/custom/servicesdash?cloudshell=false&project=$TF_VAR_ops_project_name"
 
  1. לנתח יומנים פשוטים.

‫Istio מספקת קבוצה של יומנים מובנים לכל תעבורת הנתונים ברשת, ומעלה אותם ל-Stackdriver Logging כדי לאפשר ניתוח של נתונים מאשכולות שונים בכלי אחד רב-עוצמה. היומנים כוללים הערות עם מטא-נתונים ברמת השירות, כמו האשכול, המאגר, האפליקציה, connection_id וכו'.

דוגמה לרשומה ביומן (במקרה הזה, accesslog של Envoy proxy) יכולה להיראות כך (אחרי חיתוך):

*** DO NOT PASTE *** 
 logName: "projects/PROJECTNAME-11932-01-ops/logs/server-tcp-accesslog-stackdriver.instance.istio-system" 
labels: {
  connection_id: "fbb46826-96fd-476c-ac98-68a9bd6e585d-1517191"   
  destination_app: "redis-cart"   
  destination_ip: "10.16.1.7"   
  destination_name: "redis-cart-6448dcbdcc-cj52v"   
  destination_namespace: "cart"   
  destination_owner: "kubernetes://apis/apps/v1/namespaces/cart/deployments/redis-cart"   
  destination_workload: "redis-cart"   
  source_ip: "10.16.2.8"   
  total_received_bytes: "539"   
  total_sent_bytes: "569" 
...  
 }

כאן אפשר לראות את היומנים:

echo "https://console.cloud.google.com/logs/viewer?cloudshell=false&project=$TF_VAR_ops_project_name"
 

כדי לראות את היומנים של מישור הבקרה של Istio, בוחרים באפשרות Resource (משאב) > Kubernetes Container (מאגר Kubernetes) ומחפשים את pilot —

6f93b2aec6c4f520.png

כאן אפשר לראות את מישור הבקרה של Istio דוחף את הגדרות ה-proxy ל-proxy של sidecar עבור כל שירות של אפליקציה לדוגמה. ‫CDS,‏ LDS ו-RDS מייצגים ממשקי API שונים של Envoy ( מידע נוסף).

בנוסף ליומנים של Istio, תוכלו למצוא באותו ממשק גם יומנים של קונטיינרים, יומנים של תשתית או יומנים של שירותי GCP אחרים. הנה כמה שאילתות לדוגמה ליומנים ב-GKE. בכלי לצפייה ביומנים אפשר גם ליצור מדדים מיומנים (לדוגמה: 'ספירה של כל שגיאה שתואמת למחרוזת מסוימת'), שאפשר להשתמש בהם בלוח בקרה או כחלק מהתראה. אפשר גם להזרים יומנים לכלים אחרים לניתוח, כמו BigQuery.

כמה דוגמאות למסננים לחנות היפסטרים:

resource.type="k8s_container" labels.destination_app="productcatalogservice"

resource.type="k8s_container" resource.labels.namespace_name="cart"

  1. כדאי לעיין במאמר בנושא מעקב מבוזר.

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

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

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

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

כאן אפשר למצוא את ה-Traces:

echo "https://console.cloud.google.com/traces/overview?cloudshell=false&project=$TF_VAR_ops_project_name"
 

דוגמה לצילום מסך של הכלי:

5ee238836dc9047f.png

9. אימות TLS בו-זמני (mTLS)

המטרה: קישוריות מאובטחת בין מיקרו-שירותים (אימות).

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

הוראות לשימוש ב-Labs בשיטת העתקה והדבקה

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

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

  1. בודקים את MeshPolicy באשכולות של פעולות. הערה: ‏mTLS PERMISSIVE מאפשר תנועה מוצפנת ותנועה שלא מוצפנת.
kubectl --context $OPS_GKE_1 get MeshPolicy -o json | jq '.items[].spec'
kubectl --context $OPS_GKE_2 get MeshPolicy -o json | jq '.items[].spec'
 
    `Output (do not copy)`
{
  "peers": [
    {
      "mtls": {
        "mode": "PERMISSIVE"
      }
    }
  ]
}

‫Istio מוגדר בכל האשכולות באמצעות Istio operator, שמשתמש במשאב המותאם אישית (CR) ‏IstioControlPlane. אנחנו נגדיר mTLS בכל האשכולות על ידי עדכון של IstioControlPlane CR ועדכון של k8s-repo. הגדרת global > mTLS > enabled: true ב-IstioControlPlane CR גורמת לשני השינויים הבאים במישור הבקרה של Istio:

  • ההגדרה MeshPolicy מופעלת כדי להפעיל mTLS בכל רשת ה-mesh לכל השירותים שפועלים בכל האשכולות.
  • נוצר כלל DestinationRule כדי לאפשר תעבורת נתונים מסוג ISTIO_MUTUAL בין שירותים שפועלים בכל האשכולות.
  1. נחיל תיקון kustomize על istioControlPlane CR כדי להפעיל mTLS ברמת האשכול. מעתיקים את התיקון לספרייה הרלוונטית לכל האשכולות ומוסיפים תיקון של Kustomize.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-replicated.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml

cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-replicated.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml

cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml

cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml

cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml

cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml
 
  1. ביצוע Commit למאגר k8s.
cd $WORKDIR/k8s-repo
git add . && git commit -am "turn mTLS on"
git push
 
  1. אפשר לראות את הסטטוס של פרויקט ה-Ops ב-Cloud Build בכרטיסייה שנפתחה קודם או בלחיצה על הקישור הבא:
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"

 

אימות mTLS

  1. בודקים שוב את MeshPolicy באשכולות של פעולות. הערה: mTLS כבר לא PERMISSIVE ויאפשר רק תנועה של mTLS.
kubectl --context $OPS_GKE_1 get MeshPolicy -o json | jq .items[].spec
kubectl --context $OPS_GKE_2 get MeshPolicy -o json | jq .items[].spec
 

פלט (אין להעתיק):

{
  "peers": [
    {
      "mtls": {}
    }
  ]
}
  1. מתארים את ה-DestinationRule שנוצר על ידי בקר האופרטור של Istio.
kubectl --context $OPS_GKE_1 get DestinationRule default -n istio-system -o json | jq '.spec'
kubectl --context $OPS_GKE_2 get DestinationRule default -n istio-system -o json | jq '.spec'

פלט (אין להעתיק):

{
    host: '*.local',
    trafficPolicy: {
      tls: {
        mode: ISTIO_MUTUAL
      }
   }
}

בנוסף, אפשר לראות ביומנים את המעבר מ-HTTP ל-HTTPS.

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

d92e0c88cd5b2132.png

כך אפשר לראות את המעבר בצורה ברורה:

ea3d0240fa6fed81.png

10. פריסות של גרסה ראשונית (canary)

המטרה: השקת גרסה חדשה של שירות הקצה הקדמי.

  • השקה של גרסה frontend-v2 (גרסת הייצור הבאה) של השירות באזור אחד
  • שימוש בDestinationRules ובVirtualServices כדי להפנות תנועה לfrontend-v2 בהדרגה
  • כדי לאמת את צינור עיבוד הנתונים של GitOps, בודקים סדרה של קומיטים ב-k8s-repo

הוראות לשימוש ב-Labs בשיטת העתקה והדבקה

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

בקטע הזה נסביר איך להשתמש ב-Cloud Build ובמדיניות התנועה של Istio כדי ליצור פריסה של גרסה ראשונית (canary) בסיסית לגרסה חדשה של שירות הקצה הקדמי.

קודם כל, נריץ את צינור ה-Canary באזור DEV1‏ (us-west1), ונשיק את חזית האתר v2 בשני האשכולות באזור הזה. בשלב השני, נריץ את צינור ה-Canary באזור DEV2 (us-central) ונפרוס את גרסה 2 בשני האשכולות באזור הזה. הפעלת צינור הנתונים באזורים לפי הסדר, לעומת הפעלה מקבילה בכל האזורים, עוזרת להימנע מהפסקות שירות גלובליות שנגרמות בגלל הגדרה שגויה או בגלל באגים באפליקציה v2 עצמה.

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

  1. ב-Cloud Shell, מגדירים כמה משתני סביבה כדי לפשט את הרצת שאר הפקודות.
CANARY_DIR="$WORKDIR/asm/k8s_manifests/prod/app-canary/"
K8S_REPO="$WORKDIR/k8s-repo"
 
  1. מריצים את הסקריפט repo_setup.sh כדי להעתיק את קובצי המניפסט של קו הבסיס אל k8s-repo.
$CANARY_DIR/repo-setup.sh 
 

המאניפסטים הבאים מועתקים:

  • פריסת frontend-v2
  • תיקון frontend-v1 (כדי לכלול את התווית v1 ותמונה עם נקודת קצה /version)
  • respy,‏ pod קטן שידפיס את חלוקת תגובות ה-HTTP ויעזור לנו להמחיש את פריסת הקנרי בזמן אמת.
  • Istio DestinationRule בקצה הקדמי – מפצל את שירות Kubernetes בקצה הקדמי לשתי קבוצות משנה, v1 ו-v2, על סמך תווית ה-Deployment 'version'
  • ‫Istio VirtualService של חזית האתר – מעביר 100% מהתנועה לחזית האתר בגרסה 1. הפעולה הזו מבטלת את התנהגות ברירת המחדל של Kubernetes Service, שבה 50% מכל התנועה האזורית של Dev1 נשלחת באופן מיידי לחלק הקדמי v2.
  1. אישור השינויים ב-k8s_repo:
cd $K8S_REPO 
git add . && git commit -am "frontend canary setup"
git push
 
  1. אפשר לראות את הסטטוס של פרויקט ה-Ops ב-Cloud Build בכרטיסייה שנפתחה קודם או בלחיצה על הקישור הבא:
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}" 
 
  1. עוברים אל Cloud Build במסוף של פרויקט OPS1. מחכים עד שצינור הנתונים של Cloud Build יסתיים, ואז מקבלים את ה-pods במרחב השמות של קצה קדמי בשני האשכולות DEV1. אתם אמורים לראות את הנתונים הבאים:
watch -n 1 kubectl --context $DEV1_GKE_1 get pods -n frontend 
 

Output (do not copy)

NAME                           READY   STATUS    RESTARTS   AGE
frontend-578b5c5db6-h9567      2/2     Running   0          59m
frontend-v2-54b74fc75b-fbxhc   2/2     Running   0          2m26s
respy-5f4664b5f6-ff22r         2/2     Running   0          2m26s

נשתמש ב-tmux כדי לפצל את חלון Cloud Shell ל-2 חלוניות:

  • בחלונית התחתונה תפעל הפקודה watch כדי לעקוב אחרי חלוקת תגובות ה-HTTP לשירות הקצה הקדמי.
  • בחלונית העליונה יפעל סקריפט צינור ה-Canary בפועל.
  1. מריצים את הפקודה כדי לפצל את חלון Cloud Shell ומריצים את הפקודה watch בחלונית התחתונה.
RESPY_POD=$(kubectl --context $DEV1_GKE_1 get pod \
-n frontend -l app=respy -o jsonpath='{..metadata.name}')
export TMUX_SESSION=$(tmux display-message -p '#S')
tmux split-window -d -t $TMUX_SESSION:0 -p33 \
-v "export KUBECONFIG=$WORKDIR/asm/gke/kubemesh; \
kubectl --context $DEV1_GKE_1 exec -n frontend -it \
$RESPY_POD -c respy /bin/sh -- -c 'watch -n 1 ./respy \
--u http://frontend:80/version --c 10 --n 500'; sleep 2"
 

פלט (אין להעתיק)

500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v1       | 100.0%            |
|          |                   |
+----------+-------------------+
  1. מריצים את צינור ה-Canary באזור Dev1. אנחנו מספקים סקריפט שמעדכן את אחוזי התנועה של frontend-v2 ב-VirtualService (מעדכן את המשקלים ל-20%, 50%, 80% ואז ל-100%). בין העדכונים, הסקריפט ממתין לסיום של צינור העברת הנתונים של Cloud Build. מריצים את סקריפט הפריסה של גרסה ראשונית (canary) לאזור Dev1. הערה: הפעלת הסקריפט הזה נמשכת כ-10 דקות.
K8S_REPO=$K8S_REPO CANARY_DIR=$CANARY_DIR \
OPS_DIR=$OPS_GKE_1_CLUSTER OPS_CONTEXT=$OPS_GKE_1 \
${CANARY_DIR}/auto-canary.sh
 

אפשר לראות את פיצול התנועה בזמן אמת בחלון התחתון שבו מריצים את הפקודה respy. לדוגמה, בסימן של 20%:

פלט (אין להעתיק)

500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v1       | 79.4%             |
|          |                   |
| v2       | 20.6%             |
|          |                   |
+----------+-------------------+
  1. אחרי שההשקה של Dev2 תושלם עבור frontend-v2, תופיע הודעת הצלחה בסוף הסקריפט:
     Output (do not copy) 
    
✅ 100% successfully deployed
🌈 frontend-v2 Canary Complete for gke-asm-1-r1-prod
  1. וכל התנועה מהקצה הקדמי של פוד Dev2 צריכה לעבור לקצה הקדמי – גרסה 2:
     Output (do not copy) 
    
500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v2       | 100.0%            |
|          |                   |
+----------+-------------------+
  1. סוגרים את החלונית המפוצלת.
tmux respawn-pane -t ${TMUX_SESSION}:0.1 -k 'exit'
 
  1. עוברים אל Cloud Source Repos בקישור שנוצר.
echo https://source.developers.google.com/p/$TF_VAR_ops_project_name/r/k8s-repo

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

b87b85f52fd2ff0f.png

עכשיו חוזרים על אותו תהליך באזור Dev2. שימו לב שהאזור Dev2 עדיין 'נעול' בגרסה 1. הסיבה לכך היא שבתסריט הבסיסי repo_setup, העברנו VirtualService כדי לשלוח במפורש את כל התעבורה לגרסה v1. כך יכולנו לבצע בבטחה בדיקת קנרית אזורית ב-Dev1, ולוודא שהיא פועלת בהצלחה לפני השקת הגרסה החדשה ברחבי העולם.

  1. מריצים את הפקודה כדי לפצל את חלון Cloud Shell ומריצים את הפקודה watch בחלונית התחתונה.
RESPY_POD=$(kubectl --context $DEV2_GKE_1 get pod \
-n frontend -l app=respy -o jsonpath='{..metadata.name}')
export TMUX_SESSION=$(tmux display-message -p '#S')
tmux split-window -d -t $TMUX_SESSION:0 -p33 \
-v "export KUBECONFIG=$WORKDIR/asm/gke/kubemesh; \
kubectl --context $DEV2_GKE_1 exec -n frontend -it \
$RESPY_POD -c respy /bin/sh -- -c 'watch -n 1 ./respy \
--u http://frontend:80/version --c 10 --n 500'; sleep 2"
 

פלט (אין להעתיק)

500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v1       | 100.0%            |
|          |                   |
+----------+-------------------+
  1. מריצים את צינור ה-Canary באזור Dev2. אנחנו מספקים סקריפט שמעדכן את אחוזי התנועה של frontend-v2 ב-VirtualService (מעדכן את המשקלים ל-20%, 50%, 80% ואז ל-100%). בין העדכונים, הסקריפט ממתין לסיום של צינור העברת הנתונים של Cloud Build. מריצים את סקריפט הפריסה של גרסה ראשונית (canary) לאזור Dev1. הערה: הפעלת הסקריפט הזה נמשכת כ-10 דקות.
K8S_REPO=$K8S_REPO CANARY_DIR=$CANARY_DIR \
OPS_DIR=$OPS_GKE_2_CLUSTER OPS_CONTEXT=$OPS_GKE_2 \
${CANARY_DIR}/auto-canary.sh
 

פלט (אין להעתיק)

500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v1       | 100.0%            |
|          |                   |
+----------+-------------------+
  1. מתוך ה-pod של Respy ב-Dev2, אפשר לראות את התנועה מ-pods של Dev2 עוברת בהדרגה מחלק הקצה (frontend) v1 ל-v2. בסיום הפעלת הסקריפט, אמורות להופיע ההודעות הבאות:

פלט (אין להעתיק)

500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v2       | 100.0%            |
|          |                   |
+----------+-------------------+
  1. סוגרים את החלונית המפוצלת.
tmux respawn-pane -t ${TMUX_SESSION}:0.1 -k 'exit'

בקטע הזה הסברנו איך להשתמש ב-Istio לפריסות קנרית אזוריות. בסביבת ייצור, במקום להשתמש בסקריפט ידני, אפשר להפעיל את סקריפט הקנרי הזה באופן אוטומטי כצינור עיבוד נתונים של Cloud Build, באמצעות טריגר כמו תמונה מתויגת חדשה שנדחפת ל-Container Registry. כדאי גם להוסיף ניתוח גרסה ראשונית (canary) בין כל שלב, כדי לנתח את זמן האחזור ושיעור השגיאות של גרסה 2 בהשוואה לסף בטיחות מוגדר מראש, לפני שליחת תעבורה נוספת.

11. מדיניות הרשאות

המטרה: הגדרת RBAC בין מיקרו-שירותים (AuthZ).

  • יצירת AuthorizationPolicy כדי לדחות גישה למיקרו-שירות
  • יצירת AuthorizationPolicy כדי לאפשר גישה ספציפית למיקרו-שירות

הוראות לשימוש ב-Labs בשיטת העתקה והדבקה

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

מדיניות Istio כוללת גם אימות וגם הרשאה. אימות בודק את הזהות (האם השרת הזה הוא מי שהוא אומר שהוא?), והרשאה בודקת את ההרשאות (האם הלקוח הזה מורשה לבצע את הפעולה הזו?). הסברנו על אימות ב-Istio בקטע על TLS בו-זמני (mTLS) במודול 1 (MeshPolicy). בקטע הזה נלמד איך להשתמש במדיניות הרשאות של Istio כדי לשלוט בגישה לאחד מנפחי העבודה של האפליקציה שלנו, currencyservice.

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

  1. בודקים את התוכן של currency-deny-all.yaml. המדיניות הזו משתמשת בבוררי תוויות פריסה כדי להגביל את הגישה אל currencyservice. שימו לב שאין שדה specזה אומר שהמדיניות הזו תחסום את כל הגישה לשירות שנבחר.
cat $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-deny-all.yaml
 

פלט (אין להעתיק)

apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "currency-policy"
  namespace: currency
spec:
  selector:
    matchLabels:
      app: currencyservice
  1. מעתיקים את מדיניות המטבע אל k8s-repo, עבור אשכולות ה-Ops בשני האזורים.
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-deny-all.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization/currency-policy.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization
kustomize edit add resource currency-policy.yaml
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-deny-all.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization/currency-policy.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization
kustomize edit add resource currency-policy.yaml
  1. דוחפים את השינויים.
cd $WORKDIR/k8s-repo 
git add . && git commit -am "AuthorizationPolicy - currency: deny all"
git push 
  1. בודקים את הסטטוס של פרויקט Ops Cloud Build בכרטיסייה שנפתחה קודם או על ידי לחיצה על הקישור הבא:
echo https://console.cloud.google.com/cloud-build/builds?project=$TF_VAR_ops_project_name 
 
  1. אחרי שהבנייה מסתיימת בהצלחה, מנסים להגיע לחלק הקדמי של hipstershop בדפדפן בקישור הבא:
echo "https://frontend.endpoints.$TF_VAR_ops_project_name.cloud.goog" 
 

אמורה להופיע שגיאת הרשאה מ-currencyservice:

f120f3d30d6ee9f.png

  1. בואו נבדוק איך שירות המטבעות אוכף את AuthorizationPolicy. קודם כול, מפעילים יומנים ברמת המעקב ב-Envoy proxy לאחד מ-pods המטבעות, כי קריאות הרשאה חסומות לא מתועדות כברירת מחדל.
CURRENCY_POD=$(kubectl --context $DEV1_GKE_2 get pod -n currency | grep currency| awk '{ print $1 }')
kubectl --context $DEV1_GKE_2 exec -it $CURRENCY_POD -n \
currency -c istio-proxy -- curl -X POST \
"http://localhost:15000/logging?level=trace"
 
  1. מקבלים את יומני ה-RBAC (הרשאות) משרת ה-Proxy מסוג Sidecar של שירות המטבע. אמורה להופיע ההודעה 'enforced denied' (הגישה נדחתה), שמציינת שהשירות currencyservice מוגדר לחסימת כל הבקשות הנכנסות.
kubectl --context $DEV1_GKE_2 logs -n currency $CURRENCY_POD \
-c istio-proxy | grep -m 3 rbac
 

פלט (אין להעתיק)

[Envoy (Epoch 0)] [2020-01-30 00:45:50.815][22][debug][rbac] [external/envoy/source/extensions/filters/http/rbac/rbac_filter.cc:67] checking request: remoteAddress: 10.16.5.15:37310, localAddress: 10.16.3.8:7000, ssl: uriSanPeerCertificate: spiffe://cluster.local/ns/frontend/sa/frontend, subjectPeerCertificate: , headers: ':method', 'POST'
[Envoy (Epoch 0)] [2020-01-30 00:45:50.815][22][debug][rbac] [external/envoy/source/extensions/filters/http/rbac/rbac_filter.cc:118] enforced denied
[Envoy (Epoch 0)] [2020-01-30 00:45:50.815][22][debug][http] [external/envoy/source/common/http/conn_manager_impl.cc:1354] [C115][S17310331589050212978] Sending local reply with details rbac_access_denied
  1. עכשיו ניתן גישה לקצה הקדמי – אבל לא לשירותי הקצה העורפי האחרים – כדי לגשת אל currencyservice. פותחים את currency-allow-frontend.yaml ובודקים את התוכן שלו. שימו לב שהוספנו את הכלל הבא:
cat ${WORKDIR}/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend.yaml

פלט (אין להעתיק)

rules:
 - from:
   - source:
       principals: ["cluster.local/ns/frontend/sa/frontend"]

בדוגמה הזו, אנחנו מוסיפים לרשימת ההיתרים source.principal (לקוח) ספציפי כדי לגשת לשירות המטבע. המשתנה source.principal מוגדר על ידי is Kubernetes Service Account. במקרה הזה, חשבון השירות שאנחנו מוסיפים לרשימת ההיתרים הוא חשבון השירות של קצה קדמי במרחב השמות של קצה קדמי.

הערה: כשמשתמשים בחשבונות שירות של Kubernetes ב-Istio AuthorizationPolicies, צריך קודם להפעיל TLS דו-כיווני בכל האשכול, כמו שעשינו במודול 1. כך מוודאים שפרטי הכניסה של חשבון השירות מוטמעים בבקשות.

  1. העתקה של מדיניות המטבע המעודכנת
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization/currency-policy.yaml
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization/currency-policy.yaml
 
  1. דוחפים את השינויים.
cd $WORKDIR/k8s-repo
git add . && git commit -am "AuthorizationPolicy - currency: allow frontend"
git push
 
  1. אפשר לראות את הסטטוס של פרויקט ה-Ops ב-Cloud Build בכרטיסייה שנפתחה קודם או בלחיצה על הקישור הבא:
echo https://console.cloud.google.com/cloud-build/builds?project=$TF_VAR_ops_project_name
  1. אחרי שהבנייה מסתיימת בהצלחה, פותחים שוב את החלק הקדמי של Hipstershop. בשלב הזה לא אמורות להופיע שגיאות בדף הבית, כי לקצה הקדמי יש הרשאה מפורשת לגשת לשירות הנוכחי.
  2. עכשיו, נסו לבצע תשלום: הוסיפו פריטים לעגלת הקניות ולחצו על 'ביצוע הזמנה'. הפעם, אמורה להופיע שגיאה בהמרת המחיר משירות המטבעות – הסיבה לכך היא שהוספנו לרשימת ההיתרים רק את הקצה הקדמי, ולכן עדיין אין ל-checkoutservice גישה ל-currencyservice.

7e30813d693675fe.png

  1. לבסוף, נותנים לשירות התשלום גישה למטבע על ידי הוספת כלל נוסף ל-AuthorizationPolicy של currencyservice. חשוב לדעת: אנחנו פותחים גישה למטבע רק לשני השירותים שצריכים גישה אליו – חזית האתר ודף התשלום. הקצה העורפי האחר עדיין ייחסם.
  2. פותחים את currency-allow-frontend-checkout.yaml ובודקים את התוכן שלו. שימו לב שרשימת הכללים פועלת כמו OR לוגי – המטבע יקבל רק בקשות מעומסי עבודה עם אחד משני חשבונות השירות האלה.
cat ${WORKDIR}/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend-checkout.yaml
 

פלט (אין להעתיק)

apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "currency-policy"
  namespace: currency
spec:
  selector:
    matchLabels:
      app: currencyservice
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/frontend/sa/frontend"]
  - from:
    - source:
        principals: ["cluster.local/ns/checkout/sa/checkout"]
  1. מעתיקים את מדיניות ההרשאה הסופית אל k8s-repo.
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend-checkout.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization/currency-policy.yaml
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend-checkout.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization/currency-policy.yaml
 
  1. שליחת השינויים
cd $WORKDIR/k8s-repo 
git add . && git commit -am "AuthorizationPolicy - currency: allow frontend and checkout"
git push
 
  1. אפשר לראות את הסטטוס של פרויקט ה-Ops ב-Cloud Build בכרטיסייה שנפתחה קודם או בלחיצה על הקישור הבא:
echo https://console.cloud.google.com/cloud-build/builds?project=$TF_VAR_ops_project_name
 
  1. אחרי שהבנייה מסתיימת בהצלחה, מנסים להפעיל תהליך תשלום – הוא אמור לפעול בהצלחה.

בקטע הזה הסברנו איך להשתמש במדיניות הרשאות ב-Istio כדי לאכוף בקרת גישה גרנולרית ברמת כל שירות. בסביבת הייצור, יכול להיות שתיצרו AuthorizationPolicy אחת לכל שירות, ותשתמשו (לדוגמה) במדיניות שמאפשרת הכול כדי לאפשר לכל עומסי העבודה באותו מרחב שמות לגשת אחד לשני.

12. הרחבת התשתית

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

  • שכפול מאגר infrastructure
  • עדכון קובצי Terraform כדי ליצור משאבים חדשים
  • ‫2 רשתות משנה באזור החדש (אחת לפרויקט התפעול ואחת לפרויקט החדש)
  • אשכול פעולות חדש באזור חדש (ברשת המשנה החדשה)
  • מישור בקרה חדש של Istio לאזור החדש
  • ‫2 קלאסטרים של אפליקציות בפרויקט החדש באזור החדש
  • ביצוע Commit למאגר infrastructure
  • אימות התקנה

הוראות לשימוש ב-Labs בשיטת העתקה והדבקה

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

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

  • אופקית – בתוך כל אזור, על ידי הוספת יכולת חישוב. כדי לעשות זאת, מוסיפים עוד צמתים (או מאגרי צמתים) לאשכולות קיימים או מוסיפים אשכולות חדשים באזור. הפעולה הזו מתבצעת דרך מאגר infrastructure. הדרך הכי פשוטה היא להוסיף צמתים לאשכולות קיימים. אין צורך לקבוע הגדרות נוספות בשביל זה. יכול להיות שתוספת של אשכולות חדשים תדרוש הוספה של רשתות משנה (ושל טווחים משניים), הוספה של כללי חומת אש מתאימים, הוספה של האשכולות החדשים למישור הבקרה של Service mesh אזורית של ASM/Istio ופריסה של משאבי אפליקציות באשכולות החדשים.
  • אופקית – על ידי הוספת אזורים נוספים. בפלטפורמה הנוכחית יש תבנית אזורית. הוא מורכב מאשכול אזורי של פעולות שבו נמצא מישור הבקרה של ASM/Istio, ושני אשכולות (או יותר) של אפליקציות אזוריות שבהם נפרסים משאבי האפליקציות.

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

  1. תת-רשתות ב-VPC המשותף של פרויקט המארח באזור r3 עבור אשכולות האפליקציות והפעולות החדשים.
  2. אשכול אזורי של פעולות באזור r3 שבו נמצא מישור הבקרה של ASM/Istio.
  3. שני אשכולות של אפליקציות אזוריות בשני אזורים באזור r3.
  4. מעדכנים את k8s-repo:
  5. פורסים משאבי מישור בקרה של ASM/Istio באשכול התפעול באזור r3.
  6. פריסת משאבי מישור בקרה משותף של ASM/Istio לאשכולות האפליקציות באזור r3.
  7. לא צריך ליצור פרויקט חדש, אבל השלבים בסדנה מדגימים איך מוסיפים פרויקט חדש בשם dev3 כדי לכסות את תרחיש השימוש של הוספת צוות חדש לפלטפורמה.

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

  1. ב-Cloud Shell, עוברים אל WORKDIR ומשכפלים את מאגר infrastructure.
mkdir -p $WORKDIR/infra-repo
cd $WORKDIR/infra-repo
git init && git remote add origin https://source.developers.google.com/p/${TF_ADMIN}/r/infrastructure
git config --local user.email ${MY_USER}
git config --local user.name "infra repo user"
git config --local credential.'https://source.developers.google.com'.helper gcloud.sh
git pull origin master
  1. משכפלים את הענף add-proj של מאגר המקור של הסדנה לספרייה add-proj-repo.
cd $WORKDIR
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git add-proj-repo -b add-proj

 
  1. מעתיקים קבצים מהענף add-proj במאגר הסדנה של המקור. ההסתעפות add-proj מכילה את השינויים בקטע הזה.
cp -r $WORKDIR/add-proj-repo/infrastructure/* $WORKDIR/infra-repo/
 
  1. כדי לאפשר הפעלה של הסקריפטים בענף, מחליפים את ספריית infrastructure בספריית המאגר add-proj בקישור סמלי לספריית infra-repo.
rm -rf $WORKDIR/add-proj-repo/infrastructure
ln -s $WORKDIR/infra-repo $WORKDIR/add-proj-repo/infrastructure
 
  1. מריצים את סקריפט add-project.sh כדי להעתיק את המשתנים והמצבים המשותפים למבנה ספריית הפרויקט החדש.
$WORKDIR/add-proj-repo/scripts/add-project.sh app3 $WORKDIR/asm $WORKDIR/infra-repo
  1. שומרים ודוחפים את השינויים כדי ליצור פרויקט חדש
cd $WORKDIR/infra-repo
git add .
git status
git commit -m "add new project" && git push origin master
 

  1. הקומט מפעיל את מאגר infrastructure כדי לפרוס את התשתית עם המשאבים החדשים. כדי לראות את ההתקדמות של Cloud Build, לוחצים על הפלט של הקישור הבא ועוברים לגרסת ה-build האחרונה בחלק העליון.
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_ADMIN}"
 

בשלב האחרון של infrastructure Cloud Build נוצרים משאבי Kubernetes חדשים ב-k8s-repo. הפעולה הזו מפעילה את Cloud Build ב-k8s-repo (בפרויקט של צוות ה-Ops). המשאבים החדשים של Kubernetes מיועדים לשלושת האשכולות החדשים שנוספו בשלב הקודם. מישור הבקרה של ASM/Istio ומשאבי מישור הבקרה המשותפים מתווספים לאשכולות החדשים באמצעות k8s-repo Cloud Build.

  1. אחרי ש-Cloud Build מסיים את התהליך של התשתית, עוברים אל k8s-repo ההרצה האחרונה של Cloud Build על ידי לחיצה על קישור הפלט הבא.
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
 
  1. מריצים את הסקריפט הבא כדי להוסיף את האשכולות החדשים לקובץ vars ולקובץ kubeconfig.
$WORKDIR/add-proj-repo/scripts/setup-gke-vars-kubeconfig-add-proj.sh $WORKDIR/asm
 
  1. משנים את המשתנה KUBECONFIG כך שיצביע על קובץ ה-kubeconfig החדש.
source $WORKDIR/asm/vars/vars.sh
export KUBECONFIG=$WORKDIR/asm/gke/kubemesh
 
  1. מציינים את ההקשרים של האשכולות. אמורים להופיע שמונה אשכולות.
kubectl config view -ojson | jq -r '.clusters[].name'
 
    `Output (do not copy)`
gke_user001-200204-05-dev1-49tqc4_us-west1-a_gke-1-apps-r1a-prod
gke_user001-200204-05-dev1-49tqc4_us-west1-b_gke-2-apps-r1b-prod
gke_user001-200204-05-dev2-49tqc4_us-central1-a_gke-3-apps-r2a-prod
gke_user001-200204-05-dev2-49tqc4_us-central1-b_gke-4-apps-r2b-prod
gke_user001-200204-05-dev3-49tqc4_us-east1-b_gke-5-apps-r3b-prod
gke_user001-200204-05-dev3-49tqc4_us-east1-c_gke-6-apps-r3c-prod
gke_user001-200204-05-ops-49tqc4_us-central1_gke-asm-2-r2-prod
gke_user001-200204-05-ops-49tqc4_us-east1_gke-asm-3-r3-prod
gke_user001-200204-05-ops-49tqc4_us-west1_gke-asm-1-r1-prod

אימות ההתקנה של Istio

  1. מוודאים ש-Istio מותקן באשכול החדש של פעולות על ידי בדיקה שכל הפודים פועלים והעבודות הושלמו.
kubectl --context $OPS_GKE_3 get pods -n istio-system
 
    `Output (do not copy)`
NAME                                      READY   STATUS    RESTARTS   AGE
grafana-5f798469fd-72g6w                  1/1     Running   0          5h12m
istio-citadel-7d8595845-hmmvj             1/1     Running   0          5h12m
istio-egressgateway-779b87c464-rw8bg      1/1     Running   0          5h12m
istio-galley-844ddfc788-zzpkl             2/2     Running   0          5h12m
istio-ingressgateway-59ccd6574b-xfj98     1/1     Running   0          5h12m
istio-pilot-7c8989f5cf-5plsg              2/2     Running   0          5h12m
istio-policy-6674bc7678-2shrk             2/2     Running   3          5h12m
istio-sidecar-injector-7795bb5888-kbl5p   1/1     Running   0          5h12m
istio-telemetry-5fd7cbbb47-c4q7b          2/2     Running   2          5h12m
istio-tracing-cd67ddf8-2qwkd              1/1     Running   0          5h12m
istiocoredns-5f7546c6f4-qhj9k             2/2     Running   0          5h12m
kiali-7964898d8c-l74ww                    1/1     Running   0          5h12m
prometheus-586d4445c7-x9ln6               1/1     Running   0          5h12m
  1. מוודאים ש-Istio מותקן בשני אשכולי dev3. רק Citadel, ‏ sidecar-injector ו-coredns פועלים באשכולות dev3. הם חולקים מישור בקרה של Istio שפועל באשכול ops-3.
kubectl --context $DEV3_GKE_1 get pods -n istio-system
kubectl --context $DEV3_GKE_2 get pods -n istio-system
 
    `Output (do not copy)`
NAME                                      READY   STATUS    RESTARTS   AGE
istio-citadel-568747d88-4lj9b             1/1     Running   0          66s
istio-sidecar-injector-759bf6b4bc-ks5br   1/1     Running   0          66s
istiocoredns-5f7546c6f4-qbsqm             2/2     Running   0          78s

אימות של גילוי שירותים עבור מישורי בקרה משותפים

  1. מוודאים שהסודות נפרסו בכל אשכולות ה-Ops עבור כל ששת אשכולות האפליקציות.
kubectl --context $OPS_GKE_1 get secrets -l istio/multiCluster=true -n istio-system
kubectl --context $OPS_GKE_2 get secrets -l istio/multiCluster=true -n istio-system
kubectl --context $OPS_GKE_3 get secrets -l istio/multiCluster=true -n istio-system
 
    `Output (do not copy)`
NAME                  TYPE     DATA   AGE
gke-1-apps-r1a-prod   Opaque   1      14h
gke-2-apps-r1b-prod   Opaque   1      14h
gke-3-apps-r2a-prod   Opaque   1      14h
gke-4-apps-r2b-prod   Opaque   1      14h
gke-5-apps-r3b-prod   Opaque   1      5h12m
gke-6-apps-r3c-prod   Opaque   1      5h12m

13. מפסק זרם

המטרה: הטמעה של מפסק זרם לשירות המשלוחים.

  • יוצרים DestinationRule לשירות shipping כדי להטמיע מפסק זרם
  • משתמשים ב-fortio (כלי ליצירת עומס) כדי לאמת את מפסק הזרם בשירות shipping על ידי הפעלת המפסק בכוח

הוראות לשימוש ב-Fast Track Script Lab

בקרוב נשיק את Fast Track Script Lab!!

הוראות לשימוש ב-Labs בשיטת העתקה והדבקה

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

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

התבנית Circuit Breaker (מפסק זרם) נקראת על שם מתג חשמלי שיכול 'לקפוץ' כשזורם דרכו יותר מדי חשמל, וכך להגן על מכשירים מפני עומס יתר. בהגדרת Istio, המשמעות היא ש-Envoy הוא מפסק הזרם, והוא עוקב אחרי מספר הבקשות בהמתנה לשירות. במצב הסגור הזה שמוגדר כברירת מחדל, הבקשות עוברות דרך Envoy ללא הפרעה.

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

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

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

2127a0a172ff4802.png

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

Output (do not copy)

apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
  name: "shippingservice-shipping-destrule"
  namespace: "shipping"
spec:
  host: "shippingservice.shipping.svc.cluster.local"
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
    connectionPool:
      tcp:
        maxConnections: 1
      http:
        http1MaxPendingRequests: 1
        maxRequestsPerConnection: 1
    outlierDetection:
      consecutiveErrors: 1
      interval: 1s
      baseEjectionTime: 10s
      maxEjectionPercent: 100

יש כאן שני שדות DestinationRule שחשוב לשים לב אליהם. ‫connectionPool מגדיר את מספר החיבורים שהשירות הזה יאפשר. בשדה outlierDetection מגדירים איך Envoy יקבע את סף הפתיחה של מפסק הזרם. במקרה הזה, כל שנייה (מרווח), Envoy יספור את מספר השגיאות שהוא קיבל ממאגר התגים בצד השרת. אם הערך חורג מהסף consecutiveErrors, מפסק הזרם של Envoy ייפתח, ו-100% מהפודים של productcatalog יהיו מוגנים מפני בקשות חדשות של לקוחות למשך 10 שניות. אחרי שמפסק הזרם של Envoy נפתח (כלומר, פעיל), הלקוחות יקבלו שגיאות 503 (השירות לא זמין). בואו נראה את זה בפעולה.

  1. כדי לפשט את הפקודות, מגדירים משתני סביבה עבור k8s-repo ו-asm dir.
export K8S_REPO="${WORKDIR}/k8s-repo"
export ASM="${WORKDIR}/asm" 
 
  1. עדכון של k8s-repo
cd $WORKDIR/k8s-repo
git pull
cd $WORKDIR
  1. מעדכנים את DestinationRule של שירות המשלוחים בשני אשכולי ה-Ops.
cp $ASM/k8s_manifests/prod/istio-networking/app-shipping-circuit-breaker.yaml ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml
cp $ASM/k8s_manifests/prod/istio-networking/app-shipping-circuit-breaker.yaml ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml

cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit add resource app-shipping-circuit-breaker.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit add resource app-shipping-circuit-breaker.yaml
 
  1. מעתיקים את ה-pod של מחולל העומסים Fortio לאשכול GKE_1 באזור Dev1. זהו ה-pod של הלקוח שבו נשתמש כדי להפעיל את מפסק הזרם של שירות המשלוחים.
cp $ASM/k8s_manifests/prod/app/deployments/app-fortio.yaml ${K8S_REPO}/${DEV1_GKE_1_CLUSTER}/app/deployments/
cd ${K8S_REPO}/${DEV1_GKE_1_CLUSTER}/app/deployments; kustomize edit add resource app-fortio.yaml
 
  1. שומרים את השינויים.
cd $K8S_REPO 
git add . && git commit -am "Circuit Breaker: shippingservice"
git push
cd $ASM
 
  1. מחכים לסיום של Cloud Build.
  2. חוזרים ל-Cloud Shell ומשתמשים ב-pod של fortio כדי לשלוח תנועת gRPC אל shippingservice עם חיבור מקביל אחד, סך של 1, 000 בקשות – זה לא יפעיל את מפסק הזרם, כי עדיין לא חרגנו מההגדרות של connectionPool.
FORTIO_POD=$(kubectl --context ${DEV1_GKE_1} get pod -n shipping | grep fortio | awk '{ print $1 }')

kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c fortio /usr/bin/fortio -- load -grpc -c 1 -n 1000 -qps 0 shippingservice.shipping.svc.cluster.local:50051 
 

פלט (אין להעתיק)

Health SERVING : 1000
All done 1000 calls (plus 0 warmup) 4.968 ms avg, 201.2 qps
  1. עכשיו מריצים שוב את fortio, מגדילים את מספר החיבורים המקבילים ל-2, אבל משאירים את המספר הכולל של הבקשות קבוע. צריך לראות שעד שני שלישים מהבקשות מחזירות שגיאת overflow, כי מפסק הזרם הופעל: במדיניות שהגדרנו, מותר רק חיבור מקביל אחד במרווח של שנייה אחת.
kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c fortio /usr/bin/fortio -- load -grpc -c 2 -n 1000 -qps 0 shippingservice.shipping.svc.cluster.local:50051 
 

פלט (אין להעתיק)

18:46:16 W grpcrunner.go:107> Error making grpc call: rpc error: code = Unavailable desc = upstream connect error or disconnect/reset before headers. reset reason: overflow
...

Health ERROR : 625
Health SERVING : 375
All done 1000 calls (plus 0 warmup) 12.118 ms avg, 96.1 qps
  1. ‫Envoy עוקב אחרי מספר החיבורים שהוא הפסיק כשהמפסק האוטומטי פעיל, באמצעות המדד upstream_rq_pending_overflow. בואו נחפש את זה ב-fortio pod:
kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c istio-proxy  -- sh -c 'curl localhost:15000/stats' | grep shipping | grep pending
 

פלט (אין להעתיק)

cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.circuit_breakers.default.rq_pending_open: 0
cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.circuit_breakers.high.rq_pending_open: 0
cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_active: 0
cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_failure_eject: 9
cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_overflow: 565
cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_total: 1433
  1. כדי להסיר את המשאבים, מסירים את מדיניות מפסק הזרם משני האזורים.
kubectl --context ${OPS_GKE_1} delete destinationrule shippingservice-circuit-breaker -n shipping 
rm ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml
cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit remove resource app-shipping-circuit-breaker.yaml
 

kubectl --context ${OPS_GKE_2} delete destinationrule shippingservice-circuit-breaker -n shipping 
rm ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit remove resource app-shipping-circuit-breaker.yaml
cd $K8S_REPO; git add .; git commit -m "Circuit Breaker: cleanup"; git push origin master
 

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

14. הזרקת תקלות

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

  • יוצרים VirtualService לשירות recommendation כדי להוסיף עיכוב של 5 שניות
  • בדיקת ההשהיה באמצעות fortio מחולל עומסים
  • הסרת העיכוב ב-VirtualService ואימות

הוראות לשימוש ב-Fast Track Script Lab

בקרוב נשיק את Fast Track Script Lab!!

הוראות לשימוש ב-Labs בשיטת העתקה והדבקה

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

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

אפשר להשתמש ב-Istio לבדיקת כאוס על ידי החלת VirtualService עם השדה fault. ‫Istio תומך בשני סוגים של תקלות: תקלות השהיה (החדרת זמן קצוב לתפוגה) ותקלות ביטול (החדרת שגיאות HTTP). בדוגמה הזו, נחדיר תקלה של עיכוב של 5 שניות אל שירות ההמלצות. אבל הפעם, במקום להשתמש במפסק זרם כדי לבצע 'כשל מהיר' בשירות הזה שנתקע, נכריח את השירותים במורד הזרם לסבול את זמן קצוב לתפוגה המלא.

  1. עוברים לספרייה של הזרקת תקלות.
export K8S_REPO="${WORKDIR}/k8s-repo"
export ASM="${WORKDIR}/asm/" 
cd $ASM
 
  1. פותחים את k8s_manifests/prod/istio-networking/app-recommendation-vs-fault.yaml כדי לבדוק את התוכן שלו. שימו לב שב-Istio יש אפשרות להחדיר את התקלה לאחוז מסוים מהבקשות – כאן, נחדיר זמן קצוב לתפוגה לכל הבקשות של שירות ההמלצות.

פלט (אין להעתיק)

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: recommendation-delay-fault
spec:
  hosts:
  - recommendationservice.recommendation.svc.cluster.local
  http:
  - route:
    - destination:
        host: recommendationservice.recommendation.svc.cluster.local
    fault:
      delay:
        percentage:
          value: 100
        fixedDelay: 5s
  1. מעתיקים את VirtualService אל k8s_repo. נחדיר את התקלה באופן גלובלי, בשני האזורים.
cp $ASM/k8s_manifests/prod/istio-networking/app-recommendation-vs-fault.yaml ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit add resource app-recommendation-vs-fault.yaml

cp $ASM/k8s_manifests/prod/istio-networking/app-recommendation-vs-fault.yaml ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit add resource app-recommendation-vs-fault.yaml
 
  1. שליחת השינויים
cd $K8S_REPO 
git add . && git commit -am "Fault Injection: recommendationservice"
git push
cd $ASM
 
  1. מחכים לסיום של Cloud Build.
  2. מבצעים exec ל-pod של fortio שנפרס בקטע של מפסק הזרם, ושולחים עומס תנועה קל ל-recommendationservice.
FORTIO_POD=$(kubectl --context ${DEV1_GKE_1} get pod -n shipping | grep fortio | awk '{ print $1 }')

kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c fortio /usr/bin/fortio -- load -grpc -c 100 -n 100 -qps 0 recommendationservice.recommendation.svc.cluster.local:8080
 
    Once the fortio command is complete, you should see responses averaging 5s:

פלט (אין להעתיק)

Ended after 5.181367359s : 100 calls. qps=19.3
Aggregated Function Time : count 100 avg 5.0996506 +/- 0.03831 min 5.040237641 max 5.177559818 sum 509.965055
  1. דרך נוספת לראות את התקלה שהחדרנו בפעולה היא לפתוח את הקצה הקדמי בדפדפן אינטרנט וללחוץ על מוצר כלשהו. טעינת דף מוצר צריכה להימשך 5 שניות נוספות, כי המערכת מאחזרת את ההמלצות שמוצגות בתחתית הדף.
  2. מבצעים ניקוי על ידי הסרת שירות הזרקת התקלות משני אשכולות ה-Ops.
kubectl --context ${OPS_GKE_1} delete virtualservice recommendation-delay-fault -n recommendation 
rm ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit remove resource app-recommendation-vs-fault.yaml

kubectl --context ${OPS_GKE_2} delete virtualservice recommendation-delay-fault -n recommendation 
rm ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit remove resource app-recommendation-vs-fault.yaml
 
  1. דחיפת השינויים:
cd $K8S_REPO 
git add . && git commit -am "Fault Injection cleanup / restore"
git push
cd $ASM
 

15. מעקב אחרי מישור הבקרה של Istio

‫ASM מתקין ארבעה רכיבי מישור בקרה חשובים: Pilot, ‏ Mixer, ‏ Galley ו-Citadel. כל אחד מהם שולח את מדדי המעקב הרלוונטיים אל Prometheus, ו-ASM מגיע עם מרכזי בקרה של Grafana שמאפשרים למפעילים לראות את נתוני המעקב האלה ולהעריך את התקינות והביצועים של מישור הבקרה.

צפייה במרכזי הבקרה

  1. הפניית יציאה של שירות Grafana שהותקן באמצעות Istio
kubectl --context ${OPS_GKE_1} -n istio-system port-forward svc/grafana 3000:3000 >> /dev/null
 
  1. פתיחת Grafana בדפדפן
  2. לוחצים על סמל התצוגה המקדימה של האתר בפינה השמאלית העליונה של חלון Cloud Shell.
  3. לוחצים על Preview (תצוגה מקדימה) ביציאה 3000 (הערה: אם היציאה היא לא 3000, לוחצים על Change port (שינוי היציאה) ובוחרים ביציאה 3000).
  4. תיפתח כרטיסייה בדפדפן עם כתובת URL שדומה ל-BASE_URL/?orgId=1&authuser=0&environment_id=default
  5. צפייה במרכזי הבקרה הזמינים
  6. משנים את כתובת ה-URL ל-" BASE_URL/dashboard"
  7. לוחצים על התיקייה istio כדי לראות את לוחות הבקרה הזמינים.
  8. אפשר ללחוץ על אחד מלוחות הבקרה האלה כדי לראות את הביצועים של הרכיב. בקטעים הבאים נבחן את המדדים החשובים של כל רכיב.

Monitoring Pilot

‫Pilot הוא רכיב של מישור הבקרה שמפיץ את הגדרות הרשת והמדיניות למישור הנתונים (שרתי ה-proxy של Envoy). בדרך כלל, היקף השימוש ב-Pilot גדל בהתאם למספר עומסי העבודה והפריסות, אבל לא בהכרח בהתאם לכמות התנועה לעומסי העבודה האלה. מערכת Pilot לא תקינה יכולה:

  • לצרוך יותר משאבים מהנדרש (CPU או RAM)
  • גורמים לעיכובים בהעברת מידע עדכני על ההגדרות אל Envoys

הערה: אם Pilot מושבת או שיש עיכובים, עומסי העבודה שלכם עדיין משרתים תנועה.

  1. בדפדפן, עוברים אל BASE_URL/dashboard/db/istio-pilot-dashboard כדי לראות את המדדים של Pilot.

מדדים חשובים למעקב

Resource Usage

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

5f1969f8e2c8b137.png

Pilot Push Information

בקטע הזה אפשר לעקוב אחרי דחיפות של הגדרות לשרתי ה-proxy של Envoy.

  • הפעלות פיילוט: בעמודה הזו מוצג סוג ההגדרה שהופעלה בכל נקודת זמן.
  • מעקב אחר ADS מציג את מספר השירותים הווירטואליים, השירותים ונקודות הקצה המחוברות במערכת.
  • Clusters with no known endpoints (אשכולות ללא נקודות קצה ידועות) מציג נקודות קצה שהוגדרו אבל לא מופעלים בהן מופעים (מה שעשוי להצביע על שירותים חיצוניים, כמו ‎ *.googleapis.com).
  • שגיאות בגרסת הפיילוט: מספר השגיאות שהמערכת נתקלה בהן לאורך זמן.
  • Conflicts (קונפליקטים) מציג את מספר הקונפליקטים שהם הגדרות לא חד-משמעיות במאזינים.

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

פרטי Envoy

בקטע הזה יש מידע על שרתי ה-proxy של Envoy שיוצרים קשר עם מישור הבקרה. אם אתם רואים שוב ושוב שגיאות בחיבור XDS, פנו לתמיכה של GCP.

מיקסר ניטור

‫Mixer הוא הרכיב שמעביר טלמטריה משרתי ה-proxy של Envoy אל קצה העורף של הטלמטריה (בדרך כלל Prometheus,‏ Stackdriver וכו'). במסגרת התפקיד הזה, הוא לא נמצא במישור הנתונים. הוא נפרס כשני ג'ובים של Kubernetes (שנקראים Mixer) שנפרסים עם שני שמות שירות שונים (istio-telemetry ו-istio-policy).

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

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

  1. כדי לראות את המדדים של Mixer, עוברים אל BASE_URL/dashboard/db/istio-mixer-dashboard בדפדפן.

מדדים חשובים למעקב

Resource Usage

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

87ed83238f9addd8.png

סקירה כללית על Mixer

  • משך התגובה הוא מדד חשוב. הדוחות לטלמטריה של Mixer לא נמצאים בנתיב הנתונים, אבל אם זמן האחזור גבוה, הביצועים של ה-proxy של Sidecar יואטו. הערך באחוזון ה-90 צפוי להיות באלפיות השנייה עם ספרה אחת, והערך באחוזון ה-99 צפוי להיות מתחת ל-100 אלפיות השנייה.

e07bdf5fde4bfe87.png

  • Adapter Dispatch Duration (משך השליחה של המתאם) מציין את זמן האחזור שחווה Mixer בקריאה למתאמים (שדרכם הוא שולח מידע למערכות טלמטריה ורישום). זמני אחזור גבוהים כאן ישפיעו באופן משמעותי על הביצועים ברשת ה-Mesh. שוב, זמני האחזור של p90 צריכים להיות מתחת ל-10 אלפיות השנייה.

1c2ee56202b32bd9.png

מעקב אחר הגהה

‫Galley הוא רכיב של Istio שמאמת את ההגדרות, קולט, מעבד ומפיץ אותן. הוא מעביר את ההגדרה משרת ה-API של Kubernetes אל Pilot. בדומה ל-Pilot, הוא נוטה להתרחב בהתאם למספר השירותים ונקודות הקצה במערכת.

  1. בדפדפן, עוברים אל BASE_URL/dashboard/db/istio-galley-dashboard כדי לראות את מדדי Galley.

מדדים חשובים למעקב

אימות משאבים

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

לקוחות עם מכשירים מחוברים

מציין כמה לקוחות מחוברים ל-Galley. בדרך כלל יהיו 3 (pilot, ‏ istio-telemetry, ‏ istio-policy) והמספר יגדל ככל שהרכיבים האלה יגדלו.

16. פתרון בעיות ב-Istio

פתרון בעיות במישור הנתונים

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

כדי לבדוק את יומני הפיילוט, מריצים את הפקודה kubectl -n istio-system logs istio-pilot-69db46c598-45m44 discovery, ומחליפים את istio-pilot-... במזהה ה-pod של מופע הפיילוט שרוצים לפתור בו בעיות.

ביומן שיופיע, מחפשים הודעה עם סטטוס של הודעת פוש. לדוגמה:

2019-11-07T01:16:20.451967Z        info        ads        Push Status: {
    "ProxyStatus": {
        "pilot_conflict_outbound_listener_tcp_over_current_tcp": {
            "0.0.0.0:443": {
                "proxy": "cartservice-7555f749f-k44dg.hipster",
                "message": "Listener=0.0.0.0:443 AcceptedTCP=accounts.google.com,*.googleapis.com RejectedTCP=edition.cnn.com TCPServices=2"
            }
        },
        "pilot_duplicate_envoy_clusters": {
            "outbound|15443|httpbin|istio-egressgateway.istio-system.svc.cluster.local": {
                "proxy": "sleep-6c66c7765d-9r85f.default",
                "message": "Duplicate cluster outbound|15443|httpbin|istio-egressgateway.istio-system.svc.cluster.local found while pushing CDS"
            },
            "outbound|443|httpbin|istio-egressgateway.istio-system.svc.cluster.local": {
                "proxy": "sleep-6c66c7765d-9r85f.default",
                "message": "Duplicate cluster outbound|443|httpbin|istio-egressgateway.istio-system.svc.cluster.local found while pushing CDS"
            },
            "outbound|80|httpbin|istio-egressgateway.istio-system.svc.cluster.local": {
                "proxy": "sleep-6c66c7765d-9r85f.default",
                "message": "Duplicate cluster outbound|80|httpbin|istio-egressgateway.istio-system.svc.cluster.local found while pushing CDS"
            }
        },
        "pilot_eds_no_instances": {
            "outbound_.80_._.frontend-external.hipster.svc.cluster.local": {},
            "outbound|443||*.googleapis.com": {},
            "outbound|443||accounts.google.com": {},
            "outbound|443||metadata.google.internal": {},
            "outbound|80||*.googleapis.com": {},
            "outbound|80||accounts.google.com": {},
            "outbound|80||frontend-external.hipster.svc.cluster.local": {},
            "outbound|80||metadata.google.internal": {}
        },
        "pilot_no_ip": {
            "loadgenerator-778c8489d6-bc65d.hipster": {
                "proxy": "loadgenerator-778c8489d6-bc65d.hipster"
            }
        }
    },
    "Version": "o1HFhx32U4s="
}

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

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

איתור שגיאות בהגדרות

כדי להשתמש ב-istioctl כדי לנתח את ההגדרה, מריצים את הפקודה istioctl experimental analyze -k --context $OPS_GKE_1. המערכת תבצע ניתוח של ההגדרה במערכת שלכם, תציין בעיות ותציע שינויים. רשימה מלאה של שגיאות התצורה שהפקודה הזו יכולה לזהות מופיעה במסמכי העזרה.

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

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

  • שם הארגון – לדוגמה yourcompany.com
  • מזהה הסדנה – בפורמט YYMMDD-NN, לדוגמה 200131-01
  • קטגוריית GCS של אדמין – מוגדרת בסקריפט של bootstrap.
  1. פותחים את Cloud Shell ומבצעים את כל הפעולות שבהמשך ב-Cloud Shell. לוחצים על הקישור שלמטה.

Cloud Shell

  1. מוודאים שנכנסתם ל-gcloud עם משתמש האדמין הרצוי.
gcloud config list
 
  1. עוברים לתיקייה asm.
cd ${WORKDIR}/asm
 
  1. מגדירים את שם הארגון ואת מזהה הסדנה שרוצים למחוק.
export ORGANIZATION_NAME=<ORGANIZATION NAME>
export ASM_WORKSHOP_ID=<WORKSHOP ID>
export ADMIN_STORAGE_BUCKET=<ADMIN CLOUD STORAGE BUCKET>
 
  1. מריצים את הסקריפט לניקוי המשאבים באופן הבא.
./scripts/cleanup_workshop.sh --workshop-id ${ASM_WORKSHOP_ID} --admin-gcs-bucket ${ADMIN_STORAGE_BUCKET} --org-name ${ORGANIZATION_NAME}