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

1. סדנת אלפא

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

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

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

9a033157f44308f3.png

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

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

  • Module 0 - Introduction and Platform Setup
  • מבוא וארכיטקטורה
  • מבוא ל-Service Mesh ול-Istio/ASM
  • Lab: Infrastructure Setup: User workflow
  • Break
  • QnA
  • מודול 1 – התקנה, אבטחה ומעקב של אפליקציות באמצעות ASM
  • מודל Repo: הסבר על מאגרי תשתית ו-Kubernetes
  • שיעור Lab: פריסת אפליקציה לדוגמה
  • שירותים מבוזרים ויכולת צפייה
  • ארוחת צהריים
  • מעבדת תרגול: יכולת צפייה באמצעות Stackdriver
  • QNA
  • מודול 2 – DevOps – השקות קנריות, מדיניות/RBAC
  • זיהוי שירותים מרובי אשכולות ואבטחה/מדיניות
  • שיעור Lab: TLS דו-צדדי
  • פריסות של גרסה ראשונית (canary)
  • שיעור Lab: פריסות של גרסה ראשונית (canary)
  • איזון עומסים גלובלי מאובטח בין כמה אשכולות
  • Break
  • שיעור 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. לאדמינים שיוצרים סדנאות צריכות להיות הרשאות קריאה וכתיבה לקטגוריה הזו.

סקריפט הסדנה של 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 Owner לכל הפרויקטים בארגון.
  • Folder Admin – יכול ליצור ולמחוק תיקיות בארגון. כל משתמש מקבל תיקייה אחת עם כל המשאבים שלו בתוך הפרויקט.
  • אדמין ארגוני
  • Project Creator – היכולת ליצור פרויקטים בארגון.
  • 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, צריך לקבל את הקובץ workshop.txt ממאגר GCS של האדמין.
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 בקצב שלכם. הסקריפטים של המסלול המהיר הם אידמפוטנטיים, כלומר אפשר להריץ אותם כמה פעמים ולקבל את אותה תוצאה.

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

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

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

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

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

