Cloud Service Mesh by example: Authorization

במדריך הזה נסביר מהי הרשאה ואיך להפעיל אותה באמצעות Cloud Service Mesh באפליקציה לדוגמה, כדי ללמוד איך להפעיל כללי מדיניות של הרשאות במיקרו-שירותים (microservices). תיצרו AuthorizationPolicy כדי DENY גישה למיקרו-שירות, ואז תיצרו AuthorizationPolicy כדי ALLOW גישה ספציפית למיקרו-שירות.

מה זה אישור?

אימות מאשר את הזהות – האם השירות הזה הוא מי שהוא טוען שהוא? ההרשאה מאמתת את ההרשאה – האם לשירות הזה מותר לעשות את זה? הזהות היא חלק בסיסי מהרעיון הזה. בעזרת Cloud Service Mesh, אפשר להשתמש ב-AuthorizationPolicies כדי לשלוט בתקשורת בין עומסי העבודה ברשת, וכך לשפר את האבטחה והגישה.

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

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

במאמר הרשאה באמצעות Cloud Service Mesh מוסבר בהרחבה איך להגדיר כללי מדיניות ושיטות מומלצות.

עלויות

המדריך הזה משתמש ברכיבים הבאים של Google Cloud, והשימוש בהם כרוך בתשלום:

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

לפני שמתחילים

פריסת שער כניסה

  1. מגדירים את ההקשר הנוכחי של kubectl לאשכול:

    gcloud container clusters get-credentials CLUSTER_NAME  \
        --project=PROJECT_ID \
        --zone=CLUSTER_LOCATION 
    
  2. יוצרים מרחב שמות לשער הכניסה:

    kubectl create namespace asm-ingress
    
  3. מפעילים את מרחב השמות להזרקה. השלבים תלויים בהטמעה של מישור הבקרה.

    מנוהל (TD)

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

    kubectl label namespace asm-ingress \
        istio.io/rev- istio-injection=enabled --overwrite
    

    מנוהל (Istiod)

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

    kubectl label namespace asm-ingress \
        istio.io/rev- istio-injection=enabled --overwrite
    

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

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

      kubectl -n istio-system get controlplanerevision
      

      הפלט אמור להיראות כך:

      NAME                AGE
      asm-managed-rapid   6d7h
      

      בפלט, הערך בעמודה NAME הוא תווית הגרסה שתואמת לערוץ ההפצה הזמין של גרסת Cloud Service Mesh.

    2. מחילים את תווית הגרסה על מרחב השמות:

      kubectl label namespace asm-ingress \
          istio-injection- istio.io/rev=REVISION_LABEL --overwrite
      

    בתוך האשכול

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

    kubectl label namespace asm-ingress \
        istio.io/rev- istio-injection=enabled --overwrite
    

    מומלץ להשתמש בהזרקה כברירת מחדל, אבל יש תמיכה בהזרקה מבוססת-גרסה: כך עושים את זה:

    1. כדי לאתר את תווית הגרסה ב-istiod, משתמשים בפקודה הבאה:

      kubectl get deploy -n istio-system -l app=istiod -o \
          jsonpath={.items[*].metadata.labels.'istio\.io\/rev'}'{"\n"}'
      
    2. מחילים את תווית הגרסה על מרחב השמות. בפקודה הבאה, REVISION_LABEL הוא הערך של תווית הגרסה istiod שציינתם בשלב הקודם.

      kubectl label namespace asm-ingress \
          istio-injection- istio.io/rev=REVISION_LABEL --overwrite
      
  4. פורסים את שער ה-API לדוגמה במאגר anthos-service-mesh-samples:

    kubectl apply -n asm-ingress \
        -f docs/shared/asm-ingress-gateway
    

    הפלט אמור להיראות כך:

    serviceaccount/asm-ingressgateway configured
    service/asm-ingressgateway configured
    deployment.apps/asm-ingressgateway configured
    gateway.networking.istio.io/asm-ingressgateway configured
    

