פריסת אפליקציית ASP.NET Core ב-Google Kubernetes Engine באמצעות Istio (חלק 2)

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

בחלק הראשון של שיעור ה-Lab יצרתם אפליקציית ASP.NET Core, פרסתם קונטיינרים ופרסתם אותה ב-Google Kubernetes Engine (GKE) והגדרתם את תעבורת הנתונים שלה לניהול על ידי Istio.

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

מה תלמדו

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

למה תזדקק?

איך תשתמשו במדריך הזה?

לקריאה בלבד לקרוא אותו ולבצע את התרגילים

איזה דירוג מגיע לחוויה שלך עם Google Cloud Platform?

מתחילים בינונית בקיאים

2. הגדרה ודרישות

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

  1. נכנסים למסוף Cloud ויוצרים פרויקט חדש או עושים שימוש חוזר בפרויקט קיים. (אם עדיין אין לכם חשבון Gmail או G Suite, עליכם ליצור חשבון).

H_hgylo4zxOllHaAbPKJ7VyqCKPDUnDhkr-BsBIFBsrB6TYSisg6LX-uqmMhh4sXUy_hoa2Qv87C2nFmkg-QAcCiZZp0qtpf6VPaNEEfP_iqt29KVLD-gklBWugQVeOWsFnJmNjHDw

dcCPqfBIwNO4R-0fNQLUC4aYXOOZhKhjUnakFLZJGeziw2ikOxGjGkCHDwN5x5kCbPFB8fiOzZnX-GfuzQ8Ox-UU15BwHirkVPR_0RJwl0oXrhqZmMIvZMa_uwHugBJIdx5-bZ6Z8Q

jgLzVCxk93d6E2bbonzATKA4jFZReoQ-fORxZZLEi5C3D-ubnv6nL-eP-iyh7qAsWyq_nyzzuEoPFD1wFOFZOe4FWhPBJjUDncnTxTImT3Ts9TM54f4nPpsAp52O0y3Cb19IceAEgQ

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

  1. בשלב הבא צריך להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבים של Google Cloud.

מעבר ב-Codelab הזה לא אמור לעלות הרבה, אם בכלל. חשוב לבצע את כל ההוראות בקטע 'ניקוי' שמסביר איך להשבית משאבים כדי שלא תצברו חיובים מעבר למדריך הזה. משתמשים חדשים ב-Google Cloud זכאים להשתתף בתוכנית תקופת ניסיון בחינם בשווי 1,200 ש"ח.

הפעלת Cloud Shell

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

הפעלת Cloud Shell

  1. במסוף Cloud, לוחצים על Activate Cloud Shell dnDTxS9j60RcXdTjea12HLB9paS9Gzf7PfFLE9RW8g0Qx1bz7nmCzyCu4rjluX3bOEwavOpDwioXEkzOf6xtZp6-ZbJa08jwJqtmeeW8p9P1bz7nmCzyCu4rjluX3bOEwavOpDwioXEkzOf6xtZp6-ZbJa08jwJqtmeeW8p1.

yzBQBp2RC1EFvSSLYVkMA2m6LHqGsp22O81rUS5tGb9Y1FqlVhoRj_ka8V_uEjtpcirZRULMy1IjNr848uYvb9mC9RcGGqeayaLcXFfRwUGeXWChZPtWkHzUshTcqx_wJHis0X8viA

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

VgsaqGbKPRiqK24CqAKjSXjepuJT96PmiDqQMcySmWKx8QyW5F3G2D8JH2d08ek-YM77wWKxPvggpOFER8Hbq3aaZipTDU2o0N7A0kS3FXjDzukF

ההקצאה וההתחברות ל-Cloud Shell נמשכת כמה דקות.

7RuYr-LCKzdiE1veTFmL_lYrVxsMZ6-xDoxAnfwPPc5uFA0utmFGejvu81jGmTdbqnqxrytW3KcHT6xrMIRc3bskctnDZC5nJdpqw-LRxu3r35hL4A0BSBTtbtirfh3PKv-eOKt8Rg

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

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

  1. מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שהאימות בוצע:
gcloud auth list

פלט הפקודה

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
gcloud config list project

פלט הפקודה

[core]
project = <PROJECT_ID>

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

gcloud config set project <PROJECT_ID>

פלט הפקודה

Updated property [core/project].

3. בדיקת האפליקציה

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

kubectl get svc istio-ingressgateway -n istio-system

כדי להציג את האפליקציה, אפשר לפתוח את הדפדפן ולנווט אל http://<gatewayurl>:

f579a9baedc108a9.png

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

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

בשלב הבא נתחיל לבחון את המדדים.

4. מדדים עם Grafana ו-Prometheus

כברירת מחדל, Istio יוצר מדדים מסוימים. תוכלו להשתמש בתוספים כדי להריץ שאילתות על מדדי ברירת המחדל האלה ולהמחיש אותם באופן חזותי.