הסדנה הזו מתבצעת באמצעות חשבון משתמש זמני (או חשבון מעבדה) שנוצר על ידי האדמין של הסדנה. כל הפרויקטים בסדנה הם בבעלות של חשבון 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](https://cloud.google.com/terms) ולוחצים על `Start Cloud Shell`. 7b198cf2e32cb457.png

בשלב הזה מוקצה לכם מכונה וירטואלית קטנה של Linux Debian שתוכלו להשתמש בה כדי לגשת למשאבי GCP. כל חשבון מקבל מכונה וירטואלית של Cloud Shell. מתחברים באמצעות פרטי הכניסה לחשבון ה-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 נוסף בפרויקט ops. לוחצים על הקישור שמוצג כדי לפתוח את הדף Cloud Build של ops project ומוודאים שה-Cloud Build של k8s-repo הסתיים בהצלחה.
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 של אשכולות האפליקציות (מאומת באמצעות הסודות שלמעלה). אפשר לראות ששני אשכולי הפעולות יכולים לבצע אימות לכל אשכולי האפליקציות באמצעות סודות שנוצרו על ידי kubeconfig. אפשר להגדיר את האשכולות של Ops כך שיגלו שירותים באופן אוטומטי באמצעות קובצי kubeconfig כשיטה סודית. כדי לעשות את זה, ל-Pilot באשכולות של ה-ops צריכה להיות גישה לשרת Kube API של כל שאר האשכולות. אם Pilot לא יכול לגשת לשרתי Kube API, צריך להוסיף שירותים מרוחקים באופן ידני כ-ServiceEntries. אפשר לחשוב על ServiceEntries כרשומות DNS במרשם השירותים. רשומות ServiceEntry מגדירות שירות באמצעות שם DNS שמוגדר במלואו ( FQDN) וכתובת IP שאפשר להגיע אליה. מידע נוסף זמין במסמכי התיעוד בנושא Istio Multicluster.

6. הסבר על Infrastructure Repo

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. תשתית – מייצג את צוות תשתית הענן. הם אחראים ליצירת משאבי 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 בפרויקט, צריך לדעת את מזהה הפרויקט. מזהה הפרויקט מופיע בקובץ tfstate דרך output.tf, ואפשר להשתמש בו דרך מקור נתונים 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. אשכולי Ops – משמשים את צוות ה-Ops להפעלת כלי DevOps. בסדנה הזו, הם מפעילים את מישור הבקרה של ASM/Istio כדי לנהל את Service mesh.
  2. אשכולות של אפליקציות – משמשים את צוותי הפיתוח להרצת אפליקציות. בסדנה הזו נעשה שימוש באפליקציית Hipster shop.

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

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

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

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

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

משתמשים ב-k8s_repo כדי להוסיף משאבי Kubernetes לכל אשכולות GKE. כדי לעשות זאת, מעתיקים את מניפסטים של Kubernetes ומבצעים קומיט ל-k8s_repo. כל פעולות ה-commit אל 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 באשכולות של פעולות ה-Ops
  • הגדרה של 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 מהקובץ ops clusters kustomization.yaml.
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 נחשפת באמצעות מאזן עומסים גלובלי של Google Cloud ‏ (GCLB). שירות 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 במניפסטים loadgenerator של שני אשכולי ה-Ops.
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. אפשר לראות את הסטטוס של פרויקט Cloud Build של Ops בכרטיסייה שנפתחה קודם או בלחיצה על הקישור הבא:
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
  

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

  1. מוודאים שכל הפודים בכל מרחבי השמות של האפליקציות, מלבד cart, נמצאים במצב 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 משתמש בשני שערים של תעבורת נתונים נכנסת (ingress) של Istio (שפועלים בשני אשכולות של פעולות) כשרתי קצה עורפיים לשירות הקצה הקדמי הגלובלי. שערי הכניסה של Istio Ingress מקבלים את תעבורת הנתונים של הלקוחות מ-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 באמצעות הערות Service. מישורי הבקרה של 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

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

כחלק מפריסת האפליקציה, גנרטורים של עומסים נפרסו בשני אשכולות התפעול שיוצרים תנועת בדיקה לקישור GCLB Hipster shop Cloud Endpoints. מוודאים ש-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. בתפריט הנפתח Backend, משנים את האפשרות מ-All backends (כל ה-backends) ל-istio-ingressgateway, כמו שמוצג בהמשך.

6697c9eb67998d27.png

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

ff8126e44cfd7f5e.png

נוצרות שלוש קבוצות NEG לכל 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-repo.
cd $WORKDIR/k8s-repo
git add . && git commit -am "Install istio to stackdriver configuration"
git push 
 
  1. אפשר לראות את הסטטוס של פרויקט Cloud Build של Ops בכרטיסייה שנפתחה קודם או בלחיצה על הקישור הבא:
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 זמן טעינה): [ מאמרי העזרה של ה-API] Now we can add a new widget to our dashboard 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 אל ה-proxies של ה-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 באשכולות ops. הערה: ‏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'
 
    `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-repo.
cd $WORKDIR/k8s-repo
git add . && git commit -am "turn mTLS on"
git push
 
  1. אפשר לראות את הסטטוס של פרויקט Cloud Build של Ops בכרטיסייה שנפתחה קודם או בלחיצה על הקישור הבא:
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 operator.
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) בכל שלב של פיצול התנועה, ולהשוות בין "האותות המוזהבים" של הגרסה החדשה (זמן האחזור, שיעור השגיאות, ניצול מלא) לבין נתוני הבסיס. כך אפשר למנוע הפסקות בשירות ולהבטיח את היציבות של שירות '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 ויעזור לנו להמחיש את פריסה של גרסה ראשונית (canary) בזמן אמת.
  • ‫frontend Istio DestinationRule – מפצל את שירות ה-Kubernetes של חזית האתר לשתי קבוצות משנה, v1 ו-v2, על סמך תווית הפריסה 'version'
  • ‫frontend Istio VirtualService – מעביר 100% מהתנועה ל-frontend v1. הפעולה הזו מבטלת את התנהגות ברירת המחדל של Kubernetes Service, שבה 50% מכל התעבורה האזורית של Dev1 נשלחת באופן מיידי לחלק הקדמי v2.
  1. אישור השינויים ב-k8s_repo:
cd $K8S_REPO 
git add . && git commit -am "frontend canary setup"
git push
 
  1. אפשר לראות את הסטטוס של פרויקט Cloud Build של Ops בכרטיסייה שנפתחה קודם או בלחיצה על הקישור הבא:
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}" 
 
  1. עוברים אל Cloud Build במסוף של פרויקט OPS1. מחכים עד שפייפליין Cloud Build יסיים את הפעולה, ואז מקבלים את ה-Pod-ים במרחב השמות של הקצה הקדמי בשני האשכולות 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. כל תעבורת הנתונים מהקצה הקדמי של Pod Dev2 צריכה לעבור אל frontend-v2:
     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. מ-Respy pod ב-Dev2, צופים בתנועה מ-Dev2 pods עוברת בהדרגה מ-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, באמצעות טריגר כמו תמונה מתויגת חדשה שנדחפת למאגר תמונות של קונטיינרים. כדאי גם להוסיף ניתוח גרסה ראשונית (canary) בין כל שלב, כדי לנתח את זמן האחזור ואת שיעור השגיאות של גרסה 2 בהשוואה לסף בטיחות מוגדר מראש, לפני שליחת תעבורת נתונים נוספת.

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

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

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

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

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

מדיניות Istio כוללת גם אימות וגם הרשאה. אימות בודק את הזהות (האם השרת הזה הוא מי שהוא טוען שהוא?), והרשאה בודקת את ההרשאות (האם הלקוח הזה מורשה לבצע את הפעולה הזו?). הסברנו על אימות ב-Istio בקטע על TLS בו-זמני במודול 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. בואו נבדוק איך שירות המטבעות אוכף את מדיניות ההרשאה הזו. קודם כול, מפעילים את היומנים ברמת המעקב בשרת ה-proxy של Envoy לאחד ממאגרי המטבעות, כי קריאות הרשאה חסומות לא נרשמות ביומן כברירת מחדל.
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 (הרשאות) מקובץ העזר החיצוני של שירות המטבע. אמורה להופיע ההודעה 'enforced denied' (הגישה נדחתה), שמציינת ששירות המטבעות מוגדר לחסימת כל הבקשות הנכנסות.
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. אפשר לראות את הסטטוס של פרויקט Cloud Build של Ops בכרטיסייה שנפתחה קודם או בלחיצה על הקישור הבא:
echo https://console.cloud.google.com/cloud-build/builds?project=$TF_VAR_ops_project_name
  1. אחרי שהבנייה מסתיימת בהצלחה, פותחים שוב את חזית האתר של Hipstershop. הפעם לא אמורות להופיע שגיאות בדף הבית, כי לחלק הקדמי יש הרשאה מפורשת לגשת לשירות הנוכחי.
  2. עכשיו, נסו לבצע תשלום: הוסיפו פריטים לעגלת הקניות ולחצו על 'ביצוע הזמנה'. בפעם הזו, אמורה להופיע שגיאה בהמרת המחיר משירות המטבעות – הסיבה לכך היא שהוספנו לרשימת ההיתרים רק את הקצה הקדמי, ולכן עדיין אין לשירות התשלומים גישה לשירות המטבעות.

7e30813d693675fe.png

  1. לבסוף, נוסיף עוד כלל למדיניות ההרשאות של שירות המטבעות כדי לאפשר לשירות התשלום גישה למטבע. חשוב לדעת: אנחנו פותחים גישה למטבע רק לשני השירותים שצריכים גישה אליו – חזית האתר ודף התשלום. הקצה העורפי האחר עדיין ייחסם.
  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. אפשר לראות את הסטטוס של פרויקט Cloud Build של Ops בכרטיסייה שנפתחה קודם או בלחיצה על הקישור הבא:
echo https://console.cloud.google.com/cloud-build/builds?project=$TF_VAR_ops_project_name
 
  1. אחרי שהבנייה מסתיימת בהצלחה, מנסים להפעיל תשלום – זה אמור לעבוד בהצלחה.

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

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 באשכול ops באזור 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 מותקן באשכול החדש של צוות התפעול. לשם כך, בודקים שכל ה-pods פועלים ושהעבודות הושלמו.
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 יקבע את סף הפתיחה של מפסק הזרם. במקרה הזה, כל שנייה (interval), ‏ Envoy יספור את מספר השגיאות שהוא קיבל ממאגר התגים בצד השרת. אם הערך חורג מסף consecutiveErrors, מפסק הזרם של Envoy ייפתח, ו-100% מה-pods של 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 של הלקוח שבו נשתמש כדי להפעיל את מפסק הזרם של shippingservice.
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. בואו נבדוק את זה ב-pod של fortio:
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. הזרקת תקלות

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

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

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

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 שנפרס בקטע של מפסק הזרם, ושולחים עומס תנועה קל לשירות ההמלצות.
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. לוחצים על 'תצוגה מקדימה' ביציאה 3000 (הערה: אם היציאה היא לא 3000, לוחצים על 'שינוי יציאה' ובוחרים ביציאה 3000).
  4. תיפתח כרטיסייה בדפדפן עם כתובת URL שדומה ל-BASE_URL/?orgId=1&authuser=0&environment_id=default
  5. הצגת מרכזי הבקרה הזמינים
  6. משנים את כתובת ה-URL ל-" BASE_URL/dashboard"
  7. לוחצים על התיקייה istio כדי לראות את לוחות הבקרה הזמינים.
  8. אפשר ללחוץ על אחד מלוחות הבקרה האלה כדי לראות את הביצועים של הרכיב. בקטעים הבאים נבחן את המדדים החשובים של כל רכיב.

תוכנית פיילוט למעקב

‫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 במסגרת תוכניות פיילוט.

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

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

פרטי Envoy

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

מיקסר לניטור

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

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

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

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

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

Resource Usage

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

87ed83238f9addd8.png

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

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

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

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

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

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

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

כדי לקבל עזרה באבחון בעיות, אפשר לפנות לתמיכה של 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}