בדף הזה מוסבר איך להקטין את הסיכון למתקפות של הרחבת הרשאות באשכול שלכם. כדי לעשות זאת, צריך להגדיר ל-Google Kubernetes Engine (GKE) לתזמן את עומסי העבודה שלכם במאגר נפרד וייעודי של צמתים, הרחק מעומסי עבודה מנוהלים של GKE עם הרשאות. כדאי להשתמש בגישה הזו רק אם אי אפשר להשתמש ב-GKE Sandbox. GKE Sandbox היא הגישה המומלצת לבידוד צמתים. GKE Sandbox מספק גם יתרונות נוספים לחיזוק האבטחה של עומסי העבודה.
הדף הזה מיועד למומחי אבטחה שנדרש להם שכבת בידוד בעומסי עבודה, אבל הם לא יכולים להשתמש ב-GKE Sandbox. כדי לקבל מידע נוסף על תפקידים נפוצים ומשימות לדוגמה שאנחנו מתייחסים אליהם ב Google Cloud תוכן, אפשר לעיין במאמר תפקידים נפוצים של משתמשי GKE ומשימות.
הדף הזה רלוונטי לאשכולות Standard ללא הקצאת צמתים אוטומטית (NAP). כדי להפריד בין עומסי עבודה באשכולות Autopilot ובאשכולות Standard עם הקצאה אוטומטית של צמתים, אפשר לעיין במאמר הגדרת הפרדה בין עומסי עבודה ב-GKE.
סקירה כללית
אשכולות GKE משתמשים בעומסי עבודה מנוהלים של GKE עם הרשאות מיוחדות כדי להפעיל פונקציות ותכונות ספציפיות של האשכול, כמו איסוף מדדים. לעומסי העבודה האלה מוקצות הרשאות מיוחדות כדי שהם יפעלו בצורה תקינה באשכול.
יכול להיות שעומסי עבודה שאתם פורסים בצמתים ייפגעו על ידי גורם זדוני. הפעלת עומסי העבודה האלה לצד עומסי עבודה מנוהלים ב-GKE עם הרשאות מיוחדות, פירושה שתוקף שפורץ מקונטיינר שנפרץ יכול להשתמש בפרטי הכניסה של עומס העבודה עם ההרשאות המיוחדות בצומת כדי להרחיב את ההרשאות שלו באשכול.
מניעת בריחה מקונטיינר
ההגנה העיקרית שלכם צריכה להיות האפליקציות שלכם. ב-GKE יש כמה תכונות שאפשר להשתמש בהן כדי להקשיח את האשכולות וה-Pods. ברוב המקרים, מומלץ מאוד להשתמש ב-GKE Sandbox כדי לבודד את עומסי העבודה. GKE Sandbox מבוסס על פרויקט הקוד הפתוח gVisor, ומיישם את Linux kernel API במרחב המשתמש. כל Pod פועל על ליבת מערכת הפעלה ייעודית שמבודדת את האפליקציות כדי למנוע גישה לקריאות מערכת עם הרשאות מיוחדות בליבת המארח. עומסי עבודה שפועלים ב-GKE Sandbox מתוזמנים אוטומטית בצמתים נפרדים, ומבודדים מעומסי עבודה אחרים.
כדאי גם לפעול לפי ההמלצות במאמר הקשחת האבטחה באשכול.
איך להימנע מהתקפות של הסלמת הרשאות
אם אתם לא יכולים להשתמש ב-GKE Sandbox, ואתם רוצים שכבת בידוד נוספת בנוסף לאמצעי הקשחה אחרים, אתם יכולים להשתמש בטעינות של צמתים ובהעדפות של צמתים כדי לתזמן את עומסי העבודה במאגר צמתים ייעודי. הכתמה של צומת אומרת ל-GKE להימנע מתזמון עומסי עבודה ללא סבילות תואמת (כמו עומסי עבודה שמנוהלים על ידי GKE) בצמתים האלה. ההגדרה node affinity בעומסי העבודה שלכם אומרת ל-GKE לתזמן את ה-Pods בצמתים הייעודיים.
המגבלות של בידוד צמתים
- תוקפים עדיין יכולים ליזום התקפות מניעת שירות (DoS) מהצומת שנפרץ.
- צמתים שנפרצו עדיין יכולים לקרוא משאבים רבים, כולל כל ה-Pods ומרחבי השמות באשכול.
- צמתים שנפרצו יכולים לגשת לסודות ולפרטי כניסה שמשמשים כל Pod שפועל בצומת הזה.
- שימוש במאגר צמתים נפרד כדי לבודד את עומסי העבודה יכול להשפיע על יעילות העלויות, על ההתאמה האוטומטית לעומס ועל ניצול המשאבים.
- צמתים שנפרצו עדיין יכולים לעקוף את מדיניות הרשת ב-Kubernetes ליציאה.
- חלק מעומסי העבודה שמנוהלים על ידי GKE חייבים לפעול בכל צומת באשכול, והם מוגדרים כך שיוכלו לפעול למרות כל ההכתמות.
- אם אתם פורסים DaemonSets עם הרשאות מוגברות שיכולים לסבול כל taint, יכול להיות שה-Pods האלה יהיו נתיב להסלמת הרשאות מצומת שנפרץ.
איך פועל בידוד צמתים
כדי להטמיע בידוד של צמתים בעומסי העבודה, צריך לבצע את הפעולות הבאות:
- הוספת טיינט ותווית למאגר צמתים בשביל עומסי העבודה.
- מעדכנים את עומסי העבודה באמצעות כלל הסבילות והזיקה לצומת המתאים.
במדריך הזה אנחנו יוצאים מנקודת הנחה שמתחילים עם מאגר צמתים אחד באשכול. לא חובה להשתמש בהעדפת צומת בנוסף להכתמת צומת, אבל מומלץ לעשות זאת כי כך נהנים משליטה רבה יותר בתזמון.
לפני שמתחילים
לפני שמתחילים, חשוב לוודא שביצעתם את המשימות הבאות:
- מפעילים את ממשק ה-API של Google Kubernetes Engine. הפעלת Google Kubernetes Engine API
- כדי להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז לאתחל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה
gcloud components updateכדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
- בוחרים שם ספציפי ל-taint של הצומת ולתווית הצומת שרוצים להשתמש בהם עבור מאגרי הצמתים הייעודיים.
הוספת כתם ותווית למאגר צמתים לעומסי העבודה
יוצרים מאגר צמתים חדש לעומסי העבודה, ומחילים עליו טאנט ותווית. כשמחילים דחייה (taint) או תווית ברמת מאגר הצמתים, כל הצמתים החדשים, כמו אלה שנוצרו על ידי התאמה אוטומטית לעומס (automatic scaling), מקבלים באופן אוטומטי את ה-taint והתוויות שצוינו.
אפשר גם להוסיף כתמי צומת ותוויות צומת למאגרי צמתים קיימים. אם משתמשים באפקט NoExecute, GKE מפנה את כל ה-Pods שפועלים בצמתים האלה, שאין להם סבילות ל-taint החדש.
כדי לבודד עומסי עבודה, תמיד צריך להשתמש בקידומת node-restriction.kubernetes.io/ בתוויות של הצמתים ובבוררים התואמים במניפסטים של ה-Pod.
התחילית הזו מונעת מתוקפים להשתמש בפרטי הכניסה של הצומת כדי להגדיר או לשנות את התוויות שמשתמשות בתחילית הזו. למידע נוסף, קראו את המאמר בידוד/הגבלה של צמתים במסמכי התיעוד של Kubernetes.
כדי להוסיף taint ותווית למאגר צמתים חדש, מריצים את הפקודה הבאה:
gcloud container node-pools create POOL_NAME \
--cluster=CLUSTER_NAME \
--node-taints=TAINT_KEY=TAINT_VALUE:TAINT_EFFECT \
--node-labels=node-restriction.kubernetes.io/LABEL_KEY=LABEL_VALUE
מחליפים את מה שכתוב בשדות הבאים:
-
POOL_NAME: השם של מאגר הצמתים החדש לעומסי העבודה. -
CLUSTER_NAME: השם של אשכול GKE. TAINT_KEY=TAINT_VALUE: זוג של מפתח וערך שמשויך לתיזמוןTAINT_EFFECT. לדוגמה:workloadType=untrusted.-
TAINT_EFFECT: אחד מערכי ההשפעה הבאים:NoSchedule,PreferNoScheduleאוNoExecute. NoExecuteמספקת ערבות טובה יותר לפינוי מאשרNoSchedule. -
node-restriction.kubernetes.io/LABEL_KEY=LABEL_VALUE: צמדי מפתח/ערך של תוויות הצומת, שתואמים לסלקטורים שציינתם במניפסטים של עומסי העבודה. הקידומתnode-restriction.kubernetes.io/מונעת שימוש בפרטי הכניסה של הצומת כדי להגדיר את צמדי המפתח/ערך האלה בצמתים.
הוספת כלל סבילות וכלל שיוך צומת לעומסי העבודה
אחרי שמוסיפים דחייה למאגר הצמתים הייעודי, אי אפשר להקצות בו עומסי עבודה אלא אם יש להם טולרנטיות שמתאימה לדחייה שהוספתם. מוסיפים את ה-toleration למפרט של עומסי העבודה כדי לאפשר לתרמילים האלה לתזמן את עצמם במאגר הצמתים המזוהם.
אם הוספתם תווית למאגר הצמתים הייעודי, אתם יכולים גם להוסיף כלל של זיקה לצומת כדי להנחות את GKE לתזמן את עומסי העבודה רק במאגר הצמתים הזה.
בדוגמה הבאה, הוספנו סובלנות ל-taint של workloadType=untrusted:NoExecute וכלל של שיוך לצומת לתווית הצומת workloadType=untrusted.
kind: Deployment
apiVersion: apps/v1
metadata:
name: my-app
namespace: default
labels:
app: my-app
spec:
replicas: 1
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
tolerations:
- key: TAINT_KEY
operator: Equal
value: TAINT_VALUE
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-restriction.kubernetes.io/LABEL_KEY
operator: In
values:
- "LABEL_VALUE"
containers:
- name: sleep
image: ubuntu
command: ["/bin/sleep", "inf"]
מחליפים את מה שכתוב בשדות הבאים:
-
TAINT_KEY: מפתח ה-taint שהחלתם על מאגר הצמתים הייעודי. -
TAINT_VALUE: ערך ה-taint שהחלתם על מאגר הצמתים הייעודי. -
LABEL_KEY: מפתח התווית של הצומת שהוספתם למאגר הצמתים הייעודי. -
LABEL_VALUE: הערך של תווית הצומת שהחלתם על מאגר הצמתים הייעודי.
כשמעדכנים את הפריסה באמצעות kubectl apply, GKE יוצר מחדש את ה-Pods המושפעים. כלל ההתאמה של הצומת מכריח את ה-Pods לעבור למאגר הצמתים הייעודי שיצרתם. הסבילות מאפשרת להציב את הפודים האלה רק בצמתים.
איך מוודאים שההפרדה פועלת
כדי לוודא שהתזמון פועל בצורה תקינה, מריצים את הפקודה הבאה ובודקים אם עומסי העבודה נמצאים במאגר הצמתים הייעודי:
kubectl get pods -o=wide
המלצות ושיטות מומלצות
אחרי שמגדירים בידוד צמתים, מומלץ לבצע את הפעולות הבאות:
- כדי להגביל מאגרי צמתים ספציפיים רק לעומסי עבודה שמנוהלים על ידי GKE, מוסיפים את ה-taint
components.gke.io/gke-managed-components. הוספת הכתם הזה מונעת מה-Pods שלכם לתזמן בצמתים האלה, ומשפרת את הבידוד. - כשיוצרים מאגרי צמתים חדשים, אפשר למנוע מרוב עומסי העבודה שמנוהלים על ידי GKE לפעול בצמתים האלה, על ידי הוספת טיינט משלכם למאגרי הצמתים האלה.
- בכל פעם שפורסים עומסי עבודה חדשים באשכול, למשל כשמתקינים כלי צד שלישי, צריך לבדוק את ההרשאות שנדרשות ל-Pods. כאשר אפשר, כדאי להימנע מפריסת עומסי עבודה שמשתמשים בהרשאות מורחבות לצמתים משותפים.