Prometheus

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

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.8/samples/addons/prometheus.yaml

מוודאים ש-Prometheus פועל:

kubectl get svc prometheus -n istio-system

NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
prometheus   ClusterIP   10.31.243.62   <none>        9090/TCP   1d

כדי לשלוח מעט תעבורת נתונים לאפליקציה, צריך להיכנס ל-http://<gatewayurl> כמה פעמים או להריץ את פקודת ה-curl.

הגדרת העברה ליציאה אחרת עבור ממשק המשתמש של Prometheus:

kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') 8080:9090

עכשיו אפשר להריץ שאילתה על ידי לחיצה על לחצן Web Preview בפינה הימנית העליונה של Cloud Shell, וללחוץ על Preview on Port 8080:

772a5248aa493025.png

ממשק המשתמש של Prometheus יופיע בכרטיסייה חדשה:

272ee63c1fe0be16.png

למידע נוסף על Prometheus, ראו שליחת שאילתות למדדי Prometheus.

Grafana

Grafana הוא תוסף נוסף להמחשת מדדים.

מתקינים את Grafana. מחליפים את istio-version בגרסה הנוכחית של Istio,לדוגמה, 1.0.3-gke.3:

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.8/samples/addons/grafana.yaml

מוודאים ש-Grafana פועל:

kubectl get svc grafana -n istio-system

NAME      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
grafana   ClusterIP   10.31.248.230   <none>        3000/TCP   1d

כדי לשלוח מעט תעבורת נתונים לאפליקציה, צריך להיכנס ל-http://<gatewayurl> כמה פעמים או להריץ את פקודת ה-curl.

הגדרת העברה ליציאה אחרת בממשק המשתמש של Grafana:

kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana -o jsonpath='{.items[0].metadata.name}') 8080:3000

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

806d696d85267a37.png

524cb9f6d66f8655.png

למידע נוסף על Granfana, ראו המחשה של מדדים באמצעות Grafana.

5. יצירת גרסה חדשה של האפליקציה

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

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

mxrggIJ2Zz8E47ULCEo4NywjM-EpSkZF5c3TQgfGx4nODwP2obiQXrwQjEEaXuBhJDA2jJ5evR7TuHIy1gsqqDRFm0Wh3xhZUu9tn_xb1ygFlBm1HKJqLdfz_aK7WJS33u2IBDO2oQ

צריך לעבור אל Index.cshtml בקטע HelloWorldAspNetCore > Views > Home ולעדכן את אחת מהודעות הקרוסלה.

מוצאים את השורה הבאה:

Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core 

ומשנים אותה לדוגמה:

Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core on Google Cloud

שומרים את השינויים וחוזרים אל Cloud Shell. בתוך HelloWorldAspNetCore,יוצרים את קובץ האימג' של ה-Docker:

docker build -t gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v2 . 

ודחיפה ל-Container Registry:

docker push gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v2 

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

6. יצירת הפריסה החדשה

כדי לפרוס את הגרסה החדשה, קודם צריך ליצור עבורה פריסה חדשה ב-Kubernetes. מוסיפים את הקוד הבא בסוף הקובץ aspnetcore.yaml:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: aspnetcore-v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: aspnetcore
      version: v2
  template:
    metadata:
      labels:
        app: aspnetcore
        version: v2
    spec:
      containers:
      - name: aspnetcore
        image: gcr.io/YOUR-PROJECT-ID/hello-dotnet:v2
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

פורסים את הגרסה החדשה במרחב השמות שמוגדר כברירת מחדל בעזרת kubectl:

kubectl apply -f aspnetcore.yaml
service "aspnetcore" unchanged
deployment.extensions "aspnetcore-v1" unchanged
deployment.extensions "aspnetcore-v2" created

מוודאים שה-Pods הצפויים פועלים:

kubectl get pods
NAME                          READY     STATUS    RESTARTS   AGE
aspnetcore-v1-6cf64748-mddb   2/2       Running   0          34s
aspnetcore-v2-5d765db-l9xmg   2/2       Running   0          1m

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

kubectl get svc istio-ingressgateway -n istio-system

הוא רשום תחת EXTERNAL-IP. פותחים דפדפן מצב פרטי ועוברים אל http://<replace-with-external-ip>.

בזמן רענון, לפעמים מופיעה ההודעה 'מידע על בניית אפליקציות אינטרנט באמצעות ASP.NET Core':

11d528132dbb6cee.png

במקרים אחרים תופיע ההודעה 'מידע על פיתוח אפליקציות אינטרנט באמצעות ASP.NET Core ב-Google Cloud':

3eb0d5be1b4cb40b.png

הסיבה לכך היא שגם הפריסות של v1 וגם הפריסות v2 חשופות מאחורי אותו שירות Kubernetes (aspnetcore-service) וה-VirtualService שיצרת בשיעור ה-Lab הקודם (aspnetcore-virtualservice) משתמש/ת בשירות הזה כמארח.