פריסת האפליקציה לדוגמה Online Boutique

  1. אם עדיין לא עשיתם זאת, הגדירו את ההקשר הנוכחי של kubectl לאשכול:

    gcloud container clusters get-credentials CLUSTER_NAME  \
      --project=PROJECT_ID \
      --zone=CLUSTER_LOCATION 
    
  2. יוצרים את מרחב השמות של האפליקציה לדוגמה:

    kubectl create namespace onlineboutique
    
  3. מוסיפים תווית למרחב השמות onlineboutique כדי להוסיף באופן אוטומטי שרתי proxy של Envoy:

    kubectl label namespace onlineboutique \
       istio.io/rev- istio-injection=enabled --overwrite
    
  4. פורסים את האפליקציה לדוגמה, את VirtualService בשביל ה-frontend ואת חשבונות השירות בשביל עומסי העבודה. במדריך הזה תפרסו את Online Boutique, אפליקציית הדגמה של מיקרו-שירותים (microservices).

    kubectl apply \
      -n onlineboutique \
      -f docs/shared/online-boutique/virtual-service.yaml
    
    kubectl apply \
      -n onlineboutique \
      -f docs/shared/online-boutique/service-accounts
    

הצגת השירותים שלך

  1. מציגים את הפודים במרחב השמות onlineboutique:

    kubectl get pods -n onlineboutique
    

    הפלט אמור להיראות כך:

    NAME                                     READY   STATUS    RESTARTS   AGE
    adservice-85598d856b-m84m6               2/2     Running   0          2m7s
    cartservice-c77f6b866-m67vd              2/2     Running   0          2m8s
    checkoutservice-654c47f4b6-hqtqr         2/2     Running   0          2m10s
    currencyservice-59bc889674-jhk8z         2/2     Running   0          2m8s
    emailservice-5b9fff7cb8-8nqwz            2/2     Running   0          2m10s
    frontend-77b88cc7cb-mr4rp                2/2     Running   0          2m9s
    loadgenerator-6958f5bc8b-55q7w           2/2     Running   0          2m8s
    paymentservice-68dd9755bb-2jmb7          2/2     Running   0          2m9s
    productcatalogservice-84f95c95ff-c5kl6   2/2     Running   0          114s
    recommendationservice-64dc9dfbc8-xfs2t   2/2     Running   0          2m9s
    redis-cart-5b569cd47-cc2qd               2/2     Running   0          2m7s
    shippingservice-5488d5b6cb-lfhtt         2/2     Running   0          2m7s
    

    כל ה-pods של האפליקציה אמורים לפעול, עם 2/2 בעמודה READY. זה מצביע על כך שהוזרק בהצלחה קובץ עזר חיצוני של Envoy לפודים. אם לא מופיע 2/2 אחרי כמה דקות, כדאי לעיין במדריך לפתרון בעיות.

  2. משיגים את כתובת ה-IP החיצונית ומגדירים אותה למשתנה:

    kubectl get services -n asm-ingress
    export FRONTEND_IP=$(kubectl --namespace asm-ingress \
    get service --output jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}' \
    )
    

    הפלט אמור להיראות כך:

    NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                      AGE
    asm-ingressgateway   LoadBalancer   10.19.247.233   35.239.7.64   80:31380/TCP,443:31390/TCP,31400:31400/TCP   27m
    
    
  3. נכנסים לכתובת EXTERNAL-IP בדפדפן האינטרנט. החנות Online Boutique אמורה להופיע בדפדפן.

    ממשק משתמש של בוטיק אונליין

הרשאת DenyAll לעומס עבודה

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

  1. מחילים AuthorizationPolicy על currencyservice. שימו לב להתאמה בתווית currencyservice בקובץ ה-YAML.

    kubectl apply -f docs/authorization/currency-deny-all.yaml -n onlineboutique
    
    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: currency-policy
    spec:
      selector:
        matchLabels:
          app: currencyservice
  2. נסו לגשת ל-EXTERNAL-IP של השער כדי לראות את Online Boutique בדפדפן האינטרנט. אמורה להופיע שגיאת הרשאה (500 שגיאת שרת פנימית) מ-currency service.

    שגיאת authz rbac 500

