ב-Cloud Service Mesh מגרסה 1.5 ואילך, פרוטוקול Mutual TLS (mTLS) מופעל אוטומטית כברירת מחדל. עם mTLS אוטומטי, שרת proxy של קובץ עזר חיצוני בצד הלקוח מזהה באופן אוטומטי אם לשרת יש קובץ עזר חיצוני. ה-sidecar בצד הלקוח שולח mTLS לעומסי עבודה עם sidecars, ושולח טקסט פשוט לעומסי עבודה בלי sidecars. עם זאת, חשוב לזכור שהשירותים מקבלים גם תנועה בטקסט פשוט וגם תנועה ב-mTLS. כשאתם מזריקים קובצי עזר חיצוניים לפודים, מומלץ גם להגדיר את השירותים כך שיקבלו רק תנועת mTLS.
באמצעות Cloud Service Mesh, אתם יכולים לאכוף mTLS מחוץ לקוד האפליקציה, על ידי החלה של קובץ YAML יחיד. Cloud Service Mesh מאפשר לכם להחיל מדיניות אימות על כל רשת השירות, על מרחב שמות או על עומס עבודה ספציפי.
עלויות
במסמך הזה משתמשים ברכיבים הבאים של Google Cloud, והשימוש בהם כרוך בתשלום:
בעזרת מחשבון העלויות אתם יכולים להעריך את העלויות בהתאם לשימוש הצפוי.
כדי להימנע מעלויות נוספות אחרי שסיימתם את המדריך, אתם יכולים למחוק את המשאבים שיצרתם. מידע נוסף זמין בקטע הסרת המשאבים.
לפני שמתחילים
מוודאים שהחיוב מופעל בפרויקט.
הקצאת Cloud Service Mesh באשכול GKE. יש כמה שיטות הגדרה נתמכות:
משכפלים את המאגר:
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples cd anthos-service-mesh-samples
פריסת שער כניסה
מגדירים את ההקשר הנוכחי של
kubectlלאשכול:gcloud container clusters get-credentials CLUSTER_NAME \ --project=PROJECT_ID \ --zone=CLUSTER_LOCATIONיוצרים מרחב שמות לשער הכניסה:
kubectl create namespace asm-ingressמפעילים את מרחב השמות להזרקה. השלבים תלויים בהטמעה של מישור הבקרה.
מנוהל (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: אנחנו ממליצים להשתמש בהחדרה כברירת מחדל, אבל יש תמיכה בהחדרה מבוססת-גרסה. פועלים לפי ההוראות הבאות:
מריצים את הפקודה הבאה כדי לאתר את ערוצי ההפצה הזמינים:
kubectl -n istio-system get controlplanerevisionהפלט אמור להיראות כך:
NAME AGE asm-managed-rapid 6d7hבפלט, הערך בעמודה
NAMEהוא תווית הגרסה שתואמת לערוץ ההפצה הזמין של גרסת Cloud Service Mesh.מחילים את תווית הגרסה על מרחב השמות:
kubectl label namespace asm-ingress \ istio-injection- istio.io/rev=REVISION_LABEL --overwrite
פורסים את שער ה-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
אם עדיין לא עשיתם זאת, הגדירו את ההקשר הנוכחי של
kubectlלאשכול:gcloud container clusters get-credentials CLUSTER_NAME \ --project=PROJECT_ID \ --zone=CLUSTER_LOCATIONיוצרים את מרחב השמות של האפליקציה לדוגמה:
kubectl create namespace onlineboutiqueמוסיפים תווית למרחב השמות
onlineboutiqueכדי להוסיף באופן אוטומטי שרתי proxy של Envoy. פועלים לפי השלבים להפעלת החדרת sidecar אוטומטית.פורסים את האפליקציה לדוגמה, את
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
הצגת השירותים שלך
מציגים את הפודים במרחב השמות
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אחרי כמה דקות, כדאי לעיין במדריך לפתרון בעיות.משיגים את כתובת ה-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נכנסים לכתובת
EXTERNAL-IPבדפדפן האינטרנט. החנות Online Boutique אמורה להופיע בדפדפן.
יצירת pod של TestCurl
יוצרים pod של TestCurl כדי לשלוח תנועה בטקסט פשוט לצורך בדיקה.
apiVersion: v1
kind: Pod
metadata:
name: testcurl
namespace: default
annotations:
sidecar.istio.io/inject: "false"
spec:
containers:
- name: curl
image: curlimages/curl
command: ["sleep", "600"]
גישה ל-Online Boutique
מגדירים את ההקשר הנוכחי של
kubectlלאשכול שבו פרסתם את Online Boutique:gcloud container clusters get-credentials CLUSTER_NAME \ --project=PROJECT_ID \ --zone=CLUSTER_LOCATIONמציגים את רשימת השירותים במרחב השמות
frontend:kubectl get services -n frontendשימו לב ש-
frontend-externalהואLoadBalancer, ויש לו כתובת IP חיצונית. האפליקציה לדוגמה כוללת שירות שהוא מאזן עומסים, כדי שאפשר יהיה לפרוס אותה ב-GKE בלי Cloud Service Mesh.נכנסים לאפליקציה בדפדפן באמצעות כתובת ה-IP החיצונית של השירות
frontend-external:http://FRONTEND_EXTERNAL_IP/ב-Cloud Service Mesh אפשר לפרוס שער כניסה. אפשר גם לגשת ל-Online Boutique באמצעות כתובת ה-IP החיצונית של שער הכניסה. משיגים את כתובת ה-IP החיצונית של השער. מחליפים את ה-placeholders במידע הבא:
- GATEWAY_SERVICE_NAME : השם של שירות שער הכניסה. אם פרסתם את שער הדוגמה בלי שינויים, או אם פרסתם את שער ברירת המחדל של Ingress, השם הוא
istio-ingressgateway. - GATEWAY_NAMESPACE: מרחב השמות שבו פרסתם את שער הכניסה. אם פרסתם את שער הכניסה שמוגדר כברירת מחדל, מרחב השמות הוא
istio-system.
kubectl get service GATEWAY_NAME -n GATEWAY_NAMESPACE- GATEWAY_SERVICE_NAME : השם של שירות שער הכניסה. אם פרסתם את שער הדוגמה בלי שינויים, או אם פרסתם את שער ברירת המחדל של Ingress, השם הוא
פותחים כרטיסייה אחרת בדפדפן ונכנסים לאפליקציה באמצעות כתובת ה-IP החיצונית של שער הכניסה:
http://INGRESS_GATEWAY_EXTERNAL_IP/מריצים את הפקודה הבאה כדי
curlאת השירותfrontendבאמצעות HTTP פשוט מ-Pod אחר. מכיוון שהשירותים נמצאים במרחבי שמות שונים, צריך להפעיל את הפקודה curl על שם ה-DNS של השירותfrontend.kubectl debug --image istio/base --target istio-proxy -it \ $(kubectl get pod -l app=productcatalogservice -n product-catalog -o jsonpath={.items..metadata.name}) \ -n product-catalog -- \ curl http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'הבקשה מצליחה עם הסטטוס
200, כי כברירת מחדל, גם תנועת TLS וגם תנועת טקסט פשוט מתקבלות.
הפעלת Mutual TLS לכל מרחב שמות
כדי לאכוף את mTLS, צריך להחיל מדיניות PeerAuthentication באמצעות kubectl.
שומרים את מדיניות האימות הבאה בתור
mtls-namespace.yaml.cat <<EOF > mtls-namespace.yaml apiVersion: "security.istio.io/v1beta1" kind: "PeerAuthentication" metadata: name: "namespace-policy" spec: mtls: mode: STRICT EOFהשורה
mode: STRICTבקובץ ה-YAML מגדירה את השירותים כך שיקבלו רק mTLS. כברירת מחדל, הערך שלmodeהואPERMISSIVE, שמגדיר את השירותים כך שיקבלו גם טקסט פשוט וגם mTLS.מחילים את מדיניות האימות כדי להגדיר את כל השירותים של Online Boutique כך שיקבלו רק mTLS:
for ns in ad cart checkout currency email frontend loadgenerator \ payment product-catalog recommendation shipping; do kubectl apply -n $ns -f mtls-namespace.yaml doneהפלט אמור להיראות כך:
peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created
עוברים לכרטיסייה בדפדפן שדרכה ניגשים ל-Online Boutique באמצעות כתובת ה-IP החיצונית של השירות
frontend-external:http://FRONTEND_EXTERNAL_IP/יש לרענן את הדף. בדפדפן מופיעה השגיאה הבאה:

רענון הדף גורם לשליחת טקסט פשוט לשירות
frontend. בגלל מדיניות האימות שלSTRICT, קובץ העזר החיצוני חוסם את הבקשה לשירות.עוברים לכרטיסייה בדפדפן שדרכה ניגשים ל-Online Boutique באמצעות כתובת ה-IP החיצונית של
istio-ingressgateway, ומרעננים את הדף שמוצג בהצלחה. כשניגשים ל-Online Boutique באמצעות שער הכניסה, הבקשה עוברת בנתיב הבא:תהליך אימות mTLS:
- הדפדפן שולח בקשת HTTP בטקסט פשוט לשרת.
- מאגר ה-proxy של שער הכניסה מיירט את הבקשה.
- שרת ה-proxy של שער הכניסה מבצע לחיצת יד בפרוטוקול TLS עם שרת ה-proxy בצד השרת (שירות החזית בדוגמה הזו). הלחיצת היד הזו כוללת החלפת אישורים. האישורים האלה נטענים מראש לקונטיינרים של שרתי ה-proxy על ידי Cloud Service Mesh.
- שרת ה-proxy של שער הכניסה מבצע בדיקת שמות מאובטחת באישור של השרת, כדי לוודא שזהות מורשית מפעילה את השרת.
- שער הכניסה ושרתי ה-proxy של השרת יוצרים חיבור TLS הדדי (mTLS), ושרת ה-proxy של השרת מעביר את הבקשה לקונטיינר של אפליקציית השרת (השירות בחזית).
מריצים את הפקודה הבאה כדי
curlאת השירותfrontendבאמצעות HTTP פשוט מ-Pod אחר.kubectl exec testcurl -n default -- curl \ http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'הבקשה נכשלת כי אנחנו שולחים תנועה בטקסט פשוט מעומס עבודה ללא sidecar שבו חלה מדיניות
peerAuthenticationמסוג STRICT.
חיפוש ומחיקה של כללי מדיניות אימות
כדי להציג רשימה של כל כללי המדיניות של
PeerAuthenticationב-Service mesh:kubectl get peerauthentication --all-namespacesהפלט אמור להיראות כך:
NAMESPACE NAME MODE AGE ad namespace-policy STRICT 17m cart namespace-policy STRICT 17m checkout namespace-policy STRICT 17m currency namespace-policy STRICT 17m email namespace-policy STRICT 17m frontend namespace-policy STRICT 17m loadgenerator namespace-policy STRICT 17m payment namespace-policy STRICT 17m product-catalog namespace-policy STRICT 17m recommendation namespace-policy STRICT 17m shipping namespace-policy STRICT 17mמוחקים את מדיניות האימות מכל מרחבי השמות של Online Boutique:
for ns in ad cart checkout currency email frontend loadgenerator payment \ product-catalog recommendation shipping; do kubectl delete peerauthentication -n $ns namespace-policy done;הפלט אמור להיראות כך:
peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deletedנכנסים ל-Online Boutique באמצעות כתובת ה-IP החיצונית של השירות
frontend-externalומרעננים את הדף. הדף מוצג כמו שצריך.מריצים את הפקודה הבאה כדי
curlאת השירותfrontendבאמצעות HTTP פשוט מ-Pod אחר.kubectl debug --image istio/base --target istio-proxy -it \ $(kubectl get pod -l app=productcatalogservice -n product-catalog -o jsonpath={.items..metadata.name}) \ -n product-catalog -- \ curl http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'הבקשה מצליחה עם הסטטוס
200, כי כברירת מחדל, גם תנועת TLS וגם תנועת טקסט פשוט מתקבלות.
אם תרעננו את הדף במסוף Google Cloud שבו מוצגת הרשימה Workloads, תראו שהסטטוס של mTLS הוא Permissive.
הפעלת פרוטוקול TLS הדדי (mTLS) לכל עומס עבודה
כדי להגדיר מדיניות PeerAuthentication לעומס עבודה ספציפי, צריך להגדיר את הקטע selector ולציין את התוויות שתואמות לעומס העבודה הרצוי.
עם זאת, Cloud Service Mesh לא יכול לצבור כללי מדיניות ברמת עומס העבודה לתנועת mTLS יוצאת לשירות. כדי לנהל את ההתנהגות הזו, צריך להגדיר כלל יעד.
להחיל מדיניות אימות על עומס עבודה ספציפי. שימו לב איך המדיניות הבאה משתמשת בתוויות ובבוררים כדי לטרגט את הפריסה הספציפית של
frontend.cat <<EOF | kubectl apply -n frontend -f - apiVersion: "security.istio.io/v1beta1" kind: "PeerAuthentication" metadata: name: "frontend" namespace: "frontend" spec: selector: matchLabels: app: frontend mtls: mode: STRICT EOFהפלט אמור להיראות כך:
peerauthentication.security.istio.io/frontend created
מגדירים כלל תואם ליעד.
cat <<EOF | kubectl apply -n frontend -f - apiVersion: "networking.istio.io/v1alpha3" kind: "DestinationRule" metadata: name: "frontend" spec: host: "frontend.demo.svc.cluster.local" trafficPolicy: tls: mode: ISTIO_MUTUAL EOFהפלט אמור להיראות כך:
destinationrule.networking.istio.io/frontend created
נכנסים ל-Online Boutique באמצעות כתובת ה-IP החיצונית של השירות
frontend-externalומרעננים את הדף. הדף לא מוצג כיfrontend serviceמוגדר ל-mTLS שלSTRICT, וקובץ העזר החיצוני חוסם את הבקשה.מריצים את הפקודה הבאה כדי
curlאת השירותfrontendבאמצעות HTTP פשוט מ-Pod אחר.kubectl exec testcurl -n default -- curl \ http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'הבקשה נכשלת כי אנחנו שולחים תנועה בטקסט פשוט מעומס עבודה ללא sidecar שבו חלה מדיניות
peerAuthenticationמסוג STRICT.מוחקים את מדיניות האימות:
kubectl delete peerauthentication -n frontend frontendהפלט אמור להיראות כך:
peerauthentication.security.istio.io "frontend" deletedמוחקים את כלל היעד:
kubectl delete destinationrule -n frontend frontendהפלט אמור להיראות כך:
destinationrule.networking.istio.io "frontend" deleted
אכיפת mTLS בכל רשת השירותים
כדי למנוע מכל השירותים ברשת לקבל תנועה בטקסט פשוט, מגדירים מדיניות PeerAuthentication ברמת הרשת, עם מצב mTLS שמוגדר ל-STRICT.
למדיניות PeerAuthentication ברמת הרשת לא צריך להיות בורר, וצריך להחיל אותה במרחב השמות הבסיסי, istio-system. כשפורסים את המדיניות, מישור הבקרה מקצה באופן אוטומטי אישורי TLS כדי שעומסי העבודה יוכלו לאמת זה את זה.
אכיפת mTLS בכל הרשת:
kubectl apply -f - <<EOF apiVersion: "security.istio.io/v1beta1" kind: "PeerAuthentication" metadata: name: "mesh-wide" namespace: "istio-system" spec: mtls: mode: STRICT EOFהפלט אמור להיראות כך:
peerauthentication.security.istio.io/mesh-wide created
נכנסים ל-Online Boutique באמצעות כתובת ה-IP החיצונית של השירות
frontend-externalומרעננים את הדף. הדף לא מוצג.מריצים את הפקודה הבאה כדי
curlאת השירותfrontendבאמצעות HTTP פשוט מ-Pod אחר.kubectl exec testcurl -n default -- curl \ http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'הבקשה נכשלת כי אנחנו שולחים תנועה בטקסט פשוט מעומס עבודה ללא sidecar שבו חלה מדיניות
peerAuthenticationמסוג STRICT.מוחקים את המדיניות
mesh-wide:kubectl delete peerauthentication -n istio-system mesh-wideהפלט אמור להיראות כך:
peerauthentication.security.istio.io "mesh-wide" deleted
הסרת המשאבים
כדי להימנע מחיובים בחשבון Google Cloud בגלל השימוש במשאבים שנעשה במסגרת המדריך הזה, אפשר למחוק את הפרויקט שמכיל את המשאבים או להשאיר את הפרויקט ולמחוק את המשאבים הנפרדים.
כדי למנוע חיובים נוספים, צריך למחוק את האשכול:
gcloud container clusters delete CLUSTER_NAME \ --project=PROJECT_ID \ --zone=CLUSTER_LOCATIONאם רוצים להשאיר את האשכול ולהסיר את הדוגמה של Online Boutique:
- מוחקים את מרחבי השמות של האפליקציה:
kubectl delete -f online-boutique/kubernetes-manifests/namespacesהפלט אמור להיראות כך:
namespace "ad" deleted namespace "cart" deleted namespace "checkout" deleted namespace "currency" deleted namespace "email" deleted namespace "frontend" deleted namespace "loadgenerator" deleted namespace "payment" deleted namespace "product-catalog" deleted namespace "recommendation" deleted namespace "shipping" deleted- מוחקים את רשומות השירות:
kubectl delete -f online-boutique/istio-manifests/allow-egress-googleapis.yamlהפלט אמור להיראות כך:
serviceentry.networking.istio.io "allow-egress-googleapis" deleted serviceentry.networking.istio.io "allow-egress-google-metadata" deleted
המאמרים הבאים
- במאמר הגדרת אבטחת תעבורה מוסבר איך מגדירים כללי מדיניות של
PeerAuthentication.