אבטחת Kubernetes: מדריך ארכיטקטוני להגנה על cluster בפרודקשן

מאת צוות מדיה דיל · 05.08.2026 · DevOps · 7 דק'

מדריך מעמיק לאבטחת Kubernetes בכל שכבות ה-stack: RBAC, Pod Security, Network Policies, ניהול Secrets, אבטחת שרשרת האספקה ו-runtime security.

ביקורת אבטחה ב-cluster של חברת פינטק ישראלית חשפה שרשרת בעיות שבפני עצמה כל אחת נראתה קטנה, אבל יחד יצרו נתיב תקיפה מלא: pod שרץ עם הרשאות root מיותרות, ServiceAccount עם RBAC רחב מדי שהיה מקושר אליו, Secret שהיה חשוף כ-environment variable שאפשר לחלץ אותו בקלות מתוך לוגים, וחוסר Network Policy שאפשר לpod שנפרץ לתקשר חופשי עם מסד הנתונים הפנימי. אף אחת מהבעיות האלה לא הייתה 'חמורה' לבדה, אבל השרשרת המלאה הפכה תקיפה תיאורטית לנתיב מעשי מפרודקשן ועד לגניבת נתונים. אבטחת Kubernetes היא בדיוק על זה - הבנה שאבטחה היא לא פיצ'ר בודד אלא הצטברות של שכבות (defense in depth), וכל שכבה חלשה מרחיבה את משטח התקיפה הכולל.

RBAC: העיקרון של הרשאה מינימלית

Role-Based Access Control ב-Kubernetes שולט מי (משתמש, ServiceAccount, group) יכול לבצע אילו פעולות (get, list, create, delete) על אילו משאבים. הטעות הכי נפוצה היא הענקת ClusterRoleBindings רחבים - הרשאות שתקפות בכל ה-cluster - כשבפועל מספיקה הרשאה מוגבלת ל-namespace בודד. כל ServiceAccount שpod משתמש בו צריך לקבל בדיוק את ההרשאות שהוא זקוק להן ולא יותר, ואם pod לא צריך לגשת בכלל ל-API Server, הוא צריך לקבל ServiceAccount עם automountServiceAccountToken מוגדר כ-false, כדי שאפילו לא יהיה לו טוקן שאפשר לגנוב אם הקונטיינר נפרץ.

ביקורת RBAC תקופתית היא הכרחית - הרשאות מצטברות עם הזמן כשמפתחים מוסיפים 'עוד קצת גישה' כדי לפתור בעיה נקודתית, ואף אחד לא חוזר לצמצם אותן אחר כך. כלים כמו kubectl-who-can או rbac-lookup עוזרים למפות מי בפועל יכול לגשת למה, ולזהות הרשאות שלא בשימוש.

Pod Security: מה מותר לקונטיינר לעשות

Pod Security Standards מגדירות שלוש רמות אכיפה - Privileged, Baseline, Restricted. ברוב הסביבות בפרודקשן, הרמה הרצויה היא Restricted: הקונטיינר לא יכול לרוץ כ-root (runAsNonRoot: true), אין לו גישה ל-hostNetwork, hostPID או hostIPC, ה-filesystem הראשי הוא read-only (readOnlyRootFilesystem), וה-Linux capabilities שהוא יכול להשתמש בהן מוגבלות למינימום ההכרחי בלבד (drop: ALL ואז הוספה סלקטיבית רק של מה שבאמת נדרש). הטעות הנפוצה היא לבנות אימג' שדורש הרשאות root 'כי זה עבד ככה בפיתוח' ולא לחזור לבדוק אם אפשר להריץ אותו כ-non-root user - רוב האימג'ים המודרניים תומכים בזה עם קצת תשומת לב בזמן בנייה.

securityContext:
  runAsNonRoot: true
  runAsUser: 1000
  readOnlyRootFilesystem: true
  allowPrivilegeEscalation: false
  capabilities:
    drop: ["ALL"]

ניהול Secrets: מעבר לפתרון המובנה

Kubernetes Secrets המובנים נשמרים ב-etcd, ומאז גרסאות מסוימות מוצפנים במנוחה (encryption at rest) אם הוגדר במפורש - אבל ברירת המחדל בהתקנות רבות היא ללא הצפנה, מה שאומר שגישה ל-etcd חושפת את כל ה-Secrets בטקסט גלוי. גם עם הצפנה, Secret שמוצג כ-environment variable בתוך pod נגיש בקלות דרך kubectl exec או דרך תהליך שקורא /proc, וגם עלול להישאר בלוגים בטעות אם קוד האפליקציה מדפיס משתני סביבה בזמן דיבוג. בסביבות רגישות, הפתרון העדיף הוא אינטגרציה עם מחסן secrets חיצוני ייעודי כמו HashiCorp Vault או AWS Secrets Manager, עם injection דינמי בזמן ריצה דרך sidecar (כמו Vault Agent Injector) ולא באמצעות ה-Secret object הבסיסי של Kubernetes.