בדיקת היומנים של קובץ העזר החיצוני

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

  1. משיגים את השם של pod של currencyservice:

    CURRENCY_POD=$(kubectl get pod -n onlineboutique |grep currency|awk '{print $1}')
    
  2. מגדירים את שרת ה-proxy של Envoy כך שיאפשר יומנים ברמת המעקב. כברירת מחדל, קריאות הרשאה חסומות לא נרשמות ביומן:

    kubectl debug --image istio/base --target istio-proxy -it $CURRENCY_POD -n onlineboutique -- curl -X POST "http://localhost:15000/logging?level=trace"
    

    הפלט הצפוי: none {:.devsite-disable-click-to-copy} active loggers: admin: trace alternate_protocols_cache: trace ... tracing: trace upstream: trace udp: trace wasm: trace

  3. משתמשים ב-curl כדי לשלוח תנועה אל EXTERNAL_IP וליצור יומנים:

    for i in {0..10}; do
    curl -s -I $FRONTEND_IP ; done
    
  4. צפייה ביומנים שקשורים לבקרת גישה מבוססת-תפקידים (RBAC) ב-istio-proxy:

    kubectl logs -n onlineboutique $CURRENCY_POD -c istio-proxy | grep -m5 rbac
    

    הפלט אמור להיראות כך:

    2022-07-08T14:19:20.442920Z     debug   envoy rbac      checking request: requestedServerName: outbound_.7000_._.currencyservice.onlineboutique.svc.cluster.local, sourceIP: 10.8.8.5:34080, directRemoteIP: 10.8.8.5:34080, remoteIP: 10.8.8.5:34080,localAddress: 10.8.0.6:7000, ssl: uriSanPeerCertificate: spiffe://christineskim-tf-asm.svc.id.goog/ns/onlineboutique/sa/default, dnsSanPeerCertificate: , subjectPeerCertificate: OU=istio_v1_cloud_workload,O=Google LLC,L=Mountain View,ST=California,C=US, headers: ':method', 'POST'
    2022-07-08T14:19:20.442944Z     debug   envoy rbac      enforced denied, matched policy none
    2022-07-08T14:19:20.442965Z     debug   envoy http      [C73987][S13078781800499437460] Sending local reply with details rbac_access_denied_matched_policy[none]
      ```
    

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

מתן גישה מוגבלת

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

בקטע הזה תפעילו את היכולת של השירותים frontend ו-checkout לתקשר עם השירות currency.

  1. בקובץ הבא, אפשר לראות של-source.principal(לקוח) ספציפי יש הרשאת גישה ל-currencyservice:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: currency-policy
spec:
  selector:
    matchLabels:
      app: currencyservice
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/onlineboutique/sa/frontend"]
  - from:
    - source:
        principals: ["cluster.local/ns/onlineboutique/sa/checkoutservice"]
  1. מחילים את המדיניות:

    kubectl apply -f docs/authorization/currency-allow-frontend-checkout.yaml -n onlineboutique
    
  2. נכנסים לכתובת EXTERNAL-IP בדפדפן האינטרנט. עכשיו אמורה להיות לכם גישה ל-Online Boutique.

הסרת המשאבים

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

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

מחיקת הפרויקט

מוחקים את הפרויקט ב-Cloud Shell:

  gcloud projects delete PROJECT_ID

מחיקת המשאבים

  • אם רוצים להשאיר את האשכול ולהסיר את הדוגמה של Online Boutique:

    1. מוחקים את מרחבי השמות של האפליקציה:

      kubectl delete namespace onlineboutique
      

      הפלט אמור להיראות כך:

      namespace "onlineboutique" deleted
      
    2. מוחקים את מרחב השמות של Ingress Gateway:

      kubectl delete namespace asm-ingress
      

      הפלט אמור להיראות כך:

      namespace "asm-ingress" deleted
      
  • כדי למנוע חיובים נוספים, צריך למחוק את האשכול:

    gcloud container clusters delete CLUSTER_NAME  \
      --project=PROJECT_ID \
      --zone=CLUSTER_LOCATION 
    

המאמרים הבאים