אתם יכולים להגן על ליבת המארח של צומתי Google Kubernetes Engine (GKE) מפני קונטיינרים שמריצים קוד לא מהימן או לא מוכר באמצעות GKE Sandbox. במאמר הזה מוסבר למומחי אבטחה איך להפעיל את GKE Sandbox, להריץ Pods בארגזי חול (sandbox) ולאמת את הבידוד.
אתם כבר אמורים להכיר את GKE Sandbox.
סוגי ארגזי החול הזמינים
GKE Sandbox תומך בסוגי ארגז חול הבאים, שכל אחד מהם משתמש בטכנולוגיה ספציפית כדי להפריד את קוד האפליקציה מהליבה של המארח:
-
gvisor: הטמעה מחדש של ממשק ה-API של ליבת Linux במרחב המשתמש, שלא דורשת הרשאות מורחבות. ליבת מרחב המשתמש מיירטת את רוב קריאות המערכת ומטפלת בהן בשם ליבת המארח, וכך מגבילה את הגישה הישירה לליבת המארח. -
microvm: מכונות וירטואליות קלות משקל שמוטמעות במכונה הווירטואלית המארחת באמצעות nested virtualization. כל Pod בצומת פועל במכונה וירטואלית נפרדת עם ליבת אורח משלו. מכיוון שהקוד פועל במכונה וירטואלית ייעודית, סוג ארגז החול הזה מספק בידוד חזק יותר מארגזי חול של gVisor.
במאמר מידע על GKE Sandbox מוסבר איך פועל כל סוג של ארגז חול ומתי כדאי להשתמש בסוג מסוים.
מגבלות
יש מגבלות שונות על GKE Sandbox ועל טכנולוגיות ספציפיות של ארגז חול, כמו תמיכה ב-GPU וב-TPU או תמיכה בתכונות ספציפיות של Linux ו-Kubernetes. מידע נוסף מופיע בקטע מגבלות.
לפני שמתחילים
לפני שמתחילים, חשוב לוודא שביצעתם את המשימות הבאות:
- מפעילים את ממשק ה-API של Google Kubernetes Engine. הפעלת Google Kubernetes Engine API
- כדי להשתמש ב-Google Cloud CLI למשימה הזו, מתקינים ואז מאתחלים את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה
gcloud components updateכדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
- כדי לבצע את השלבים בקטע בחירת סוג ארגז חול לצמתים שנוצרו באופן אוטומטי, צריך להשתמש באשכול קיים של Autopilot או באשכול רגיל. כדי להשתמש בארגזי חול של microVM, הצמתים צריכים להריץ את GKE בגרסה 1.37.0-gke.4713000 ואילך.
בחירת סוג ארגז חול לצמתים שנוצרים אוטומטית
אתם יכולים להשתמש ב-ComputeClasses עם מצב Autopilot או עם יצירה אוטומטית של מאגר צמתים כדי להפעיל את GKE Sandbox בצמתים שנוצרו על ידי GKE. באשכולות Autopilot, gVisor נתמך כברירת מחדל, כך שאפשר להשמיט את הגדרת הסביבת ארגז חול מ-ComputeClass.
כדי להגדיר את GKE Sandbox לצמתים שנוצרים אוטומטית, מבצעים את השלבים הבאים:
חיבור לאשכול קיים במצב Autopilot או סטנדרטי:
gcloud container clusters get-credentials CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATIONמחליפים את מה שכתוב בשדות הבאים:
-
CLUSTER_NAME: השם של האשכול. -
CONTROL_PLANE_LOCATION: האזור או האזור הזמין של מישור הבקרה של האשכול.
-
שומרים אחד ממניפסטים של ComputeClass הבאים, בהתאם לטכנולוגיית ארגז החול שרוצים:
gVisor:
apiVersion: cloud.google.com/v1 kind: ComputeClass metadata: name: sandbox-gvisor-class spec: priorities: - machineFamily: n4 - machineFamily: c4 nodePoolConfig: sandbox: type: gvisor nodePoolAutoCreation: enabled: true whenUnsatisfiable: DoNotScaleUpmicroVM:
apiVersion: cloud.google.com/v1 kind: ComputeClass metadata: name: sandbox-microvm-class spec: priorities: - machineFamily: n4 - machineFamily: c4 nodePoolConfig: sandbox: type: microvm priorityDefaults: enableNestedVirtualization: true nodePoolAutoCreation: enabled: true whenUnsatisfiable: DoNotScaleUpה-ComputeClass לארגזי חול של מכונות מיקרו וירטואליות מאפשר וירטואליזציה מקוננת באמצעות השדה
enableNestedVirtualization. השדה הזה נדרש לארגזי חול של microVM. כדי להשתמש בשדה הזה, האשכול צריך להיות בגרסה 1.37.0-gke.4713000 ואילך.
במניפסטים לדוגמה האלה נעשה שימוש בשדה
nodePoolAutoCreationכדי להפעיל יצירה אוטומטית של מאגרי צמתים. אפשר גם לציין את הגדרות הסביבת ארגז חול ב-ComputeClass שמשתמש בשדהautopilotכדי להריץ את ה-Pods במצב אוטומטי. אם אתם משתמשים באשכולות Autopilot, GKE מתעלם מהשדותnodePoolAutoCreationו-autopilot.יוצרים את ComputeClass:
kubectl apply -f PATH_TO_COMPUTE_CLASS_MANIFESTמחליפים את
PATH_TO_COMPUTE_CLASS_MANIFESTבנתיב למניפסט של ComputeClass.
כדי לבחור את ComputeClass הזה ולבקש סביבת Sandbox, אפשר לעיין במאמר בנושא בקשת סביבת Sandbox ל-Pod.
בחירת סוג ארגז חול כשיוצרים מאגרי צמתים
אפשר להפעיל את GKE Sandbox באופן ידני כשיוצרים מאגר צמתים חדש באשכול רגיל. ההגבלות הבאות חלות כשמפעילים את GKE Sandbox באופן ידני:
- כדי להפעיל את GKE Sandbox במהלך יצירת אשכול Standard, צריך להגדיר לפחות מאגר צמתים נוסף אחד. בריכת הצמתים הנוספת נדרשת כי GKE צריך לפחות בריכת צמתים אחת באשכול שלא משתמשת ב-GKE Sandbox כדי להריץ עומסי עבודה של מערכת שמנוהלים על ידי GKE. אם משתמשים ב-CLI של gcloud כדי ליצור את האשכול, צריך ליצור את האשכול ואז ליצור מאגר צמתים שמשתמש ב-GKE Sandbox.
- כדי לבחור את סוג ארגז החול של microVM, צריך להשתמש ב-CLI של gcloud או ב-GKE API. במסוףCloud de Confiance אי אפשר לבחור את סוג ארגז החול microVM.
הפעלת סוג ארגז החול gVisor
כדי להפעיל באופן ידני ארגזי חול של gVisor כשיוצרים מאגר צמתים חדש, בוחרים באחת מהאפשרויות הבאות:
המסוף
נכנסים לדף Kubernetes clusters במסוף Cloud de Confiance .
לוחצים על השם של האשכול שרוצים לשנות. נפתח הדף Cluster details.
לוחצים על הכרטיסייה Nodes (צמתים).
בקטע מאגרי צמתים, לוחצים על הוספת מאגר צמתים מנוהל על ידי המשתמש. נפתח הדף Add a node pool (הוספת מאגר צמתים).
בתפריט הניווט, לוחצים על Nodes ומגדירים את ההגדרות הבאות:
- בתפריט הנפתח Image type, בוחרים באפשרות Container-Optimized OS with Containerd (cos_containerd).
- בקטע Machine configuration, בוחרים סדרת מכונות וסוג מכונה לצמתים.
- אופציונלי: בוחרים סוג GPU נתמך או סוג TPU נתמך.
בתפריט הניווט, לוחצים על אבטחה. ייפתח הדף אבטחת הצומת.
מסמנים את התיבה הפעלת ארגז חול (sandbox) עם gVisor.
כדי ליצור את מאגר הצמתים, לוחצים על Create (יצירה).
gcloud
כדי ליצור מאגר צמתים שמשתמש ב-gVisor לארגזי חול, מריצים את הפקודה הבאה:
gcloud container node-pools create NODE_POOL_NAME \
--cluster=CLUSTER_NAME \
--location=CONTROL_PLANE_LOCATION \
--sandbox=type=gvisor
מחליפים את מה שכתוב בשדות הבאים:
-
NODE_POOL_NAME: שם למאגר הצמתים. -
CLUSTER_NAME: השם של האשכול. -
CONTROL_PLANE_LOCATION: האזור או האזור הזמין של מישור הבקרה של האשכול.
אתם יכולים גם להפעיל ארגזי חול של gVisor כשאתם יוצרים מאגרי צמתים שמשתמשים בסוג GPU נתמך או בסוג TPU נתמך. מידע נוסף זמין במאמרים הבאים:
הפעלת סוג ארגז החול microVM
אפשר להפעיל את סוג ארגז החול microVM כשיוצרים מאגר צמתים באמצעות ה-CLI של gcloud או GKE API. ב Cloud de Confiance מסוף אין תמיכה בהפעלת סוג ארגז החול של microVM. כדי ליצור מאגר צמתים שמשתמש בארגזי חול של מכונות מיקרו-וירטואליות, מריצים את הפקודה הבאה:
gcloud container node-pools create NODE_POOL_NAME \
--cluster=CLUSTER_NAME \
--location=CONTROL_PLANE_LOCATION \
--sandbox=type=microvm \
--enable-nested-virtualization \
--machine-type=MACHINE_TYPE
מחליפים את מה שכתוב בשדות הבאים:
-
NODE_POOL_NAME: שם למאגר הצמתים. -
CLUSTER_NAME: שם האשכול. -
CONTROL_PLANE_LOCATION: האזור או האזור של מישור הבקרה של האשכול. -
MACHINE_TYPE: סוג המכונה של הצמתים. הערך הזה חייב להיות סוג מכונה שתומך בווירטואליזציה בתצורה מקוננת. מידע נוסף זמין בשורה Nested virtualization בטבלת ההשוואה בין סדרות המכונות.
הפעלת מעקב ורישום ביומן
כדי לאסוף ולהציג יומנים ומדדים מהארגזים שלכם, צריך לוודא שהאפשרות 'שירותי יכולת צפייה' מופעלת באשכול שלכם:
השירותים האלה מופעלים כברירת מחדל בכל אשכולות GKE החדשים.
בקשת סביבת ארגז חול ל-Pod
כדי להריץ Pod ספציפי בארגז חול, אפשר לציין את RuntimeClass של gvisor או microvm במפרט של ה-Pod. GKE מתזמן את ה-Pod בצמתים שמשתמשים בסוג ארגז החול שצוין. כדי לבחור סוג של ארגז חול במפרט של Pod, פועלים לפי השלבים הבאים:
שומרים את אחד ממניפסטים הפריסה לדוגמה הבאים, בהתאם לאופן שבו הפעלתם את GKE Sandbox באמצעות ComputeClasses או מאגרי צמתים שנוצרו באופן ידני:
ComputeClasses:
apiVersion: apps/v1 kind: Deployment metadata: name: sandbox-pod labels: environment: sandbox spec: replicas: 2 selector: matchLabels: environment: sandbox template: metadata: labels: environment: sandbox spec: nodeSelector: cloud.google.com/compute-class: COMPUTECLASS_NAME runtimeClassName: SANDBOX_TYPE containers: - name: nginx image: nginxמחליפים את מה שכתוב בשדות הבאים:
COMPUTECLASS_NAME: השם של ComputeClass שיצרתם, כמו שמתואר במאמר בחירת סוג ארגז חול לצמתים שנוצרים אוטומטית.
SANDBOX_TYPE: סוג ארגז החול שבו רוצים להשתמש עבור ה-Pods. יש תמיכה בערכים הבאים:gvisormicrovm
סוג ארגז החול שאתם מציינים צריך להיות זהה לסוג ארגז החול שמאפשרת ComputeClass שנבחרה.
מאגרי צמתים שנוצרו באופן ידני:
apiVersion: apps/v1 kind: Deployment metadata: name: httpd labels: app: httpd spec: replicas: 1 selector: matchLabels: app: httpd template: metadata: labels: app: httpd spec: runtimeClassName: SANDBOX_TYPE containers: - name: httpd image: httpdמחליפים את
SANDBOX_TYPEבסוג של ארגז החול. הערכים הבאים נתמכים:gvisormicrovm
סוג ארגז החול שאתם מציינים צריך להיות זהה לסוג ארגז החול של מאגר צמתים קיים באשכול.
יוצרים את הפריסה:
kubectl apply -f PATH_TO_DEPLOYMENT_MANIFESTמחליפים את
PATH_TO_DEPLOYMENT_MANIFESTבנתיב למניפסט הפריסה.מוודאים שה-Pods נוצרו:
kubectl get podsהפלט אמור להיראות כך:
NAME READY STATUS RESTARTS AGE httpd-db5899bc9-dk7lk 1/1 Running 0 24s
אפשר גם לבקש ארגזי חול כשמריצים Pods על סוג GPU נתמך
או על סוג TPU נתמך באמצעות השדה runtimeClassName. מידע נוסף זמין במאמרים הבאים:
- פריסת עומסי עבודה של GPU ב-GKE Standard
- פריסת עומסי עבודה של TPU ב-GKE Standard
- פריסת עומסי עבודה של GPU ב-Autopilot
- פריסת עומסי עבודה של TPU ב-Autopilot
הפעלת Pod רגיל לצד Pods בארגז חול
השלבים בקטע הזה רלוונטיים לעומסי עבודה במצב רגיל. אין צורך להריץ Pods רגילים לצד Pods של ארגז חול במצב Autopilot, כי מודל התמחור של Autopilot מבטל את הצורך לבצע אופטימיזציה ידנית של מספר ה-Pods שמתוזמנים בצמתים.
אחרי שמפעילים את GKE Sandbox במאגר צמתים, אפשר להריץ צמתים מהימנים בלי להשתמש בארגז חול, באמצעות taints ו-tolerations של צמתים. ה-Pods האלה נקראים 'Pods רגילים' כדי להבדיל ביניהם לבין Pods בתוך ארגז חול.
ל-Pods רגילים, בדיוק כמו ל-Pods בסביבת ארגז חול, אין גישה לCloud de Confiance שירותים אחרים או למטא-נתונים של האשכול. המניעה הזו היא חלק מההגדרות של הצומת. אם הפודים הרגילים או הפודים בארגז החול צריכים גישה לשירותיCloud de Confiance , השתמשו באיחוד זהויות של עומסי עבודה ל-GKE.
GKE Sandbox מוסיף את התווית וה-taint הבאים לצמתים שיכולים להריץ Pods בארגז חול:
- התווית של צומת
sandbox.gke.io/runtime: SANDBOX_TYPE. - הדחייה (taint) של הצומת
sandbox.gke.io/runtime=SANDBOX_TYPE:NoSchedule. אפשר לתזמן צמתים רק ל-Pods שיש להם התאמה לסבילות.
אם משתמשים בשדה RuntimeClass כדי להריץ Pod בסביבת ארגז חול, GKE מחיל אוטומטית זיקה של צומת וטולרנטיות על ה-Pod. כדי להריץ Pod רגיל בצומת שמשתמש ב-GKE Sandbox, צריך להחיל באופן ידני את הסלקטורים הבאים על מפרט ה-Pod:
- כדי לאפשר ל-Pod לפעול בצמתים שמשתמשים ב-GKE Sandbox כשצריך, מוסיפים רק את ה-טולרנטיות ל-דחייה (taint) של הצומת.
- כדי להריץ את ה-Pod רק בצמתים שמשתמשים ב-GKE Sandbox, מוסיפים בורר צמתים וטולרנטיות ל-node taint.
בשלבים הבאים מוסבר איך להריץ Pod רגיל בצומת שמשתמש ב-GKE Sandbox:
שומרים את מניפסט הפריסה הבא בתור
httpd-regular.yaml:apiVersion: apps/v1 kind: Deployment metadata: name: httpd-regular labels: app: httpd-regular spec: replicas: 1 selector: matchLabels: app: httpd-regular template: metadata: labels: app: httpd-regular spec: containers: - name: httpd-regular image: httpd affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: sandbox.gke.io/runtime operator: In values: - SANDBOX_TYPE tolerations: - effect: NoSchedule key: sandbox.gke.io/runtime operator: Equal value: SANDBOX_TYPEמחליפים את
SANDBOX_TYPEבסוג של ארגז החול, כמוgvisorאוmicrovm.יוצרים את הפריסה:
kubectl apply -f httpd-regular.yamlאם אי אפשר לתזמן את ה-Pod, צריך לוודא שהזיקה של הצומת והסבילות מוגדרות בצורה נכונה במניפסט של ה-Pod.
מוודאים שה-Pod לא נמצא בסביבת ארגז חול:
kubectl get pods -o jsonpath=$'{range .items[*]}{.metadata.name}: {.spec.runtimeClassName}\n{end}'הפלט אמור להיראות כך:
httpd-db5899bc9-dk7lk: SANDBOX_TYPE httpd-regular-5bf87996c6-cfmmd:ל-Pod
httpd-regularאין ערך של RuntimeClass, כלומר ה-Pod לא נמצא בארגז חול.מוודאים שה-Pod הרגיל פועל בצומת שמשתמש ב-GKE Sandbox:
kubectl get pod -o jsonpath=$'{range .items[*]}{.metadata.name}: {.spec.nodeName}\n{end}'הפלט אמור להיראות כך:
httpd-db5899bc9-dk7lk: gke-cluster-2-pool-1-75c8fc63-h373 httpd-regular-5bf87996c6-cfmmd: gke-cluster-2-pool-1-75c8fc63-h373ה-Pod בארגז החול וה-Pod הרגיל נמצאים באותו צומת, מה שמצביע על כך שה-Pod הרגיל פועל בצומת שמשתמש ב-GKE Sandbox.
אימות ההגדרות של ארגז החול
בקטעים הבאים מוסבר איך לוודא ש-Pod פועל בארגז חול ושה-Pod בארגז החול מבודד מליבת המארח. בקטעים האלה אנחנו מניחים שיצרתם את ה-Deployment לדוגמה בבקשת סביבת Sandbox ל-Pod.
איך מוודאים ש-Pod פועל בארגז חול
כדי לבדוק אם ה-Pods משתמשים בארגז חול, צריך לקבל את ה-RuntimeClass של ה-Pods. השיטה הזו מהימנה יותר מהרצת פקודה בתוך ה-Pod, כי לא תראו נתונים מתוך ארגז החול עצמו. אי אפשר לסמוך על כל מה שמדווח מתוך ארגז החול, כי יכול להיות שהוא פגום או זדוני.
מקבלים את ה-RuntimeClass של כל Pod שפועל:
kubectl get pods -l=app=httpd -o jsonpath=$'{range .items[*]}{.metadata.name}: {.spec.runtimeClassName}\n{end}'הפלט אמור להיראות כך:
httpd-db5899bc9-dk7lk: gvisor httpd-db5899bc9-ab3cd: gvisorאם הפלט הוא
gvisorאוmicrovm, ה-Pod פועל בארגז חול.
אימות הבידוד של ה-Pods בארגז חול מהמארח
כדי לוודא ש-Pod בארגז חול מבודד מצומת המארח, צריך לבדוק את המכשירים הווירטואליים הזמינים ואת גרסת הליבה שאליה יש ל-Pod גישה.
בארגזי חול של gVisor ושל מכונות וירטואליות מיקרו, בודקים אם גרסת הליבה שאליה יש ל-Pod גישה שונה מגרסת הליבה של צומת המארח:
מקבלים את גרסת הליבה שלפוד יש גישה אליה:
kubectl exec POD_NAME -- uname -rמחליפים את
POD_NAMEבשם של ה-Pod.הפלט אמור להיראות כך:
4.19.0-gvisorכדי לקבל את גרסת הליבה בצומת המארח:
kubectl get node NODE_NAME \ -o jsonpath='{.status.nodeInfo.kernelVersion}'מחליפים את
NODE_NAMEבשם הצומת שבו פועל ה-Pod.הפלט אמור להיראות כך:
6.12.94+
גרסת הליבה של צומת המארח שונה מגרסת הליבה שאליה יש ל-Pod בסביבת ארגז חול גישה, כי ה-Pod רואה רק את ליבת מרחב המשתמשים של gVisor או את ליבת האורח של מכונות וירטואליות מיקרו.
בארגזי חול של מכונות וירטואליות מיקרו, אפשר גם לבדוק אם המכשירים שיש ל-Pod גישה אליהם עוברים וירטואליזציה על ידי Cloud Hypervisor:
kubectl exec POD_NAME -- cat /sys/class/dmi/id/product_nameאם הפלט הוא
cloud-hypervisor, ה-Pod נמצא בארגז חול של microVM.
השבתת GKE Sandbox
אי אפשר להשבית את GKE Sandbox באשכולות GKE Autopilot או במאגרי צמתים של GKE Standard. אם רוצים להפסיק להשתמש ב-GKE Sandbox, צריך למחוק את מאגר הצמתים.