Network Policies כשכבת הגנה נגד תנועה רוחבית

גם אם pod נפרץ, Network Policy מוגדרת היטב מגבילה את יכולת התוקף לנוע רוחבית (lateral movement) לpods אחרים ב-cluster. העיקרון: default-deny מוחלט (חסימת כל תעבורה) עם allow-list מפורש לכל תקשורת שבאמת נדרשת. תרגול נפוץ בפרודקשן בוגר הוא לאכוף גם egress policies, לא רק ingress - להגביל לא רק מי יכול לגשת ל-pod, אלא גם לאן ה-pod עצמו יכול לפנות. זה קריטי במיוחד למניעת exfiltration - קונטיינר שנפרץ ומנסה לשלוח נתונים גנובים החוצה לשרת חיצוני, ייחסם אם ה-egress policy לא מאפשרת תעבורה יוצאת לכתובות לא מוכרות.

אבטחת שרשרת האספקה: מהאימג' ועד ה-deployment

אבטחת Kubernetes לא מתחילה ברגע שה-pod רץ - היא מתחילה בבניית האימג'. סריקת חולשות (vulnerability scanning) עם כלים כמו Trivy או Grype צריכה להיות חלק אינטגרלי מ-CI pipeline, שחוסם build שמכיל חולשות ברמת חומרה גבוהה. חתימה דיגיטלית על אימג'ים (עם Cosign, חלק מפרויקט Sigstore) מבטיחה שרק אימג'ים שעברו את התהליך המאושר יכולים לרוץ ב-cluster, ואוכפים זאת דרך admission controller שדוחה כל אימג' לא חתום. יצירת SBOM (Software Bill of Materials) לכל build מספקת שקיפות מלאה על כל תלות שנמצאת באימג', חיונית לתגובה מהירה כשמתגלה חולשה חדשה בספריה נפוצה - במקום לחפש ידנית אילו שירותים משתמשים בה, שאילתה על ה-SBOM נותנת תשובה מיידית.

Admission Controllers: אכיפת מדיניות בזמן אמת

OPA Gatekeeper ו-Kyverno הם שני הכלים המובילים לאכיפת מדיניות דרך Admission Webhooks - כל בקשה ליצור או לעדכן משאב ב-cluster עוברת דרכם לפני שהיא מתקבלת. מדיניות טיפוסית כוללת: חסימת pods שמנסים לרוץ כ-root, דרישה שלכל container יהיו resource limits מוגדרים, אכיפת תיוג חובה למעקב עלויות, וחסימת אימג'ים שלא מגיעים ממאגר מאושר. היתרון המרכזי על פני בדיקה ידנית (code review) הוא שהאכיפה קורית ברמת ה-cluster עצמו ולא ניתנת לעקיפה - גם אם מישהו מנסה להחיל YAML ישירות דרך kubectl בלי לעבור דרך pipeline, ה-admission controller עדיין יחסום הפרת מדיניות.

Runtime Security: לתפוס תקיפה שכבר בפנים

כל השכבות שתוארו עד כה עוסקות במניעה, אבל צריך גם יכולת זיהוי בזמן אמת למקרה שמשהו כבר עבר. כלים כמו Falco עוקבים אחרי קריאות מערכת (syscalls) ברמת kernel ומתריעים על התנהגות חריגה - קונטיינר שפתאום מנסה לפתוח shell אינטראקטיבי, לקרוא קבצי הגדרות רגישים, או ליצור חיבור רשת יוצא לכתובת לא מוכרת. זו שכבת ההגנה שתופסת בדיוק את המקרים שבהם כל שאר השכבות נכשלו - חולשה לא ידועה (zero-day) שנוצלה, או טעות אנוש שהחליקה דרך ה-admission controller.

Audit Logging: לדעת מה קרה אחרי שזה קרה

Kubernetes Audit Logs מתעדים כל בקשה ל-API Server - מי ביקש מה, מתי, ומה התוצאה. בלי audit logging מופעל ומוגדר נכון, אחרי incident אבטחה אין דרך לדעת בוודאות מה בדיוק קרה, מי ניגש למה, ואיך התוקף הגיע לאן שהגיע. חשוב להגדיר את רמת הפירוט הנכונה - יותר מדי לוגים יוצרים עומס אחסון ורעש שקשה לנתח, פחות מדי משאיר חורים בחקירה. מומלץ לשלוח audit logs למערכת SIEM חיצונית, לא רק לשמור אותם מקומית ב-cluster - אם התוקף השיג גישה מלאה ל-cluster, הוא עלול למחוק גם את הלוגים המקומיים.

Multi-Tenancy ואבטחה: כשה-cluster משותף בין דיירים