בשלב הבא, מצמידים את השירות לפריסה של v2 באמצעות DestinationRule.

7. הצמדת השירות לגרסה החדשה

בשלב הזה, אפשר להצמיד את השירות כדי שישתמש בפריסה של v2, ולעשות זאת באמצעות DestinationRule. כלל יעד מגדיר את קבוצת כללי המדיניות שיש להחיל על בקשה אחרי שמתרחשת פעולת ניתוב VirtualService.

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

יוצרים קובץ חדש בשם aspnetcore-destinationrule.yaml:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: aspnetcore-destinationrule
spec:
  host: aspnetcore-service
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

בשלב הבא, יוצרים את כלל היעד. הפעולה הזו יוצרת שתי קבוצות משנה (v1 ו-v2) שבהן תוכלו להשתמש מ-VirtualService:

kubectl apply -f aspnetcore-destinationrule.yaml
destinationrule.networking.istio.io "aspnetcore-destionationrule" created

עכשיו חוזרים אל הקובץ aspnetcore-virtualservice.yaml כדי לעדכן את VirtualService ולהשתמש בקבוצת המשנה v2:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - route:
    - destination:
        host: aspnetcore-service
        subset: v2

מעדכנים את VirtualService:

kubectl apply -f aspnetcore-virtualservice.yaml

פותחים את הדפדפן ועוברים אל http://<replace-with-external-ip>. גם אחרי כמה רענון, ההודעה 'מידע על פיתוח אפליקציות אינטרנט באמצעות ASP.NET Core ב-Google Cloud' צריכה להופיע:

3eb0d5be1b4cb40b.png

8. פיצול התנועה בין גרסאות

לפעמים רוצים לפצל את התנועה בין הגרסאות כדי לבדוק את הגרסה. לדוגמה, ייתכן שתרצו לשלוח 75% מהתנועה לגרסה v1 ו-25% מהתנועה לגרסה 2 של השירות. אפשר לעשות זאת בקלות ב-Istio. יוצרים קובץ aspnetcore-virtualservice-weights.yaml חדש כדי להתייחס לשתי קבוצות המשנה עם משקלים שונים:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - route:
    - destination:
        host: aspnetcore-service
        subset: v1
      weight: 75
    - destination:
        host: aspnetcore-service
        subset: v2
      weight: 25

מעדכנים את VirtualService:

kubectl apply -f aspnetcore-virtualservice-weights.yaml

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

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

9. שגיאות בהזרקה

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

לדוגמה, יכול להיות שתרצו להחזיר תגובת בקשה שגויה (HTTP 400) עבור 50% מהתנועה לגרסה 1. יוצרים קובץ aspnetcore-virtualservice-fault-abort.yaml שתואם לדברים הבאים:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - fault:
      abort:
        percentage:
          value: 50
        httpStatus: 400
    route:
    - destination:
        host: aspnetcore-service
        subset: v1

מעדכנים את VirtualService:

kubectl apply -f aspnetcore-virtualservice-fault-abort.yaml

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

לחלופין, אפשר להוסיף לבקשות השהיה של 5 שניות. יוצרים קובץ aspnetcore-virtualservice-fault-delay.yaml שתואם לדברים הבאים:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - fault:
      delay:
        fixedDelay: 5s
        percentage:
          value: 100
    route:
    - destination:
        host: aspnetcore-service
        subset: v1

מעדכנים את VirtualService:

kubectl apply -f aspnetcore-virtualservice-fault-delay.yaml

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

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

10. מעולה!

אני מקווה ששיעור ה-Lab הזה נתן לך סקירה כללית על מה ש-Istio יכול לעשות בעזרת השירותים שלך. למידע נוסף על Istio ו-GKE.

השלבים הבאים

רישיון

היצירה הזו בשימוש ברישיון Creative Commons Attribution 2.0 גנרי.

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

אפשר למחוק את האפליקציה ולהסיר את Istio או פשוט למחוק את אשכול Kubernetes.

מחיקת האפליקציה

כדי למחוק את האפליקציה:

kubectl delete -f aspnetcore-gateway.yaml
kubectl delete -f aspnetcore-virtualservice.yaml
kubectl delete -f aspnetcore-destinationrule.yaml
kubectl delete -f aspnetcore.yaml

כדי לוודא שהאפליקציה נעלמה:

kubectl get gateway 
kubectl get virtualservices
kubectl get destinationrule
kubectl get pods

איך מסירים את Istio

כדי למחוק את Istio:

kubectl delete -f install/kubernetes/istio-demo-auth.yaml

כדי לאשר ש-Istio לא נמצא:

kubectl get pods -n istio-system

מחיקת אשכול Kubernetes

gcloud container clusters delete hello-dotnet-cluster