בידוד עומסי העבודה במאגרי צמתים ייעודיים

בדף הזה מוסבר איך להקטין את הסיכון למתקפות של הרחבת הרשאות באשכול שלכם. כדי לעשות זאת, צריך להגדיר ל-Google Kubernetes Engine ‏ (GKE) לתזמן את עומסי העבודה שלכם במאגר נפרד וייעודי של צמתים, הרחק מעומסי עבודה מנוהלים של GKE עם הרשאות. כדאי להשתמש בגישה הזו רק אם אי אפשר להשתמש ב-GKE Sandbox. GKE Sandbox היא הגישה המומלצת לבידוד צמתים. ‫GKE Sandbox מספק גם יתרונות נוספים לחיזוק עומסי העבודה.

הדף הזה מיועד למומחי אבטחה שנדרש להם בידוד של עומסי עבודה, אבל הם לא יכולים להשתמש בארגז החול של GKE. כדי לקבל מידע נוסף על תפקידים נפוצים ומשימות לדוגמה שאנחנו מתייחסים אליהם ב Google Cloud תוכן, אפשר לעיין במאמר תפקידים נפוצים של משתמשים ב-GKE ומשימות.

הדף הזה רלוונטי לאשכולות רגילים ללא הקצאה אוטומטית של צמתים. כדי להפריד בין עומסי עבודה באשכולות Autopilot ובאשכולות Standard עם הקצאה אוטומטית של צמתים, אפשר לעיין במאמר הגדרת הפרדה בין עומסי עבודה ב-GKE.

סקירה כללית

באשכולות GKE נעשה שימוש בעומסי עבודה מנוהלים של GKE עם הרשאות מיוחדות כדי להפעיל פונקציות ותכונות ספציפיות באשכול, כמו איסוף מדדים. לעומסי העבודה האלה מוקצות הרשאות מיוחדות כדי שהם יפעלו בצורה תקינה באשכול.

יכול להיות שעומסי עבודה שאתם פורסים בצמתים שלכם ייפרצו על ידי גורם זדוני. הפעלת עומסי העבודה האלה לצד עומסי עבודה מנוהלים ב-GKE עם הרשאות מיוחדות, מאפשרת לתוקף שפורץ מקונטיינר שנפרץ להשתמש בפרטי הכניסה של עומס העבודה עם ההרשאות המיוחדות בצומת כדי להרחיב את ההרשאות שלו באשכול.

מניעת בריחה מקונטיינר

ההגנה העיקרית שלכם צריכה להיות האפליקציות. ל-GKE יש כמה תכונות שבהן אפשר להשתמש כדי להקשיח את האשכולות וה-Pods. ברוב המקרים, מומלץ מאוד להשתמש ב-GKE Sandbox כדי לבודד את עומסי העבודה. ‫GKE Sandbox מבוסס על פרויקט הקוד הפתוח gVisor, ומיישם את Linux kernel API במרחב המשתמש. כל Pod פועל על ליבת מערכת הפעלה ייעודית שיוצרת ארגז חול לאפליקציות כדי למנוע גישה לקריאות מערכת עם הרשאות מיוחדות בליבת המארח. עומסי עבודה שפועלים בארגז חול של GKE מתוזמנים אוטומטית בצמתים נפרדים, ומבודדים מעומסי עבודה אחרים.

כדאי גם לפעול לפי ההמלצות במאמר הקשחת האבטחה באשכול.

הימנעות מהתקפות של הסלמת הרשאות (privilege escalation)

אם אתם לא יכולים להשתמש ב-GKE Sandbox, ואתם רוצים שכבת בידוד נוספת בנוסף לאמצעי אבטחה אחרים, אתם יכולים להשתמש בnode taints ובnode affinity כדי לתזמן את עומסי העבודה שלכם ב-node pool ייעודי. הגדרה של taint בצומת אומרת ל-GKE להימנע מתזמון עומסי עבודה ללא toleration תואם (כמו עומסי עבודה שמנוהלים על ידי GKE) בצמתים האלה. ההגדרה node affinity בעומסי העבודה שלכם אומרת ל-GKE לתזמן את ה-Pods שלכם בצמתים הייעודיים.