כשה-cluster משמש לריבוי דיירים - צוותים פנימיים או לקוחות חיצוניים - כל השכבות שתוארו למעלה מקבלות משנה חשיבות (למאמר מורחב על הנושא ראו Multi-Tenancy ב-Kubernetes). ההנחה שדייר אחד לא ינסה לגשת למשאבים של דייר אחר היא הנחה מסוכנת גם בסביבות פנים-ארגוניות, וקל וחומר בסביבות עם לקוחות חיצוניים. שילוב של RBAC מוגבל ל-namespace, Network Policies עם default-deny בין namespaces, ו-ResourceQuota שמונע ניצול יתר - הוא המינימום ההכרחי, לא תוספת אופציונלית.

אימות רב-שכבתי: מעבר לסיסמה בודדת

גישה ל-API Server עצמו צריכה להיות מוגנת מעבר להרשאות RBAC בלבד. אינטגרציה עם ספק זהות ארגוני (OIDC דרך Okta, Azure AD או Google Identity) מאפשרת ניהול מרכזי של גישה, כולל אכיפת MFA וניתוק אוטומטי כשעובד עוזב את הארגון - יתרון עצום לעומת ניהול קרדנציאלס נפרדים לכל cluster. חשוב גם להגביל את הגישה הישירה ל-API Server ברמת הרשת - שימוש ב-private endpoint שנגיש רק דרך VPN או Bastion host, ולא חשיפה ישירה לאינטרנט הציבורי, מצמצם משמעותית את משטח התקיפה החיצוני. תקיפות רבות על clusters מתחילות בדיוק שם - API Server שנחשף בטעות לאינטרנט הפתוח עם הרשאות ברירת מחדל חלשות מדי.

אבטחת CI/CD כחלק בלתי נפרד מאבטחת ה-cluster

לעיתים קרובות נקודת הכניסה הקלה ביותר לתקיפת cluster היא לא ה-cluster עצמו אלא צינור ה-CI/CD שמפרסם אליו. מערכת CI/CD עם הרשאות rw מלאות ל-cluster היא יעד מפתה - תוקף שמשיג גישה ל-pipeline (למשל דרך dependency זדוני או token שדלף) יכול לפרסם ישירות ל-production בלי לגעת כלל באבטחת ה-cluster עצמו. הפרדת הרשאות בין סביבות (dev, staging, production), שימוש ב-short-lived credentials במקום טוקנים קבועים, ואימוץ מודל GitOps שבו שינויים ל-cluster קורים רק דרך Pull Request מאושר ומתועד - כל אלה מצמצמים משמעותית את משטח התקיפה הזה. הקשר בין אבטחת שרשרת האספקה שתוארה למעלה לבין אבטחת ה-CI/CD הוא הדוק: שניהם עוסקים בשאלה מי בפועל יכול לגרום לקוד לרוץ בקלאסטר, ולא רק מה מותר לקוד לעשות ברגע שהוא כבר שם. עוד עיקרון מעשי שכדאי לאמץ: כל שינוי ב-cluster - בין אם דרך Terraform, Helm או kubectl ישיר - צריך להשאיר עקבות ברורות שמאפשרים לשחזר בדיוק מי אישר אותו ומתי, כדי שגם כשמשהו משתבש, זמן החקירה יימדד בדקות ולא בימים.

גישה הוליסטית: מדוע אף שכבה בודדת לא מספיקה

הדוגמה שפתחה את המאמר ממחישה בדיוק את זה - כל בעיה בודדת נראתה נסבלת, אבל השרשרת המלאה הייתה קטלנית. אבטחת Kubernetes בוגרת דורשת חשיבה בכל השכבות בבת אחת: RBAC מינימלי, Pod Security מחמיר, Secrets מחוץ ל-etcd הבסיסי, Network Policies עם default-deny, שרשרת אספקה מאובטחת עם חתימה וסריקה, אכיפה אוטומטית דרך admission controllers, ניטור runtime, ואודיט מלא. במדיה דיל אנחנו ממליצים תמיד להתחיל ממיפוי משטח התקיפה המלא של ה-cluster הקיים, ולתעדף שכבות לפי הסיכון האמיתי - לא לפי מה שקל ליישם ראשון.

שווה גם לזכור שאבטחה ב-Kubernetes היא תהליך מתמשך, לא פרויקט חד-פעמי. חולשות חדשות מתגלות כל הזמן בתלויות נפוצות, וה-cluster עצמו משתנה - namespaces חדשים נוצרים, הרשאות מצטברות, אימג'ים מתעדכנים. סבב ביקורת תקופתי (רבעוני לפחות) שבודק מחדש RBAC, Network Policies וסריקת חולשות הוא מה שמבדיל בין ארגון שבאמת מאובטח לבין ארגון שהיה מאובטח ביום ההשקה בלבד.

תגיות: Kubernetes Security · RBAC · Pod Security Standards · Network Policy · Falco · OPA Gatekeeper · Secrets Management · Supply Chain Security

← חזרה לבלוג · צור קשר