ב-Cloud Service Mesh בגרסה 1.5 ואילך, פרוטוקול TLS הדדי אוטומטי (auto mTLS) מופעל כברירת מחדל. עם mTLS אוטומטי, קובץ עזר חיצוני בצד הלקוח מזהה באופן אוטומטי אם לשרת יש קובץ עזר חיצוני. ה-sidecar של הלקוח שולח mTLS לעומסי עבודה עם sidecar ושולח טקסט לא מוצפן לעומסי עבודה בלי sidecar. עם זאת, שירותים מקבלים תעבורה בטקסט פשוט וגם תעבורת mTLS. כשמזריקים פרוקסי מסוג sidecar ל-Pods, מומלץ גם להגדיר את השירותים כך שיקבלו רק תנועה מסוג 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אם אתם משתמשים קיימים במישור הבקרה המנוהל של 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
פורסים את שער לדוגמה במאגר
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לקצה הקדמי ואת חשבונות השירות לעומסי העבודה. במדריך הזה תפרסו את Online Boutique, אפליקציית הדגמה של מיקרו-שירות.kubectl apply \ -n onlineboutique \ -f docs/shared/online-boutique/virtual-service.yaml kubectl apply \ -n onlineboutique \ -f docs/shared/online-boutique/service-accounts
צפייה בשירותים
מציגים את ה-pods במרחב השמות
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כל הפודים של האפליקציה צריכים לפעול, ובעמודה
READYצריך להופיע2/2. המשמעות היא שה-pods קיבלו בהצלחה הזרקה של Envoy sidecar proxy. אם הסמל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 אמורה להופיע בדפדפן.
יצירת פוד TestCurl
יוצרים פוד 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"]
גישה לבוטיק אונליין
מגדירים את ההקשר הנוכחי של
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 אפשר לפרוס שער כניסה. אפשר גם לגשת לחנות המקוונת באמצעות כתובת ה-IP החיצונית של שער הכניסה. מקבלים את כתובת ה-IP החיצונית של השער. מחליפים את ה-placeholders בפרטים הבאים:
- GATEWAY_SERVICE_NAME : השם של שירות שער הכניסה. אם פרסתם את שער הדוגמה ללא שינוי, או אם פרסתם את שער הכניסה שמוגדר כברירת מחדל, השם הוא
istio-ingressgateway. - GATEWAY_NAMESPACE: מרחב השמות שבו פרסתם את שער הכניסה. אם פרסתם את שער הכניסה שמוגדר כברירת מחדל, מרחב השמות הוא
istio-system.
kubectl get service GATEWAY_NAME -n GATEWAY_NAMESPACE- GATEWAY_SERVICE_NAME : השם של שירות שער הכניסה. אם פרסתם את שער הדוגמה ללא שינוי, או אם פרסתם את שער הכניסה שמוגדר כברירת מחדל, השם הוא
פותחים כרטיסייה נוספת בדפדפן ועוברים לאפליקציה באמצעות כתובת ה-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 וגם תעבורת טקסט רגיל מתקבלות.
הפעלת mTLS לכל מרחב שמות
כדי לאכוף 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
עוברים לכרטיסייה בדפדפן שדרכה ניגשים לחנות הווירטואלית באמצעות כתובת ה-IP החיצונית של שירות
frontend-external:http://FRONTEND_EXTERNAL_IP/יש לרענן את הדף. הדפדפן מציג את השגיאה הבאה:

רענון הדף גורם לשליחת טקסט רגיל לשירות
frontend. בגללSTRICTמדיניות האימות, שרת ה-proxy מסוג קובץ עזר חיצוני חוסם את הבקשה לשירות.עוברים לכרטיסייה בדפדפן שדרכה ניגשים ל-Online Boutique באמצעות כתובת ה-IP החיצונית של
istio-ingressgateway, ומרעננים את הדף. הדף מוצג בהצלחה. כשניגשים אל Online Boutique באמצעות שער הכניסה, הבקשה עוברת בנתיב הבא:תהליך האימות של mTLS:
- הדפדפן שולח בקשת HTTP בטקסט לא מוצפן לשרת.
- הבקשה עוברת דרך קונטיינר הפרוקסי של שער הכניסה.
- שרת ה-proxy של שער הכניסה מבצע לחיצת יד בפרוטוקול TLS עם שרת ה-proxy בצד השרת (שירות הקצה הקדמי בדוגמה הזו). הלחיצת יד הזו כוללת החלפה של אישורים. האישורים האלה נטענים מראש למאגרי ה-proxy על ידי Cloud Service Mesh.
- שרת ה-proxy של שער הכניסה מבצע בדיקה מאובטחת של השמות באישור של השרת, כדי לוודא שזהות מורשית מפעילה את השרת.
- שערי הכניסה ושרתי ה-proxy יוצרים חיבור Mutual 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, שבו מוחלת מדיניות STRICT
peerAuthentication.
חיפוש ומחיקה של מדיניות אימות
רשימה של כל כללי המדיניות של
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 הדדי לכל עומס עבודה
כדי להגדיר מדיניות של PeerAuthentication לעומס עבודה ספציפי, צריך להגדיר את הקטע selector ולציין את התוויות שתואמות לעומס העבודה הרצוי.
עם זאת, Cloud Service Mesh לא יכול לצבור מדיניות ברמת עומס העבודה לתעבורת mTLS יוצאת לשירות. כדי לנהל את ההתנהגות הזו, צריך להגדיר כלל יעד.
החלת מדיניות אימות על עומס עבודה ספציפי. שימו לב איך המדיניות הבאה משתמשת בתוויות ובסלקטורים כדי לטרגט את הפריסה הספציפית
frontendcat <<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מוגדר ל-STRICTmTLS, וקובץ העזר החיצוני חוסם את הבקשה.מריצים את הפקודה הבאה כדי
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, שבו מוחלת מדיניות STRICT
peerAuthentication.מחיקת מדיניות האימות:
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, שבו מוחלת מדיניות STRICT
peerAuthentication.מחיקת המדיניות
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זמין במאמר הגדרת אבטחת תעבורה.