הגדרת אבטחת שירות באמצעות Envoy
במדריך הזה מוסבר איך להגדיר אימות והרשאה לשירותים שנפרסו באמצעות Cloud Service Mesh ושרתי proxy של Envoy. מידע מלא על אבטחת שירותים ב-Cloud Service Mesh זמין במאמר אבטחת שירותים ב-Cloud Service Mesh.
דרישות
לפני שמגדירים אבטחת שירותים ב-Cloud Service Mesh באמצעות Envoy, צריך לוודא שההגדרה עומדת בדרישות המוקדמות הבאות:
אתם יכולים לעמוד בכל הדרישות לפריסת Cloud Service Mesh. מידע מלא על הדרישות האלה זמין במאמר הכנה להגדרה של ממשקי API לניתוב שירותים עם Envoy ועומסי עבודה בלי שרת Proxy.
יש לכם הרשאות מספיקות ליצור או לעדכן את Cloud Service Mesh ואת משאבי Service mesh כדי להשתמש באבטחת השירות, כפי שמתואר במאמר הכנה להגדרה של ממשקי API לניתוב שירותים עם Envoy ועומסי עבודה בלי שרת Proxy.Google Cloud
הכנה להגדרה
בקטעים הבאים מתוארות המשימות שצריך לבצע לפני שמגדירים את שירות האבטחה של Cloud Service Mesh. המשימות האלה הן:
- עדכון Google Cloud CLI
- הגדרת משתנים
- הפעלת ממשקי ה-API שנדרשים כדי ש-Cloud Service Mesh יעבוד עם Certificate Authority Service
עדכון כלי שורת הפקודה gcloud
כדי לעדכן את Google Cloud CLI, מריצים את הפקודה הבאה במחשב המקומי:
gcloud components update
הגדרת משתנים
כדי שתוכלו להעתיק ולהדביק קוד עם ערכים עקביים כשאתם עובדים עם הדוגמה במסמך הזה, צריך להגדיר את המשתנים הבאים. משתמשים בערכים הבאים.
- PROJECT_ID: מחליפים את מזהה הפרויקט.
- CLUSTER_NAME: מחליפים את שם האשכול שרוצים להשתמש בו, לדוגמה,
secure-td-cluster. - ZONE: מחליפים את האזור שבו נמצא האשכול.
- GKE_CLUSTER_URL: תחליף
https://container.googleapis.com/v1/projects/PROJECT_ID/locations/ZONE/clusters/CLUSTER_NAME - WORKLOAD_POOL: תחליף
PROJECT_ID.svc.id.goog - K8S_NAMESPACE: Substitute
default. - DEMO_CLIENT_KSA: מחליפים את השם של חשבון השירות של הלקוח ב-Kubernetes.
- DEMO_SERVER_KSA: מחליפים את השם של חשבון השירות של שרת Kubernetes.
PROJNUM: מחליפים את מספר הפרויקט שלכם, שאפשר לראות במסוף Google Cloud או באמצעות הפקודה הבאה:
gcloud projects describe PROJECT_ID --format="value(projectNumber)"
SA_GKE: תחליף
service-PROJNUM@container-engine-robot.iam.gserviceaccount.comCLUSTER_VERSION: מחליפים את הגרסה העדכנית ביותר שזמינה. אפשר למצוא את המידע הזה בנתוני הגרסה של הערוץ המהיר. הגרסה המינימלית הנדרשת היא 1.21.4-gke.1801. זוהי גרסת אשכול GKE שמשמשת בדוגמה הזו.
מגדירים את הערכים כאן:
# Substitute your project ID PROJECT_ID=PROJECT_ID # GKE cluster name and zone for this example. CLUSTER_NAME=CLUSTER_NAME ZONE=ZONE # GKE cluster URL derived from the above GKE_CLUSTER_URL="https://container.googleapis.com/v1/projects/PROJECT_ID/locations/ZONE/clusters/CLUSTER_NAME" # Workload pool to be used with the GKE cluster WORKLOAD_POOL="PROJECT_ID.svc.id.goog" # Kubernetes namespace to run client and server demo. K8S_NAMESPACE=K8S_NAMESPACE DEMO_CLIENT_KSA=DEMO_CLIENT_KSA DEMO_SERVER_KSA=DEMO_SERVER_KSA # Compute other values # Project number for your project PROJNUM=PROJNUM CLUSTER_VERSION=CLUSTER_VERSION SA_GKE=service-PROJNUM@container-engine-robot.iam.gserviceaccount.com
הפעלת ממשקי ה-API
משתמשים בפקודה gcloud services enable כדי להפעיל את כל ממשקי ה-API שצריך להגדיר אבטחה של Cloud Service Mesh באמצעות Certificate Authority Service.
gcloud services enable \ container.googleapis.com \ cloudresourcemanager.googleapis.com \ compute.googleapis.com \ trafficdirector.googleapis.com \ networkservices.googleapis.com \ networksecurity.googleapis.com \ privateca.googleapis.com \ gkehub.googleapis.com
יצירה או עדכון של אשכול GKE
האבטחה של שירות Cloud Service Mesh תלויה בשילוב של שירות CA עם GKE. אשכול GKE צריך לעמוד בדרישות הבאות בנוסף לדרישות ההגדרה:
- צריך להשתמש בגרסת אשכול מינימלית של 1.21.4-gke.1801. אם אתם צריכים תכונות שזמינות בגרסה מאוחרת יותר, תוכלו לקבל את הגרסה הזו מערוץ ההפצה המהירה.
- צריך להפעיל את אשכול GKE ולהגדיר בו אישורי רשת, כמו שמתואר במאמר יצירת רשויות אישורים להנפקת אישורים.
יוצרים אשכול חדש שמשתמש באיחוד זהויות של עומסי עבודה ל-GKE. אם אתם מעדכנים אשכול קיים, דלגו לשלב הבא. הערך שאתם מציינים עבור
--tagsצריך להיות זהה לשם שמועבר לדגל--target-tagsעבור הפקודהfirewall-rules createבקטע הגדרת Cloud Service Mesh באמצעות רכיבי Cloud Load Balancing.# Create a GKE cluster with GKE managed mesh certificates. gcloud container clusters create CLUSTER_NAME \ --release-channel=rapid \ --scopes=cloud-platform \ --image-type=cos_containerd \ --machine-type=e2-standard-2 \ --zone=ZONE \ --workload-pool=PROJECT_ID.svc.id.goog \ --enable-mesh-certificates \ --cluster-version=CLUSTER_VERSION \ --enable-ip-alias \ --tags=allow-health-checks \ --workload-metadata=GKE_METADATA
יצירת האשכול עשויה להימשך כמה דקות.
אם אתם משתמשים באשכול קיים, אתם צריכים להפעיל את איחוד הזהויות של עומסי עבודה ל-GKE ואת האישורים של GKE Mesh. מוודאים שהאשכול נוצר עם הדגל
--enable-ip-alias, שלא ניתן להשתמש בו עם הפקודהupdate.gcloud container clusters update CLUSTER_NAME \ --enable-mesh-certificates
מריצים את הפקודה הבאה כדי לעבור לאשכול החדש כאשכול ברירת המחדל עבור פקודות
kubectl:gcloud container clusters get-credentials CLUSTER_NAME \ --zone ZONE
פריסה בסביבה מרובת אשכולות
אם אתם מבצעים פריסה בסביבה מרובת אשכולות, צריך לפעול לפי ההליך הכללי שמתואר בקטע הזה. ההנחיות האלה מניחות ש-Pods של לקוחות פועלים באשכול אחד, ו-Pods של שרתים פועלים באשכול השני.
יוצרים או מעדכנים את האשכולות לפי ההוראות שבקטע הקודם.
מריצים את הפקודה הבאה כדי לתעד את טווחי כתובות ה-IP של ה-Pod לכל אשכול:
gcloud compute firewall-rules list \ --filter="name~gke-{CLUSTER_NAME}-[0-9a-z]*-all" \ --format="value(sourceRanges)"לדוגמה, עבור אשכולות בשם
cluster-aו-cluster-b, הפקודות מחזירות תוצאות כמו אלה:cluster-a, pod CIDR: 10.4.0.0/14, node network tag: gke-cluster-a-9cd18751-node cluster-b, pod CIDR: 10.8.0.0/14, node network tag: gke-cluster-b-acd14479-node
יוצרים כללים של חומת אש ב-VPC שמאפשרים לאשכולות לתקשר ביניהם. לדוגמה, הפקודה הבאה יוצרת כלל חומת אש שמאפשר לכתובות ה-IP של הפוד
cluster-aלתקשר עם הצמתיםcluster-b:gcloud compute firewall-rules create per-cluster-a-pods \ --allow="tcp,udp,icmp,esp,ah,sctp" \ --target-tags="gke-cluster-b-acd14479-node"
הפקודה הבאה יוצרת כלל חומת אש שמאפשר לכתובות ה-IP של ה-Pod
cluster-bלתקשר עם הצמתיםcluster-a:gcloud compute firewall-rules create per-cluster-b-pods \ --allow="tcp,udp,icmp,esp,ah,sctp" \ --target-tags="gke-cluster-a-9cd18751-node"
רישום אשכולות ב-Fleet
רושמים את האשכול שיצרתם או עדכנתם במאמר יצירת אשכול GKE בצי. רישום האשכול מקל על הגדרת אשכולות בפרויקטים מרובים.
הערה: כל אחד מהשלבים האלה עשוי להימשך עד עשר דקות.
רושמים את האשכול ב-Fleet:
gcloud container fleet memberships register CLUSTER_NAME \ --gke-cluster=ZONE/CLUSTER_NAME \ --enable-workload-identity --install-connect-agent \ --manifest-output-file=MANIFEST-FILE_NAME
מחליפים את המשתנים באופן הבא:
- CLUSTER_NAME: השם של האשכול.
- ZONE: האזור של האשכול.
- MANIFEST-FILE_NAME: הנתיב שבו הפקודות האלה יוצרות את המניפסט לצורך רישום.
אם תהליך ההרשמה יצליח, תופיע הודעה כמו זו:
Finished registering the cluster CLUSTER_NAME with the fleet.
מחילים את קובץ המניפסט שנוצר על האשכול:
kubectl apply -f MANIFEST-FILE_NAME
אם תהליך הבקשה יצליח, יוצגו הודעות כמו אלה:
namespace/gke-connect created serviceaccount/connect-agent-sa created podsecuritypolicy.policy/gkeconnect-psp created role.rbac.authorization.k8s.io/gkeconnect-psp:role created rolebinding.rbac.authorization.k8s.io/gkeconnect-psp:rolebinding created role.rbac.authorization.k8s.io/agent-updater created rolebinding.rbac.authorization.k8s.io/agent-updater created role.rbac.authorization.k8s.io/gke-connect-agent-20210416-01-00 created clusterrole.rbac.authorization.k8s.io/gke-connect-impersonation-20210416-01-00 created clusterrolebinding.rbac.authorization.k8s.io/gke-connect-impersonation-20210416-01-00 created clusterrolebinding.rbac.authorization.k8s.io/gke-connect-feature-authorizer-20210416-01-00 created rolebinding.rbac.authorization.k8s.io/gke-connect-agent-20210416-01-00 created role.rbac.authorization.k8s.io/gke-connect-namespace-getter created rolebinding.rbac.authorization.k8s.io/gke-connect-namespace-getter created secret/http-proxy created deployment.apps/gke-connect-agent-20210416-01-00 created service/gke-connect-monitoring created secret/creds-gcp create
מקבלים את משאב החברות מהאשכול:
kubectl get memberships membership -o yaml
הפלט צריך לכלול את מאגר הזהויות של עומסי העבודה שהוקצה על ידי הצי, כאשר PROJECT_ID הוא מזהה הפרויקט:
workload_identity_pool: PROJECT_ID.svc.id.goog
המשמעות היא שהאשכול נרשם בהצלחה.
יצירת רשויות אישורים להנפקת אישורים
כדי להנפיק אישורים ל-Pods, צריך ליצור מאגר של שירות CA ואת רשויות האישורים (CA) הבאות:
- רשות אישורים (CA) עליונה. זהו בסיס המהימנות לכל האישורים שהונפקו לרשת ה-Mesh. אפשר להשתמש ב-CA בסיסי קיים, אם יש לכם כזה. יוצרים את רשות האישורים (CA) ברמת
enterprise, שמיועדת להנפקת אישורים לטווח ארוך עם נפח נמוך. - רשות אישורים משנית. רשות האישורים הזו מנפיקה אישורים לעומסי עבודה. יוצרים את רשות האישורים המשנית באזור שבו האשכול שלכם נפרס. יוצרים את רשות האישורים המשנית ברמה
devops, שמיועדת להנפקת אישורים לטווח קצר בכמויות גדולות.
יצירת רשות אישורים משנית היא אופציונלית, אבל מומלץ מאוד ליצור אחת כזו במקום להשתמש ברשות אישורי הבסיס כדי להנפיק אישורי GKE Mesh. אם מחליטים להשתמש ב-CA הבסיסי כדי להנפיק אישורים לרשת, צריך לוודא שמצב ההנפקה מבוסס-ההגדרה שמוגדר כברירת מחדל עדיין מותר.
ה-CA המשני יכול להיות באזור אחר מהאזור של האשכול, אבל מומלץ מאוד ליצור אותו באותו אזור של האשכול כדי לשפר את הביצועים. עם זאת, אפשר ליצור את רשויות האישורים הבסיסיות והמשניות באזורים שונים בלי להשפיע על הביצועים או על הזמינות.
האזורים הבאים נתמכים בשירות CA:
| שם האזור | תיאור האזור |
|---|---|
asia-east1 |
טייוואן |
asia-east2 |
הונג קונג |
asia-northeast1 |
טוקיו |
asia-northeast2 |
אוסקה |
asia-northeast3 |
סיאול |
asia-south1 |
מומבאי |
asia-south2 |
דלהי |
asia-southeast1 |
סינגפור |
asia-southeast2 |
ג'קארטה |
australia-southeast1 |
סידני |
australia-southeast2 |
מלבורן |
europe-central2 |
ורשה |
europe-north1 |
פינלנד |
europe-southwest1 |
מדריד |
europe-west1 |
בלגיה |
europe-west2 |
לונדון |
europe-west3 |
פרנקפורט |
europe-west4 |
הולנד |
europe-west6 |
ציריך |
europe-west8 |
מילאנו |
europe-west9 |
פריז |
europe-west10 |
ברלין |
europe-west12 |
טורינו |
me-central1 |
דוחה |
me-central2 |
דמאם |
me-west1 |
תל אביב |
northamerica-northeast1 |
מונטריאול |
northamerica-northeast2 |
טורונטו |
southamerica-east1 |
סאו פאולו |
southamerica-west1 |
סנטיאגו |
us-central1 |
איווה |
us-east1 |
דרום קרוליינה |
us-east4 |
צפון וירג'יניה |
us-east5 |
קולומבוס |
us-south1 |
דאלאס |
us-west1 |
אורגון |
us-west2 |
לוס-אנג׳לס |
us-west3 |
סולט לייק סיטי |
us-west4 |
לאס וגאס |
אפשר גם להריץ את הפקודה הבאה כדי לבדוק את רשימת המיקומים הנתמכים:
gcloud privateca locations list
נותנים את הרשאת IAM
roles/privateca.caManagerלאנשים שיוצרים מאגר רשויות אישורים ורשות אישורים. שימו לב: הפורמט הנכון של MEMBER הואuser:userid@example.com. אם האדם הזה הוא המשתמש הנוכחי, אפשר לקבל את מזהה המשתמש הנוכחי באמצעות פקודת ה-Shell$(gcloud auth list --filter=status:ACTIVE --format="value(account)").gcloud projects add-iam-policy-binding PROJECT_ID \ --member=MEMBER \ --role=roles/privateca.caManager
מקצים את התפקיד
role/privateca.adminבשירות CA לאנשים שצריכים לשנות את כללי המדיניות של IAM, כאשרMEMBERהוא אדם שצריך את הגישה הזו, במיוחד כל אדם שמבצע את השלבים הבאים שנותנים את התפקידיםprivateca.auditorו-privateca.certificateManager:gcloud projects add-iam-policy-binding PROJECT_ID \ --member=MEMBER \ --role=roles/privateca.admin
יוצרים את המאגר של שירות רשות האישורים (CA) הבסיסית.
gcloud privateca pools create ROOT_CA_POOL_NAME \ --location ROOT_CA_POOL_LOCATION \ --tier enterprise
יוצרים רשות אישורים (CA) עליונה.
gcloud privateca roots create ROOT_CA_NAME --pool ROOT_CA_POOL_NAME \ --subject "CN=ROOT_CA_NAME, O=ROOT_CA_ORGANIZATION" \ --key-algorithm="ec-p256-sha256" \ --max-chain-length=1 \ --location ROOT_CA_POOL_LOCATION
בהדגמה הזו, משתמשים בערכים הבאים למשתנים:
- ROOT_CA_POOL_NAME=td_sec_pool
- ROOT_CA_NAME=pkcs2-ca
- ROOT_CA_POOL_LOCATION=us-east1
- ROOT_CA_ORGANIZATION="TestCorpLLC"
יוצרים את המאגר המשני ואת רשות האישורים המשנית. מוודאים שמצב ההנפקה מבוסס-ההגדרה שמוגדר כברירת מחדל עדיין מותר.
gcloud privateca pools create SUBORDINATE_CA_POOL_NAME \ --location SUBORDINATE_CA_POOL_LOCATION \ --tier devops
gcloud privateca subordinates create SUBORDINATE_CA_NAME \ --pool SUBORDINATE_CA_POOL_NAME \ --location SUBORDINATE_CA_POOL_LOCATION \ --issuer-pool ROOT_CA_POOL_NAME \ --issuer-location ROOT_CA_POOL_LOCATION \ --subject "CN=SUBORDINATE_CA_NAME, O=SUBORDINATE_CA_ORGANIZATION" \ --key-algorithm "ec-p256-sha256" \ --use-preset-profile subordinate_mtls_pathlen_0
בהדגמה הזו, משתמשים בערכים הבאים למשתנים:
- SUBORDINATE_CA_POOL_NAME="td-ca-pool"
- SUBORDINATE_CA_POOL_LOCATION=us-east1
- SUBORDINATE_CA_NAME="td-ca"
- SUBORDINATE_CA_ORGANIZATION="TestCorpLLC"
- ROOT_CA_POOL_NAME=td_sec_pool
- ROOT_CA_POOL_LOCATION=us-east1
מקצים את התפקיד
privateca.auditorב-IAM למאגר CA הבסיסי כדי לאפשר גישה מחשבון השירות של GKE:gcloud privateca pools add-iam-policy-binding ROOT_CA_POOL_NAME \ --location ROOT_CA_POOL_LOCATION \ --role roles/privateca.auditor \ --member="serviceAccount:service-PROJNUM@container-engine-robot.iam.gserviceaccount.com"
מקצים את התפקיד
privateca.certificateManagerב-IAM למאגר של רשות אישורים משנית כדי לאפשר גישה מחשבון השירות של GKE:gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_NAME \ --location SUBORDINATE_CA_POOL_LOCATION \ --role roles/privateca.certificateManager \ --member="serviceAccount:service-PROJNUM@container-engine-robot.iam.gserviceaccount.com"
שומרים את הגדרת ה-YAML הבאה
WorkloadCertificateConfigכדי להגדיר לאשכול איך להנפיק אישורים לרשת:apiVersion: security.cloud.google.com/v1 kind: WorkloadCertificateConfig metadata: name: default spec: # Required. The CA service that issues your certificates. certificateAuthorityConfig: certificateAuthorityServiceConfig: endpointURI: ISSUING_CA_POOL_URI # Required. The key algorithm to use. Choice of RSA or ECDSA. # # To maximize compatibility with various TLS stacks, your workloads # should use keys of the same family as your root and subordinate CAs. # # To use RSA, specify configuration such as: # keyAlgorithm: # rsa: # modulusSize: 4096 # # Currently, the only supported ECDSA curves are "P256" and "P384", and the only # supported RSA modulus sizes are 2048, 3072 and 4096. keyAlgorithm: rsa: modulusSize: 4096 # Optional. Validity duration of issued certificates, in seconds. # # Defaults to 86400 (1 day) if not specified. validityDurationSeconds: 86400 # Optional. Try to start rotating the certificate once this # percentage of validityDurationSeconds is remaining. # # Defaults to 50 if not specified. rotationWindowPercentage: 50מחליפים את מה שכתוב בשדות הבאים:
- מזהה הפרויקט שבו פועל האשכול:
PROJECT_ID
- ה-URI המוגדר במלואו של רשות האישורים שמנפיקה את אישורי הרשת (ISSUING_CA_POOL_URI).
יכול להיות שזו רשות אישורים משנית (מומלץ) או רשות אישורים בסיסית. הפורמט הוא:
//privateca.googleapis.com/projects/PROJECT_ID/locations/SUBORDINATE_CA_POOL_LOCATION/caPools/SUBORDINATE_CA_POOL_NAME
- מזהה הפרויקט שבו פועל האשכול:
שומרים את הגדרת ה-YAML הבאה
TrustConfigכדי להגדיר לאשכול איך לתת אמון באישורים שהונפקו:apiVersion: security.cloud.google.com/v1 kind: TrustConfig metadata: name: default spec: # You must include a trustStores entry for the trust domain that # your cluster is enrolled in. trustStores: - trustDomain: PROJECT_ID.svc.id.goog # Trust identities in this trustDomain if they appear in a certificate # that chains up to this root CA. trustAnchors: - certificateAuthorityServiceURI: ROOT_CA_POOL_URIמחליפים את מה שכתוב בשדות הבאים:
- מזהה הפרויקט שבו פועל האשכול:
PROJECT_ID
- ה-URI המוגדר במלואו של מאגר רשויות האישורים (CA) הבסיסי (ROOT_CA_POOL_URI).
הפורמט הוא:
//privateca.googleapis.com/projects/PROJECT_ID/locations/ROOT_CA_POOL_LOCATION/caPools/ROOT_CA_POOL_NAME
- מזהה הפרויקט שבו פועל האשכול:
מחילים את ההגדרות על האשכול:
kubectl apply -f WorkloadCertificateConfig.yaml kubectl apply -f TrustConfig.yaml
הגדרת ניהול זהויות והרשאות גישה (IAM)
כדי ליצור את המשאבים שנדרשים להגדרה, צריך להיות לכם תפקיד compute.NetworkAdmin. התפקיד הזה מכיל את כל ההרשאות שנדרשות כדי ליצור, לעדכן, למחוק, להציג רשימה ולהשתמש במשאבים הנדרשים (כלומר, להפנות אליהם במשאבים אחרים). אם אתם הבעלים של הפרויקט ויש לכם הרשאת עריכה בו, התפקיד הזה מוקצה לכם באופן אוטומטי.
שימו לב שהמדיניות networksecurity.googleapis.com.clientTlsPolicies.use ו-networksecurity.googleapis.com.serverTlsPolicies.use לא נאכפת כשמפנים למשאבים האלה בשירות לקצה העורפי.
אם ההרשאות האלה ייאכפו בעתיד ואתם משתמשים בתפקיד compute.NetworkAdmin, לא תיתקלו בבעיות כשהבדיקה הזו תיאכף.
אם אתם משתמשים בתפקידים בהתאמה אישית והבדיקה הזו תיאכף בעתיד, תצטרכו לוודא שאתם כוללים את ההרשאה המתאימה .use. אחרת, בעתיד יכול להיות שתגלו שלתפקיד המותאם אישית אין את ההרשאות הנדרשות כדי להפנות אל clientTlsPolicy או אל serverTlsPolicy משירות הקצה העורפי או ממדיניות נקודת הקצה.
ההוראות הבאות מאפשרות לחשבון השירות שמוגדר כברירת מחדל לגשת אל Cloud Service Mesh Security API וליצור חשבונות שירות של Kubernetes.
מגדירים את IAM כך שחשבון השירות שמוגדר כברירת מחדל יוכל לגשת ל-Cloud Service Mesh security API.
GSA_EMAIL=$(gcloud iam service-accounts list --format='value(email)' \ --filter='displayName:Compute Engine default service account') gcloud projects add-iam-policy-binding PROJECT_ID \ --member serviceAccount:${GSA_EMAIL} \ --role roles/trafficdirector.clientהגדרת חשבונות שירות של Kubernetes. הפריסות של הלקוח והשרת בקטעים הבאים משתמשות בשמות K של חשבונות השירות של השרת והלקוח ב-Kubernetes.
kubectl create serviceaccount --namespace K8S_NAMESPACE DEMO_SERVER_KSA kubectl create serviceaccount --namespace K8S_NAMESPACE DEMO_CLIENT_KSA
כדי לאפשר לחשבונות השירות של Kubernetes להתחזות לחשבון השירות שמוגדר כברירת מחדל ב-Compute Engine, צריך ליצור קשר בין מדיניות IAM לשני החשבונות. הקישור הזה מאפשר לחשבון השירות של Kubernetes לפעול כחשבון השירות שמוגדר כברירת מחדל ב-Compute Engine.
gcloud iam service-accounts add-iam-policy-binding \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[K8S_NAMESPACE/DEMO_SERVER_KSA]" ${GSA_EMAIL} gcloud iam service-accounts add-iam-policy-binding \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[K8S_NAMESPACE/DEMO_CLIENT_KSA]" ${GSA_EMAIL}מוסיפים הערות לחשבונות השירות של Kubernetes כדי לשייך אותם לחשבון השירות שמוגדר כברירת מחדל ב-Compute Engine.
kubectl annotate --namespace K8S_NAMESPACE \ serviceaccount DEMO_SERVER_KSA \ iam.gke.io/gcp-service-account=${GSA_EMAIL} kubectl annotate --namespace K8S_NAMESPACE \ serviceaccount DEMO_CLIENT_KSA \ iam.gke.io/gcp-service-account=${GSA_EMAIL}
הגדרת Cloud Service Mesh
כדי להתקין את כלי ההזרקה של sidecar, להגדיר שירות בדיקה ולהשלים משימות פריסה אחרות, פועלים לפי ההוראות הבאות.
התקנת Envoy sidecar injector באשכול
כדי לפרוס ולהפעיל הזרקת Envoy sidecar באשכול, צריך לפעול לפי ההוראות בשני הקטעים הבאים של הגדרת Cloud Service Mesh עבור GKE Pods עם הזרקת Envoy אוטומטית:
- התקנת Envoy sidecar injector
מוודאים שהגדרתם את שם הרשת כ-
sidecar_meshואת הרשת כ-"", מחרוזת ריקה. - הפעלת החדרת sidecar
חשוב להשלים את שני סוגי ההוראות לפני שמגדירים שירות בדיקה.
הגדרת שירות בדיקה
אחרי שמתקינים את Envoy sidecar injector, משתמשים בהוראות האלה כדי להגדיר שירות בדיקה לפריסה.
wget -q -O - https://storage.googleapis.com/traffic-director/security/ga/service_sample.yaml | sed -e s/DEMO_SERVER_KSA_PLACEHOLDER/DEMO_SERVER_KSA/g > service_sample.yaml kubectl apply -f service_sample.yaml
הקובץ service_sample.yaml מכיל את podspec של אפליקציית שרת ההדגמה. יש הערות ספציפיות לאבטחה של Cloud Service Mesh.
מטא נתונים של שרת Proxy ב-Cloud Service Mesh
קובץ ה-podspec מציין את ההערה proxyMetadata:
spec:
...
annotations:
cloud.google.com/proxyMetadata: '{"app": "payments"}'
...
כשה-Pod מאותחל, שרת ה-proxy של קובץ העזר החיצוני מאתר את ההערה הזו ומעביר אותה ל-Cloud Service Mesh. אחרי כן, Cloud Service Mesh יכול להשתמש במידע הזה כדי לשלוח חזרה הגדרה מסוננת:
- בהמשך המדריך הזה, שימו לב שמדיניות נקודות הקצה מציינת התאמה של נקודת קצה.
- התאמת נקודת הקצה מציינת שרק לקוחות שמציגים תווית עם שם
appוערךpaymentsיקבלו את ההגדרה המסוננת.
שימוש במפתחות ובאישורים של רשת שחתומים על ידי שירות CA
קובץ ה-podspec מציין את ההערה enableManagedCerts:
spec:
...
annotations:
...
cloud.google.com/enableManagedCerts: "true"
...
כשה-Pod מאותחל, אישורים ומפתחות שחתומים על ידי CA Service מותקנים אוטומטית במערכת הקבצים של קובץ העזר החיצוני המקומי.
הגדרת היציאה לחסימת תנועה נכנסת
קובץ ה-podspec מציין את ההערה includeInboundPorts:
spec:
...
annotations:
...
cloud.google.com/includeInboundPorts: "8000"
...
זו היציאה שבה אפליקציית השרת מאזינה לחיבורים. כשה-Pod מאותחל, שרת ה-proxy של קובץ העזר החיצוני מאתר את ההערה הזו ומעביר אותה ל-Cloud Service Mesh. לאחר מכן, Cloud Service Mesh יכול להשתמש במידע הזה כדי לשלוח בחזרה הגדרה מסוננת שמיירטת את כל התנועה הנכנסת ליציאה הזו ויכולה להחיל עליה מדיניות אבטחה.
היציאה של בדיקת תקינות צריכה להיות שונה מהיציאה של האפליקציה. אחרת, אותן מדיניות אבטחה יחולו על חיבורים נכנסים ליציאה של בדיקת תקינות, מה שעלול להוביל לדחיית החיבורים וכתוצאה מכך לסימון שגוי של השרת כלא תקין.
הגדרת שירותי GKE באמצעות NEGs
שירותי GKE צריכים להיות חשופים דרך קבוצות של נקודות קצה ברשת (NEGs) כדי שתוכלו להגדיר אותם כשרתי קצה של שירות קצה של Cloud Service Mesh. חבילת service_sample.yaml שמסופקת עם מדריך ההגדרה הזה משתמשת בשם ה-NEG service-test-neg בהערה הבאה:
...
metadata:
annotations:
cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "service-test-neg"}}}'
spec:
ports:
- port: 80
name: service-test
protocol: TCP
targetPort: 8000
אין צורך לשנות את קובץ service_sample.yaml.
שמירת השם של ה-NEG
שומרים את השם של קבוצת ה-NEG במשתנה NEG_NAME:
NEG_NAME="service-test-neg"
פריסת אפליקציית לקוח ב-GKE
מריצים את הפקודה הבאה כדי להפעיל לקוח הדגמה עם שרת proxy של Envoy כ-sidecar, שנדרש להדגמת תכונות האבטחה.
wget -q -O - https://storage.googleapis.com/traffic-director/security/ga/client_sample.yaml | sed -e s/DEMO_CLIENT_KSA_PLACEHOLDER/DEMO_CLIENT_KSA/g > client_sample.yaml kubectl apply -f client_sample.yaml
קובץ ה-podspec של הלקוח כולל רק את ההערה enableManagedCerts. הפעולה הזו נדרשת כדי לטעון את אמצעי האחסון הנדרשים עבור אישורים ומפתחות של רשת GKE מנוהלת, שנחתמים על ידי מופע CA Service.
הגדרת משאבים של בדיקת תקינות, כלל לחומת אש ושירות קצה עורפי
בקטע הזה יוצרים משאבים של בדיקת תקינות, כלל חומת אש ושירות לקצה העורפי עבור Cloud Service Mesh.
יוצרים את בדיקת התקינות.
gcloud compute health-checks create http td-gke-health-check \ --use-serving-port
יוצרים את הכלל בחומת האש כדי לאפשר את טווחי כתובות ה-IP של בודק התקינות.
gcloud compute firewall-rules create fw-allow-health-checks \ --action ALLOW \ --direction INGRESS \ --source-ranges 35.191.0.0/16,130.211.0.0/22 \ --rules tcp
יוצרים את שירות לקצה העורפי ומשייכים את בדיקת תקינות לשירות לקצה העורפי.
gcloud compute backend-services create td-gke-service \ --global \ --health-checks td-gke-health-check \ --load-balancing-scheme INTERNAL_SELF_MANAGED
מוסיפים את ה-NEG שנוצר קודם כקצה עורפי לשירות הקצה העורפי.
gcloud compute backend-services add-backend td-gke-service \ --global \ --network-endpoint-group ${NEG_NAME} \ --network-endpoint-group-zone ZONE \ --balancing-mode RATE \ --max-rate-per-endpoint 5
הגדרת משאבים של Mesh ו-HTTPRoute
בקטע הזה יוצרים משאבים מסוג Mesh ו-HTTPRoute.
יוצרים את מפרט המשאב
Meshושומרים אותו בקובץ בשםmesh.yaml.name: sidecar-mesh interceptionPort: 15001
אם לא מציינים את יציאת היירוט בקובץ
mesh.yaml, ברירת המחדל היא15001.יוצרים את המשאב
Meshבאמצעות המפרט mesh.yaml.gcloud network-services meshes import sidecar-mesh \ --source=mesh.yaml \ --location=global
יוצרים את המפרט
HTTPRouteושומרים אותו בקובץ בשםhttp_route.yaml.אפשר להשתמש ב-
PROJECT_IDאו ב-PROJECT_NUMBER.name: helloworld-http-route hostnames: - service-test meshes: - projects/PROJNUM/locations/global/meshes/sidecar-mesh rules: - action: destinations: - serviceName: "projects/PROJNUM/locations/global/backendServices/td-gke-service"
יוצרים את המשאב
HTTPRouteבאמצעות המפרט בקובץhttp_route.yaml.gcloud network-services http-routes import helloworld-http-route \ --source=http_route.yaml \ --location=global
ההגדרה של Cloud Service Mesh הושלמה ועכשיו אפשר להגדיר מדיניות אימות והרשאה.
הגדרת אבטחה משירות לשירות
בקטעים הבאים מפורטות ההוראות להגדרת אבטחה משירות לשירות.
הפעלת mTLS ברשת
כדי להגדיר mTLS ברשת, צריך לאבטח את התנועה היוצאת לשירות הקצה העורפי ואת התנועה הנכנסת לנקודת הקצה.
הפורמט של סימוכין בתקנון המדיניות
חשוב לשים לב לפורמט הנדרש הבא להפניה ל-TLS של שרת, ל-TLS של לקוח ולמדיניות הרשאות:
projects/PROJECT_ID/locations/global/[serverTlsPolicies|clientTlsPolicies|authorizationPolicies]/[server-tls-policy|client-mtls-policy|authz-policy]
לדוגמה:
projects/PROJECT_ID/locations/global/serverTlsPolicies/server-tls-policy
projects/PROJECT_ID/locations/global/clientTlsPolicies/client-mtls-policy
projects/PROJECT_ID/locations/global/authorizationPolicies/authz-policy
אבטחת תעבורה יוצאת לשירות הקצה העורפי
כדי לאבטח תנועה יוצאת, קודם יוצרים מדיניות TLS של לקוח שמבצעת את הפעולות הבאות:
- משתמש ב-
google_cloud_private_spiffeכפלאגין ל-clientCertificate, שמגדיר את Envoy להשתמש באישור רשת מנוהל של GKE בתור זהות הלקוח. - משתמש ב-
google_cloud_private_spiffeכפלאגין ל-serverValidationCa, שמתכנת את Envoy להשתמש באישורים מנוהלים של GKE Mesh לצורך אימות שרת.
לאחר מכן, מצרפים את מדיניות ה-TLS של הלקוח לשירות הקצה העורפי. הפעולה הזו גורמת לדברים הבאים:
- מחיל את מדיניות האימות ממדיניות TLS של הלקוח על חיבורים יוצאים לנקודות קצה של שירות לקצה העורפי.
- שמות נושאים חלופיים (SAN) מנחים את הלקוח לאמת את הזהות המדויקת של השרת שאליו הוא מתחבר.
יוצרים את מדיניות ה-TLS של הלקוח בקובץ
client-mtls-policy.yaml:name: "client-mtls-policy" clientCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffe serverValidationCa: - certificateProviderInstance: pluginInstance: google_cloud_private_spiffeמייבאים את מדיניות ה-TLS של הלקוח:
gcloud network-security client-tls-policies import client-mtls-policy \ --source=client-mtls-policy.yaml --location=globalמצרפים את מדיניות ה-TLS של הלקוח לשירות הקצה העורפי. הפעולה הזו מחייבת אימות mTLS בכל הבקשות היוצאות מהלקוח לשירות הקצה העורפי הזה.
gcloud compute backend-services export td-gke-service \ --global --destination=demo-backend-service.yamlמוסיפים את השורות הבאות ל-
demo-backend-service.yaml:securitySettings: clientTlsPolicy: projects/PROJECT_ID/locations/global/clientTlsPolicies/client-mtls-policy subjectAltNames: - "spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA"מייבאים את הערכים:
gcloud compute backend-services import td-gke-service \ --global --source=demo-backend-service.yamlאפשר להריץ את הפקודה הבאה כדי לבדוק אם הבקשה נכשלה. זהו כשל צפוי, כי הלקוח מצפה לקבל אישורים מנקודת הקצה, אבל נקודת הקצה לא מתוכנתת עם מדיניות אבטחה.
# Get the name of the Podrunning Busybox. BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}') # Command to execute that tests connectivity to the service service-test. TEST_CMD="wget -q -O - service-test; echo" # Execute the test command on the pod. kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"הפלט אמור להיראות כך:
wget: server returned error: HTTP/1.1 503 Service Unavailable
אבטחת תנועה נכנסת לנקודת הקצה
כדי לאבטח תנועה נכנסת, קודם יוצרים מדיניות TLS של שרת שמבצעת את הפעולות הבאות:
- משתמש ב-
google_cloud_private_spiffeכפלאגין ל-serverCertificate, שמגדיר את Envoy להשתמש באישור רשת מנוהל של GKE בתור זהות השרת. - משתמש ב-
google_cloud_private_spiffeכפלאגין ל-clientValidationCa, שמגדיר את Envoy להשתמש באימות לקוח באמצעות אישורים של רשתות GKE מנוהלות.
שומרים את ערכי המדיניות של TLS בשרת בקובץ בשם
server-mtls-policy.yaml.name: "server-mtls-policy" serverCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffe mtlsPolicy: clientValidationCa: - certificateProviderInstance: pluginInstance: google_cloud_private_spiffeיוצרים את מדיניות ה-TLS של השרת:
gcloud network-security server-tls-policies import server-mtls-policy \ --source=server-mtls-policy.yaml --location=globalיוצרים קובץ בשם
ep_mtls.yamlשמכיל את התאמת נקודת הקצה ומצרפים את מדיניות ה-TLS של השרת.endpointMatcher: metadataLabelMatcher: metadataLabelMatchCriteria: MATCH_ALL metadataLabels: - labelName: app labelValue: payments name: "ep" serverTlsPolicy: projects/PROJECT_ID/locations/global/serverTlsPolicies/server-mtls-policy type: SIDECAR_PROXYמייבאים את endpoint matcher.
gcloud network-services endpoint-policies import ep \ --source=ep_mtls.yaml --location=global
אימות ההגדרה
מריצים את הפקודה הבאה curl. אם הבקשה מסתיימת בהצלחה, הפלט יציג x-forwarded-client-cert. הכותרת מודפסת רק אם החיבור הוא חיבור mTLS.
# Get the name of the Podrunning Busybox.
BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')
# Command to execute that tests connectivity to the service service-test.
TEST_CMD="wget -q -O - service-test; echo"
# Execute the test command on the pod.
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"
הפלט אמור להיראות כך:
GET /get HTTP/1.1 Host: service-test content-length: 0 x-envoy-internal: true accept: */* x-forwarded-for: 10.48.0.6 x-envoy-expected-rq-timeout-ms: 15000 user-agent: curl/7.35.0 x-forwarded-proto: http x-request-id: redacted x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA
שימו לב שהכותרת x-forwarded-client-cert מוכנסת על ידי Envoy בצד השרת, והיא מכילה את הזהות שלו (השרת) ואת הזהות של לקוח המקור. מכיוון שאנחנו רואים את הזהויות של הלקוח והשרת, זהו אות לחיבור mTLS.
הגדרת גישה ברמת השירות באמצעות מדיניות הרשאות
ההוראות האלה יוצרות מדיניות הרשאות שמאפשרת בקשות שנשלחות על ידי חשבון DEMO_CLIENT_KSA שבו שם המארח הוא service-test, היציאה היא 8000 ושיטת ה-HTTP היא GET. לפני שיוצרים מדיניות הרשאות, חשוב לקרוא את האזהרה שבמאמר הגבלת הגישה באמצעות הרשאות.
יוצרים מדיניות הרשאות על ידי יצירת קובץ בשם
authz-policy.yaml.action: ALLOW name: authz-policy rules: - sources: - principals: - spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA destinations: - hosts: - service-test ports: - 8000 methods: - GETמייבאים את המדיניות:
gcloud network-security authorization-policies import authz-policy \ --source=authz-policy.yaml \ --location=global
כדי לעדכן את מדיניות נקודת הקצה כך שתפנה למדיניות ההרשאות החדשה, מוסיפים את השורות הבאות לקובץ
ep_mtls.yaml:authorizationPolicy: projects/PROJECT_ID/locations/global/authorizationPolicies/authz-policy
מדיניות נקודת הקצה מציינת עכשיו שצריך לאכוף גם mTLS וגם את מדיניות ההרשאה על בקשות נכנסות ל-Pods שבהם פרוקסי Envoy sidecar מציג את התווית
app:payments.מייבאים את המדיניות:
gcloud network-services endpoint-policies import ep \ --source=ep_mtls.yaml --location=global
אימות ההגדרה
מריצים את הפקודות הבאות כדי לאמת את ההגדרה.
# Get the name of the Podrunning Busybox.
BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')
# Command to execute that tests connectivity to the service service-test.
# This is a valid request and will be allowed.
TEST_CMD="wget -q -O - service-test; echo"
# Execute the test command on the pod.
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"
הפלט הצפוי אמור להיראות כך:
GET /get HTTP/1.1 Host: service-test content-length: 0 x-envoy-internal: true accept: */* x-forwarded-for: redacted x-envoy-expected-rq-timeout-ms: 15000 user-agent: curl/7.35.0 x-forwarded-proto: http x-request-id: redacted x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA
מריצים את הפקודות הבאות כדי לבדוק אם מדיניות ההרשאות דוחה בקשות לא חוקיות בצורה נכונה:
# Failure case # Command to execute that tests connectivity to the service service-test. # This is an invalid request and server will reject because the server # authorization policy only allows GET requests. TEST_CMD="wget -q -O - service-test --post-data='' ; echo" # Execute the test command on the pod. kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"
הפלט הצפוי אמור להיראות כך:
<RBAC: access denied HTTP/1.1 403 Forbidden>
הגדרת מדיניות הרשאות ב-sidecars ב-GKE
בקטע הזה נסביר איך להגדיר סוגים שונים של מדיניות הרשאות ב-sidecar של Cloud Service Mesh ב-GKE.
כדי ליצור מדיניות הרשאות, צריך להתקין את GCPAuthzPolicy CustomResourceDefinition (CRD):
curl https://github.com/GoogleCloudPlatform/gke-networking-recipes/blob/main/gateway-api/config/mesh/crd/experimental/gcpauthzpolicy.yaml \
| kubectl apply -f -
מדיניות הרשאות לדחיית בקשות
אם יש לכם עומס עבודה שאמור לבצע רק שיחות יוצאות, כמו משימת cron, אתם יכולים להגדיר מדיניות הרשאות שתדחה כל בקשות HTTP נכנסות לעומס העבודה. בדוגמה הבאה נדחות בקשות HTTP נכנסות לעומס העבודה example-app.
כדי ליצור את מדיניות הדחייה ולהחיל אותה:
יוצרים מדיניות מותאמת אישית על ידי יצירת קובץ בשם
deny-all-authz-policy.yaml:cat >deny-all-authz-policy.yaml <<EOF apiVersion: networking.gke.io/v1 kind: GCPAuthzPolicy metadata: name: my-workload-authz namespace: ns1 spec: targetRefs: - kind: Deployment name: example-app httpRules: - to: operations: - paths: - type: Prefix value: "/" action: DENY EOFהחלת המדיניות:
kubectl apply -f deny-all-authz-policy.yaml
מדיניות הרשאות שמאפשרת בקשות
אפשר גם להגדיר מדיניות הרשאה שמאשרת רק בקשות שתואמות לקריטריונים ספציפיים, ודוחה את השאר. בדוגמה הבאה מוגדרת מדיניות הרשאות בפריסת example-app כדי לאפשר רק בקשות mTLS מ-Pods עם הזהות spiffee://cluster.local/ns1/pod1.
כדי ליצור את מדיניות ההרשאה וליישם אותה:
יוצרים מדיניות מותאמת אישית על ידי יצירת קובץ בשם
allow-authz-policy.yaml:cat >allow-authz-policy.yaml <<EOF apiVersion: networking.gke.io/v1 kind: GCPAuthzPolicy metadata: name: my-workload-authz namespace: ns1 spec: targetRefs: - kind: Deployment name: example-app httpRules: - from: sources: - principals: - type: Exact value: "spiffee://cluster.local/ns1/pod1" action: ALLOW EOFהחלת המדיניות:
kubectl apply -f allow-authz-policy.yaml
הגדרת אבטחה של שער כניסה
בקטע הזה מניחים שהשלמתם את הקטע בנושא אבטחה משירות לשירות, כולל הגדרת אשכול GKE עם הזרקה אוטומטית של sidecar, יצירת רשות אישורים ויצירת מדיניות של נקודת קצה.
בקטע הזה פורסים פרוקסי של Envoy כשער כניסה שמסיים חיבורי TLS ומאשר בקשות מלקוחות פנימיים של אשכול.
כדי להגדיר שער כניסה לניתוק TLS:
- פריסת שירות Kubernetes שאפשר להגיע אליו באמצעות כתובת IP פנימית של האשכול.
- הפריסה כוללת שרת proxy עצמאי של Envoy שנחשף כשירות Kubernetes ומתחבר ל-Cloud Service Mesh.
- יוצרים מדיניות TLS לשרת כדי להפסיק את ה-TLS.
- יוצרים מדיניות הרשאות כדי לאשר בקשות נכנסות.
פריסת שירות שער כניסה ל-GKE
מריצים את הפקודה הבאה כדי לפרוס את שירות שער הכניסה ב-GKE:
wget -q -O - https://storage.googleapis.com/traffic-director/security/ga/gateway_sample_xdsv3.yaml | sed -e s/PROJECT_NUMBER_PLACEHOLDER/PROJNUM/g | sed -e s/NETWORK_PLACEHOLDER/default/g | sed -e s/DEMO_CLIENT_KSA_PLACEHOLDER/DEMO_CLIENT_KSA/g > gateway_sample.yaml kubectl apply -f gateway_sample.yaml
הקובץ gateway_sample.yaml הוא המפרט של שער הכניסה. בקטעים הבאים מתוארים כמה תוספות למפרט.
השבתה של הזרקת sidecar ב-Cloud Service Mesh
ה-gateway_sample.yaml spec פורס פרוקסי של Envoy כקונטיינר היחיד. בשלבים הקודמים, Envoy הוזרק כ-sidecar למאגר אפליקציות. כדי למנוע מצב שבו כמה שרתי Envoy מטפלים בבקשות, אפשר להשבית את הזרקת קובץ העזר לשירות Kubernetes הזה באמצעות ההצהרה הבאה:
sidecar.istio.io/inject: "false"
הרכבה של אמצעי האחסון הנכון
מפרט gateway_sample.yaml מרכיב את עוצמת הקול gke-workload-certificates.
הנפח הזה משמש גם בפריסת sidecar, אבל הוא מתווסף באופן אוטומטי על ידי sidecar injector כשהוא מזהה את ההערה cloud.google.com/enableManagedCerts: "true". הווליום gke-workload-certificates מכיל את האישורים והמפתחות של SPIFFE שמנוהלים על ידי GKE, שחתומים על ידי מופע CA Service שהגדרתם.
הגדרת כתובת ה-IP הפנימית של האשכול
מגדירים את שער הכניסה עם שירות מסוג ClusterInternal. הפעולה הזו יוצרת שם מארח DNS שניתן לפענוח באופן פנימי עבור mesh-gateway. כשלקוח שולח בקשה ל-mesh-gateway:443, Kubernetes מנתב את הבקשה באופן מיידי ליציאה 8080 של פריסת שער הכניסה Envoy.
הפעלת TLS בשער כניסה
כדי להפעיל TLS בשער כניסה, צריך לפעול לפי ההוראות הבאות.
יוצרים משאב מדיניות TLS לשרת כדי לסיים חיבורי TLS, עם הערכים בקובץ שנקרא
server-tls-policy.yaml:description: tls server policy name: server-tls-policy serverCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffeמייבאים את מדיניות ה-TLS של השרת:
gcloud network-security server-tls-policies import server-tls-policy \ --source=server-tls-policy.yaml --location=globalיוצרים יעד חדש
Gatewayושומרים אותו בקובץtd-gke-gateway.yaml. הפעולה הזו מצרפת את מדיניות ה-TLS של השרת ומגדירה את שער הכניסה של פרוקסי Envoy כדי לסיים את תעבורת ה-TLS הנכנסת.name: td-gke-gateway scope: gateway-proxy ports: - 8080 type: OPEN_MESH serverTlsPolicy: projects/PROJECT_ID/locations/global/serverTlsPolicies/server-tls-policy
מייבאים את השער:
gcloud network-services gateways import td-gke-gateway \ --source=td-gke-gateway.yaml \ --location=global
יוצרים ושומרים
HTTPRouteחדש בשםtd-gke-routeשמפנה לשער ומנתב את כל הבקשות אלtd-gke-service.name: td-gke-route hostnames: - mesh-gateway gateways: - projects/PROJECT_NUMBER/locations/global/gateways/td-gke-gateway rules: - action: destinations: - serviceName: "projects/PROJECT_NUMBER/locations/global/backendServices/td-gke-service"מייבאים את
HTTPRoute:gcloud network-services http-routes import td-gke-route \ --source=td-gke-route.yaml \ --location=global
אפשרות נוספת: לעדכן את מדיניות ההרשאות בשרתי הקצה העורפיים כדי לאפשר בקשות כשכל התנאים הבאים מתקיימים:
- בקשות שנשלחו על ידי
DEMO_CLIENT_KSA. (הפריסה של שער הכניסה משתמשת בחשבון השירותDEMO_CLIENT_KSA). - בקשות עם מארח
mesh-gatewayאוservice-test - יציאה:
8000
אין צורך להריץ את הפקודות האלה אלא אם הגדרתם מדיניות הרשאות לשרתי הקצה שלכם. אם אין מדיניות הרשאות בנקודת הקצה או שהיא לא מכילה התאמה של מארח או של חשבון משתמש מקור במדיניות ההרשאות, הבקשות יאושרו בלי השלב הזה. מוסיפים את הערכים האלה אל
authz-policy.yaml.action: ALLOW name: authz-policy rules: - sources: - principals: - spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA destinations: - hosts: - service-test - mesh-gateway ports: - 8000 methods: - GET- בקשות שנשלחו על ידי
מייבאים את המדיניות:
gcloud network-security authorization-policies import authz-policy \ --source=authz-policy.yaml \ --location=global
אימות הפריסה של שער הכניסה
אתם משתמשים בקונטיינר חדש בשם debug כדי לשלוח בקשות לשער ה-Ingress כדי לאמת את ה-Deployment (פריסה).
במפרט הבא, ההערה "sidecar.istio.io/inject":"false" מונעת מהכלי להזרקת sidecar של Cloud Service Mesh להזריק אוטומטית פרוקסי sidecar. אין sidecar שיכול לעזור למאגר התגים debug בניתוב הבקשה.
המאגר צריך להתחבר לשער הכניסה כדי להגדיר ניתוב.
המפרט כולל את הדגל --no-check-certificate, שמתעלם מאימות אישור השרת. למאגר התגים של debug אין אישורי אימות של רשות האישורים שנדרשים לאימות אישורים שנחתמו על ידי שירות הרשות שמנפיקה את האישורים (CA), שמשמשים את שער הכניסה להפסקת TLS.
בסביבת ייצור, מומלץ להוריד את אישור האימות של CA Service ולהטמיע או להתקין אותו בלקוח. אחרי שמתקינים את אישור האימות, מסירים את האפשרות --no-check-certificate מהפקודה wget.
מריצים את הפקודה הבאה:
kubectl run -i --tty --rm debug --image=busybox --restart=Never --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }' -- /bin/sh -c "wget --no-check-certificate -qS -O - https://mesh-gateway; echo"
הפלט אמור להיראות כך:
GET / HTTP/1.1 Host: 10.68.7.132 x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA x-envoy-expected-rq-timeout-ms: 15000 x-envoy-internal: true x-request-id: 5ae429e7-0e18-4bd9-bb79-4e4149cf8fef x-forwarded-for: 10.64.0.53 x-forwarded-proto: https content-length: 0 user-agent: Wget
מריצים את פקודת הבדיקה השלילית הבאה:
# Negative test
# Expect this to fail because gateway expects TLS.
kubectl run -i --tty --rm debug --image=busybox --restart=Never --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }' -- /bin/sh -c "wget --no-check-certificate -qS -O - http://mesh-gateway:443/headers; echo"
הפלט אמור להיראות כך:
wget: error getting response: Connection reset by peer
מריצים את פקודת הבדיקה השלילית הבאה:
# Negative test.
# AuthorizationPolicy applied on the endpoints expect a GET request. Otherwise
# the request is denied authorization.
kubectl run -i --tty --rm debug --image=busybox --restart=Never --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }' -- /bin/sh -c "wget --no-check-certificate -qS -O - https://mesh-gateway --post-data=''; echo"
הפלט אמור להיראות כך:
HTTP/1.1 403 Forbidden wget: server returned error: HTTP/1.1 403 Forbidden
מחיקת הפריסה
אפשר להריץ את הפקודות האלה כדי למחוק את הפריסה שיצרתם באמצעות המדריך הזה.
כדי למחוק את האשכול, מריצים את הפקודה הבאה:
gcloud container clusters delete CLUSTER_NAME --zone ZONE --quiet
כדי למחוק את המשאבים שיצרתם, מריצים את הפקודות הבאות:
gcloud compute backend-services delete td-gke-service --global --quiet
cloud compute network-endpoint-groups delete service-test-neg --zone ZONE --quiet
gcloud compute firewall-rules delete fw-allow-health-checks --quiet
gcloud compute health-checks delete td-gke-health-check --quiet
gcloud network-services endpoint-policies delete ep \
--location=global --quiet
gcloud network-security authorization-policies delete authz-gateway-policy \
--location=global --quiet
gcloud network-security authorization-policies delete authz-policy \
--location=global --quiet
gcloud network-security client-tls-policies delete client-mtls-policy \
--location=global --quiet
gcloud network-security server-tls-policies delete server-tls-policy \
--location=global --quiet
gcloud network-security server-tls-policies delete server-mtls-policy \
--location=global --quiet
מגבלות
אבטחת שירותים ב-Cloud Service Mesh נתמכת רק ב-GKE. אי אפשר לפרוס אבטחת שירות באמצעות Compute Engine.
פתרון בעיות
בקטע הזה מוסבר איך לפתור בעיות שנתקלים בהן במהלך ההגדרה של שירות אבטחה.
כשלים בחיבור
אם החיבור נכשל עם שגיאה upstream connect או שגיאה disconnect/reset
before headers, כדאי לבדוק את היומנים של Envoy, שבהם יכול להיות שתופיע אחת מהודעות היומן הבאות:
gRPC config stream closed: 5, Requested entity was not found
gRPC config stream closed: 2, no credential token is found
אם השגיאות האלה מופיעות ביומן של Envoy, סביר להניח שהטוקן של חשבון השירות לא הועלה בצורה נכונה, או שהוא משתמש ב-audience אחר, או בשניהם.
מידע נוסף זמין במאמר הודעות שגיאה ביומני Envoy מצביעות על בעיה בהגדרה.
לא נוצרו פודים
כדי לפתור את הבעיה, אפשר לעיין במאמר בנושא פתרון בעיות בפריסות אוטומטיות של GKE Pods.
Envoy לא מבצע אימות באמצעות Cloud Service Mesh
כש-Envoy (envoy-proxy) מתחבר ל-Cloud Service Mesh כדי לאחזר את הגדרות ה-xDS, הוא משתמש באיחוד זהויות של עומסי עבודה ל-GKE ובחשבון השירות שמוגדר כברירת מחדל במכונה הווירטואלית של Compute Engine (אלא אם שונה ה-bootstrap). אם האימות נכשל, Envoy לא עובר למצב מוכן.
לא ניתן ליצור אשכול עם --workload-identity-certificate-authority flag
אם השגיאה הזו מופיעה, צריך לוודא שאתם מריצים את הגרסה העדכנית ביותר של Google Cloud CLI:
gcloud components update
הפודים נשארים במצב המתנה
אם ה-Pods נשארים במצב 'בהמתנה' במהלך תהליך ההגדרה, צריך להגדיל את משאבי ה-CPU והזיכרון של ה-Pods במפרט הפריסה.
לא ניתן ליצור אשכול עם הדגל --enable-mesh-certificates
מוודאים שאתם מריצים את הגרסה העדכנית של ה-CLI של gcloud:
gcloud components update
הערה: הדגל --enable-mesh-certificates פועל רק עם gcloud beta.
פודים לא מופעלים
יכול להיות ש-Pods שמשתמשים באישורים של GKE mesh לא יופעלו אם הקצאת האישורים נכשלת. מצב כזה יכול לקרות במקרים הבאים:
- ההגדרה של
WorkloadCertificateConfigאו שלTrustConfigשגויה או שהם חסרים. - בקשות CSR לא מאושרות.
כדי לבדוק אם הקצאת האישורים נכשלת, בודקים את אירועי ה-Pod.
בודקים את הסטטוס של ה-Pod:
kubectl get pod -n POD_NAMESPACE POD_NAMEמחליפים את מה שכתוב בשדות הבאים:
-
POD_NAMESPACE: מרחב השמות של ה-Pod. -
POD_NAME: השם של ה-Pod.
-
כדי לבדוק אירועים אחרונים ב-Pod:
kubectl describe pod -n POD_NAMESPACE POD_NAMEאם הקצאת האישורים נכשלת, יוצג אירוע עם
Type=Warning,Reason=FailedMount,From=kubeletושדהMessageשמתחיל ב-MountVolume.SetUp failed for volume "gke-workload-certificates". השדהMessageמכיל מידע לפתרון בעיות.Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedMount 13s (x7 over 46s) kubelet MountVolume.SetUp failed for volume "gke-workload-certificates" : rpc error: code = Internal desc = unable to mount volume: store.CreateVolume, err: unable to create volume "csi-4d540ed59ef937fbb41a9bf5380a5a534edb3eedf037fe64be36bab0abf45c9c": caPEM is nil (check active WorkloadCertificateConfig)אם ה-Pods לא מופעלים בגלל אובייקטים שהוגדרו בצורה שגויה או בגלל בקשות חתימה על אישורים (CSR) שנדחו, כדאי לפעול לפי השלבים הבאים לפתרון בעיות.
ההגדרה של WorkloadCertificateConfig או TrustConfig שגויה
מוודאים שיצרתם את האובייקטים WorkloadCertificateConfig ו-TrustConfig בצורה נכונה. אפשר לאבחן הגדרות שגויות באחד מהאובייקטים האלה באמצעות kubectl.
אחזור הסטטוס הנוכחי.
עבור
WorkloadCertificateConfig:kubectl get WorkloadCertificateConfig default -o yamlעבור
TrustConfig:kubectl get TrustConfig default -o yamlבודקים את פלט הסטטוס. אובייקט תקין יכלול תנאי עם
type: Readyו-status: "True".status: conditions: - lastTransitionTime: "2021-03-04T22:24:11Z" message: WorkloadCertificateConfig is ready observedGeneration: 1 reason: ConfigReady status: "True" type: Readyבמקום זאת, מופיע
status: "False"לאובייקטים לא תקינים. השדותreasonוmessageמכילים פרטים נוספים לפתרון בעיות.
בקשות CSR לא מאושרות
אם משהו משתבש במהלך תהליך אישור ה-CSR, אפשר לבדוק את פרטי השגיאה בתנאים type: Approved ו-type: Issued של ה-CSR.
מציגים רשימה של בקשות CSR רלוונטיות באמצעות
kubectl:kubectl get csr \ --field-selector='spec.signerName=spiffe.gke.io/spiffe-leaf-signer'בוחרים בקובץ CSR שערכו הוא
ApprovedולאIssued, או שערכו לאApproved.כדי לקבל פרטים על בקשת ה-CSR שנבחרה באמצעות kubectl:
kubectl get csr CSR_NAME -o yamlמחליפים את
CSR_NAMEבשם של בקשת ה-CSR שבחרתם.
בקשת חתימה על אישור (CSR) תקינה כוללת תנאי עם type: Approved ו-status: "True", ואישור תקין בשדה status.certificate:
status:
certificate: <base64-encoded data>
conditions:
- lastTransitionTime: "2021-03-04T21:58:46Z"
lastUpdateTime: "2021-03-04T21:58:46Z"
message: Approved CSR because it is a valid SPIFFE SVID for the correct identity.
reason: AutoApproved
status: "True"
type: Approved
מידע לפתרון בעיות שקשורות לבקשות CSR לא תקינות מופיע בשדות message ו-reason.
לא ניתן להשתמש באישורי mTLS שהונפקו באפליקציות
מוודאים שתוקף האישור לא פג:
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"בודקים שסוג המפתח שבו השתמשתם נתמך על ידי האפליקציה.
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Public Key Algorithm" -A 3בודקים שרשות האישורים שהנפיקה את האישור משתמשת באותה משפחת מפתחות כמו מפתח האישור.
קבלת הסטטוס של שירות ה-CA (תצוגה מקדימה):
gcloud privateca ISSUING_CA_TYPE describe ISSUING_CA_NAME \ --location ISSUING_CA_LOCATIONמחליפים את מה שכתוב בשדות הבאים:
-
ISSUING_CA_TYPE: סוג רשות האישורים המנפיקה, שחייב להיותsubordinatesאוroots. -
ISSUING_CA_NAME: השם של רשות האישורים המנפיקה. -
ISSUING_CA_LOCATION: האזור של הרשות שמנפיקה את האישורים (CA).
-
בודקים שאלגוריתם המפתח
keySpec.algorithmבפלט זהה לזה שהגדרתם במניפסט YAML שלWorkloadCertificateConfig. הפלט אמור להיראות כך:config: ... subjectConfig: commonName: td-sub-ca subject: organization: TestOrgLLC subjectAltName: {} createTime: '2021-05-04T05:37:58.329293525Z' issuingOptions: includeCaCertUrl: true keySpec: algorithm: RSA_PKCS1_2048_SHA256 ...
האישורים נדחים
- מוודאים שאפליקציית העמיתים משתמשת באותו חבילת אמון כדי לאמת את האישור.
מוודאים שתוקף האישור לא פג:
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"אם לא משתמשים ב-Credentials Reloading API של gRPC Go, צריך לוודא שקוד הלקוח מרענן מעת לעת את פרטי הכניסה ממערכת הקבצים.
מוודאים שעומסי העבודה נמצאים באותו דומיין מהימן כמו רשות האישורים. אישורים של GKE mesh תומכים בתקשורת בין עומסי עבודה בדומיין אמון יחיד.