מגבלות של בידוד צמתים

  • תוקפים עדיין יכולים ליזום התקפות מניעת שירות (DoS) מהצומת שנפרץ.
  • צמתים שנפרצו עדיין יכולים לקרוא הרבה משאבים, כולל כל ה-Pods ומרחבי השמות באשכול.
  • צמתים שנפרצו יכולים לגשת לערכי Secret ולפרטי הכניסה שמשמשים כל Pod שפועל בצומת הזה.
  • שימוש במאגר צמתים נפרד כדי לבודד את עומסי העבודה יכול להשפיע על יעילות העלויות, על שינוי הגודל האוטומטי ועל ניצול המשאבים.
  • צמתים שנפרצו עדיין יכולים לעקוף את מדיניות הרשת ליציאה.
  • חלק מעומסי העבודה שמנוהלים על ידי GKE חייבים לפעול בכל צומת באשכול, והם מוגדרים כך שיוכלו לפעול למרות כל ההגבלות.
  • אם פורסים DaemonSets עם הרשאות גבוהות שיכולים להתמודד עם כל taint, יכול להיות שה-Pods האלה יהיו דרך להסלמת הרשאות מצומת שנפרצה.

איך פועל בידוד הצמתים

כדי להטמיע בידוד של צמתים בעומסי העבודה, צריך לבצע את הפעולות הבאות:

  1. הוספת כתם ותווית למאגר צמתים בשביל עומסי העבודה.
  2. מעדכנים את עומסי העבודה עם כלל הסבילות והזיקה לצומת המתאים.

במדריך הזה אנחנו יוצאים מנקודת הנחה שמתחילים עם מאגר צמתים אחד באשכול. לא חובה להשתמש בהעדפת צומת בנוסף להכתמת צומת, אבל מומלץ לעשות זאת כי כך אפשר לשלוט יותר בתזמון.

לפני שמתחילים

לפני שמתחילים, חשוב לוודא שביצעתם את הפעולות הבאות:

  • מפעילים את ממשק Google Kubernetes Engine API.
  • הפעלת Google Kubernetes Engine API
  • כדי להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז להפעיל את gcloud CLI. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה gcloud components update כדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
  • בוחרים שם ספציפי ל-taint של הצומת ולתווית הצומת שרוצים להשתמש בהם עבור מאגרי הצמתים הייעודיים.

הוספת כתם ותווית למאגר צמתים בשביל עומסי העבודה

יוצרים מאגר צמתים חדש לעומסי העבודה ומחילים עליו taint של צומת ותווית צומת. כשמחילים taint או תווית ברמת מאגר הצמתים, כל הצמתים החדשים, כמו אלה שנוצרו על ידי שינוי גודל אוטומטי, מקבלים באופן אוטומטי את ה-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 לתזמן את עומסי העבודה רק במאגר הצמתים הזה.

בדוגמה הבאה מוסיפים toleration ל-taint‏ workloadType=untrusted:NoExecute וכלל node affinity לתווית הצומת 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_VALUE: ערך ה-taint שהגדרתם למאגר הצמתים הייעודי.
  • LABEL_KEY: מפתח התווית של הצומת שהוספתם למאגר הצמתים הייעודי.
  • LABEL_VALUE: הערך של תווית הצומת שהחלתם על מאגר הצמתים הייעודי.

כשמעדכנים את הפריסה באמצעות kubectl apply, ‏ GKE יוצר מחדש את ה-Pods המושפעים. כלל ההתאמה של הצומת מאלץ את ה-Pods אל מאגר הצמתים הייעודי שיצרתם. הסבילות מאפשרת להציב את ה-Pods האלה רק בצמתים.

איך מוודאים שההפרדה פועלת

כדי לוודא שהתזמון פועל כמו שצריך, מריצים את הפקודה הבאה ובודקים אם עומסי העבודה נמצאים במאגר הצמתים הייעודי:

kubectl get pods -o=wide

המלצות ושיטות מומלצות

אחרי שמגדירים בידוד של צמתים, מומלץ לבצע את הפעולות הבאות:

  • כדי להגביל מאגרי צמתים ספציפיים רק לעומסי עבודה שמנוהלים על ידי GKE, מוסיפים את ה-taint‏ components.gke.io/gke-managed-components. הוספת ההכתמה הזו מונעת מה-Pods שלכם להיקבע לתזמון בצמתים האלה, וכך משפרת את הבידוד.
  • כשיוצרים מאגרי צמתים חדשים, אפשר למנוע את ההרצה של רוב עומסי העבודה שמנוהלים על ידי GKE בצמתים האלה על ידי הוספת taint משלכם למאגרי הצמתים האלה.
  • בכל פעם שפורסים עומסי עבודה חדשים באשכול, למשל כשמתקינים כלי צד שלישי, צריך לבדוק את ההרשאות שנדרשות ל-Pods. כשאפשר, מומלץ להימנע מפריסת עומסי עבודה שמשתמשים בהרשאות מורחבות לצמתים משותפים.

המאמרים הבאים