בדף הזה מוסבר איך לאשר פעולות במשאבים באשכולות של Google Kubernetes Engine (GKE) באמצעות מנגנון בקרת הגישה המובנה שמבוסס על תפקידים (RBAC) ב-Kubernetes. Kubernetes RBAC מופעל כברירת מחדל, ומאפשר לכם שליטה מפורטת בגישה לאשכול.
תלמדו איך להגדיר ולהקצות הרשאות מדויקות, ליצור תפקידים וקישורי תפקידים כדי לנהל את הגישה של המשתמשים, לאמת את הגישה ל-API כדי לבדוק את רמת הגישה, לפתור בעיות נפוצות ולהבין את המגבלות כשעובדים עם RBAC ב-GKE.
הדף הזה מיועד למומחי אבטחה ולמפעילים שרוצים להשתמש ב-RBAC כדי לשפר את האבטחה באשכולות GKE. למידע נוסף על תפקידים נפוצים ומשימות לדוגמה שאנחנו מתייחסים אליהם בתוכן של Google Cloud , קראו את המאמר תפקידים ומשימות נפוצים של משתמשי GKE.
לפני שקוראים את הדף הזה, חשוב להכיר את המושגים הבאים:
- סקירה כללית על RBAC ב-Kubernetes
- שיטות מומלצות ל-RBAC ב-GKE, כדי לשפר את התכנון של כללי מדיניות ה-RBAC.
לפני שמתחילים
לפני שמתחילים, חשוב לוודא שביצעתם את המשימות הבאות:
- מפעילים את Google Kubernetes Engine API. הפעלת Google Kubernetes Engine API
- כדי להשתמש ב-Google Cloud CLI למשימה הזו, מתקינים ואז מאתחלים את ה-CLI של gcloud. אם כבר התקנתם את ה-CLI של gcloud, הריצו את הפקודה
gcloud components updateכדי לקבל את הגרסה העדכנית. יכול להיות שבגרסאות קודמות של ה-CLI של gcloud אי אפשר להריץ את הפקודות שבמסמך הזה.
אינטראקציה עם ניהול זהויות והרשאות גישה (IAM)
כדי לשלוט בגישה לאשכול GKE, אתם יכולים להשתמש גם בניהול זהויות והרשאות גישה (IAM) וגם ב-Kubernetes RBAC:
IAM לא ספציפי ל-Kubernetes. הוא מספק ניהול זהויות לכמה מוצרים של Google Cloud , ופועל בעיקר ברמת הפרויקט ב- Google Cloud .
RBAC ב-Kubernetes הוא רכיב ליבה של Kubernetes, שמאפשר ליצור ולהקצות תפקידים (קבוצות של הרשאות) לכל אובייקט או סוג אובייקט בתוך האשכול.
כדי לאשר פעולה, GKE בודק קודם אם יש מדיניות RBAC. אם אין מדיניות RBAC, GKE בודק את הרשאות ה-IAM.
ב-GKE, מערכת IAM ו-Kubernetes RBAC משולבים כדי לאשר למשתמשים לבצע פעולות אם יש להם הרשאות מספיקות לפי אחד מהכלים. זהו חלק חשוב באתחול של אשכול GKE, כי כברירת מחדל למשתמשי Google Cloud אין קישורי תפקידים (RoleBindings) של RBAC ב-Kubernetes.
כדי לתת הרשאה למשתמשים באמצעות חשבונות Google Cloud , קודם צריך להגדיר את הלקוח בצורה נכונה לאימות באמצעות החשבונות האלה. לדוגמה, אם אתם משתמשים ב-kubectl, אתם צריכים להגדיר את הפקודה kubectl לאימות ב- Google Cloud לפני שתריצו פקודות שדורשות הרשאה.
כמעט בכל המקרים, אפשר להשתמש ב-Kubernetes RBAC במקום ב-IAM.
משתמשי GKE צריכים לפחות את הרשאת ה-IAM container.clusters.get בפרויקט שמכיל את האשכול.
ההרשאה הזו כלולה בתפקיד container.clusterViewer ובתפקידים אחרים עם הרשאות ברמה גבוהה יותר. ההרשאה container.clusters.get נדרשת למשתמשים כדי לאמת את האשכולות בפרויקט, אבל לא מאשרת להם לבצע פעולות בתוך האשכולות האלה. לאחר מכן, אפשר לספק הרשאה באמצעות IAM או Kubernetes RBAC.
הגדרה והקצאה של הרשאות
אפשר להגדיר כללי RBAC באובייקטים ClusterRole ו-Role, ואז להקצות את הכללים האלה לאובייקטים ClusterRoleBinding ו-RoleBinding באופן הבא:
- ClusterRole: קיבוץ של משאבים ופעולות מותרות ברמת האשכול, שאפשר להקצות למשתמש או לקבוצה באמצעות
RoleBindingאוClusterRoleBinding. - תפקיד: קבוצה של משאבים ופעולות מותרות במרחב שמות, שאפשר להקצות למשתמש או לקבוצת משתמשים באמצעות
RoleBinding. - ClusterRoleBinding: הקצאת
ClusterRoleלמשתמש או לקבוצה לכל מרחבי השמות באשכול. - RoleBinding: הקצאת
RoleאוClusterRoleלמשתמש או לקבוצה במרחב שמות ספציפי.
כשמשתמשים ב-RoleBinding כדי להקצות ClusterRole למשתמש או לקבוצה, המשתמשים והקבוצות האלה יכולים לגשת רק למשאבים במרחב השמות שציינתם ב-RoleBinding. אם רוצים שהמשתמשים או הקבוצות יוכלו לגשת למשאבים בכל מרחבי השמות, צריך להשתמש ב-ClusterRoleBinding.
הגדרת הרשאות באמצעות Roles או ClusterRoles
אתם מגדירים הרשאות בתוך אובייקט Role או ClusterRole. תפקיד מגדיר גישה למשאבים במרחב שמות אחד, ואילו ClusterRole מגדיר גישה למשאבים בכל האשכול.
התחביר של Roles ו-ClusterRoles זהה. לכל אחד מהם יש קטע rules, שבו מגדירים את המשאבים שהכלל חל עליהם ואת הפעולות שמותר לבצע בתפקיד. לדוגמה, התפקיד הבא מעניק גישת קריאה (get, watch ו-list) לכל ה-Pods במרחב השמות accounting:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: accounting
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
הרשימה המלאה של השדות המותרים מופיעה במאמרי העזרה של ה-API בנושא Role ו-ClusterRole.
Role לעומת ClusterRole
מכיוון שההרשאות שניתנות על ידי ClusterRole חלות על כל האשכול, אפשר להשתמש ב-ClusterRoles כדי לשלוט בגישה לסוגים שונים של משאבים, בניגוד ל-Roles. למשל:
- משאבים בהיקף אשכול, כמו צמתים
- נקודות קצה (endpoints) של REST שאינן משאבים, כמו
/healthz - משאבים עם מרחב שמות בכל מרחבי השמות (לדוגמה, כל ה-Pods בכל האשכול, בלי קשר למרחב השמות)
הקצאת תפקידים באמצעות RoleBindings או ClusterRoleBindings
אחרי שיוצרים Role או ClusterRole, מקצים אותו למשתמש או לקבוצת משתמשים על ידי יצירת RoleBinding או ClusterRoleBinding. משתמשים וקבוצות נקראים subjects, ויכולים להיות כל אחד מהבאים:
| סוג הנושא | הערך של kind |
הערך של name |
|---|---|---|
| Google Cloud חשבון משתמש | User |
כתובת האימייל הרשומה שלGoogle Cloud |
| חשבון שירות ב-Kubernetes | ServiceAccount |
השם של אובייקט Kubernetes ServiceAccount באשכול |
| חשבון שירות ב-IAM | User |
כתובת אימייל של חשבון שירות ב-IAM שנוצרה באופן אוטומטי |
| כתובת של קבוצה ב-Google בדומיין מאומת | Group |
כתובת האימייל של קבוצה ב-Google Workspace שחברה בקבוצה gke-security-groups. הוראות להגדרת קבוצות Google ל-RBAC מפורטות במאמר הגדרת קבוצות Google ל-RBAC. |
ה-RoleBinding הבא מקצה את התפקיד pod-reader למשתמש, לחשבון שירות של Kubernetes, לחשבון שירות של IAM ולקבוצה ב-Google:
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pod-reader-binding
namespace: accounting
subjects:
# Google Cloud user account
- kind: User
name: janedoe@example.com
# Kubernetes service account
- kind: ServiceAccount
name: johndoe
# IAM service account
- kind: User
name: test-account@test-project.iam.gserviceaccount.com
# Google Group
- kind: Group
name: accounting-group@example.com
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
אימות הגישה ל-API באמצעות kubectl
kubectl מספק את פקודת המשנה auth can-i כדי לשלוח במהירות שאילתות לשכבת ההרשאות של ה-API. כאדמינים בפלטפורמה, יכול להיות שתצטרכו להתחזות למשתמשים כדי לקבוע אילו פעולות הם יכולים לבצע. אפשר להשתמש ב-auth can-i ולהעביר דגל --as נוסף.
כשמריצים את הפקודה kubectl auth can-i בלי הדגל --as, ניהול הזהויות והרשאות הגישה (IAM) מבצע את ההרשאה. לעומת זאת, כשמוסיפים את הדגל --as, האימות מתבצע באמצעות RBAC ב-Kubernetes. לכן, תצטרכו ליצור את האובייקטים הנדרשים של Role ו-RoleBinding בשביל RBAC.
מידע נוסף זמין במאמר אימות הגישה ל-API.
שימוש ב-API ודוגמאות
כדי לקבל מידע מלא על השימוש ב-Kubernetes API ליצירת האובייקטים הנדרשים של Role, ClusterRole, RoleBinding ו-ClusterRoleBinding בשביל RBAC, קראו את המאמר שימוש בהרשאה של בקרת גישה מבוססת-תפקידים במסמכי התיעוד של Kubernetes.
פתרון בעיות ב-RBAC
כדי לנפות באגים בבעיות שקשורות ל-RBAC, אפשר להשתמש ביומן הביקורת של פעילות האדמין, שמופעל כברירת מחדל בכל האשכולות. אם הגישה למשאב או לפעולה נדחית בגלל שאין מספיק הרשאות, שרת ה-API מתעד שגיאת RBAC DENY ביומן, יחד עם מידע נוסף כמו החברות המשתמעת והמפורשת של המשתמש בקבוצה. אם אתם משתמשים בקבוצות Google בשביל RBAC, הערך google groups מופיע בהודעת היומן.
מגבלות
בקטעים הבאים מתוארות אינטראקציות שאולי לא נראות ברורות כשעובדים עם Kubernetes RBAC ו-IAM.
תפקידי ברירת המחדל של Discovery
אשכולות נוצרים עם קבוצה של ClusterRoles ו-ClusterRoleBindings שמוגדרים כברירת מחדל.
בקשות שבוצעו עם פרטי כניסה תקינים ממוקמות בקבוצה system:authenticated, וכל שאר הבקשות ממוקמות בקבוצה system:unauthenticated.
ה-ClusterRole system:basic-user מאפשר למשתמשים ליצור SelfSubjectAccessReviews כדי לבדוק את ההרשאות שלהם באשכול. התפקיד system:discovery מאפשר למשתמשים לקרוא ממשקי API של גילוי, שיכולים לחשוף מידע על CustomResourceDefinitions שנוספו לאשכול.
במקום זאת, משתמשים לא רשומים (system:unauthenticated) מקבלים את ClusterRole system:public-info-viewer, שמעניק הרשאת קריאה בלבד לממשקי ה-API /healthz ו-/version.
כדי לראות את נקודות הקצה ל-API שמותרות על ידי ClusterRole של system:discovery, מריצים את הפקודה הבאה:
kubectl get clusterroles system:discovery -o yaml
שגיאת Forbidden בחשבונות שירות במכונות וירטואליות של Google Cloud
השגיאה הבאה יכולה להתרחש כשבמכונה הווירטואלית אין את ההיקף userinfo-email:
Error from server (Forbidden): error when creating ... "role-name" is forbidden: attempt to grant extra privileges:...
לדוגמה, נניח שלמכונה הווירטואלית יש את ההיקף cloud-platform אבל אין לה את ההיקף userinfo-email. כשהמכונה הווירטואלית מקבלת אסימון גישה, Google Cloudמשייך את האסימון הזה להיקף ההרשאות של cloud-platform. כששרת ה-API של Kubernetes מבקש מ- Google Cloud את הזהות שמשויכת לאסימון הגישה, הוא מקבל את המזהה הייחודי של חשבון השירות ולא את כתובת האימייל של חשבון השירות.
כדי לבצע אימות בהצלחה, צריך ליצור מכונה וירטואלית חדשה עם ההיקף userinfo-email או ליצור קישור תפקיד חדש שמשתמש במזהה הייחודי.
כדי ליצור מכונה וירטואלית חדשה עם ההיקף userinfo-email, מריצים את הפקודה הבאה:
gcloud compute instances create INSTANCE_NAME \
--service-account SERVICE_ACCOUNT_EMAIL \
--scopes userinfo-email
כדי ליצור קישור תפקיד חדש שמשתמש במזהה הייחודי של חשבון השירות למכונה וירטואלית קיימת, מבצעים את הפעולות הבאות:
מזהים את המזהה הייחודי של חשבון השירות:
gcloud iam service-accounts describe SERVICE_ACCOUNT_EMAILלדוגמה, הפלט הבא מציג את
uniqueIdשל חשבון השירותmy-iam-account@somedomain.com:displayName: Some Domain IAM service account email: my-iam-account@somedomain.com etag: BwWWja0YfJA name: projects/project-name/serviceAccounts/my-iam-account@somedomain.com oauth2ClientId: '123456789012345678901' projectId: project-name uniqueId: '123456789012345678901'יוצרים קישור תפקיד באמצעות ה-
uniqueIdשל חשבון השירות:kubectl create clusterrolebinding CLUSTERROLEBINDING_NAME \ --clusterrole cluster-admin \ --user UNIQUE_ID
הרשאה ליצור או לעדכן תפקידים וקישורי תפקידים
ב-Kubernetes, אפשר ליצור או לעדכן תפקיד או קישור תפקיד עם הרשאות ספציפיות רק אם עומדים בתנאים הבאים:
- יצירה או עדכון של תפקיד: אתם צריכים שיהיו לכם את אותן ההרשאות שאתם רוצים לתת לתפקיד. לחלופין, צריכה להיות לכם הרשאה לבצע את הפעולה
escalateבתפקיד. - יצירה או עדכון של קישור בין תפקידים: אתם צריכים שיהיו לכם את אותן ההרשאות שניתנות בתפקיד המקושר, באותו היקף של הקישור בין התפקידים. לחלופין, צריכה להיות לכם הרשאה לבצע את הפעולה
bindבתפקיד שאליו מתייחסים.
אם ההרשאות שאתם מקצים בתפקיד הוקצו לכם במקור באמצעות מדיניות הרשאה של IAM במקום RBAC, יכול להיות שהבקשה שלכם לתפקיד או לקישור תפקיד תיכשל. לדוגמה, נניח שמשתמש עם ההרשאות container.pods.* ו-container.roles.create ב-IAM שלח את הבקשה הבאה ליצירת תפקיד:
kubectl create role allowed-to-view-pods --resource pods --verb list,get
אם למשתמש ניתנו רק הרשאות באמצעות IAM, יכול להיות שתופיע השגיאה הבאה:
Error from server (Forbidden): clusterroles.rbac.authorization.k8s.io "allowed-to-view-pods" is forbidden:
user "caller@example.com" (groups=["system:authenticated"]) is attempting to grant RBAC permissions not currently held:
{APIGroups:[""], Resources:["pods"], Verbs:["list" "get"]}
כדי לעקוף את המגבלה הזו, אתם יכולים להשתמש ב-RBAC במקום ב-IAM כדי לתת למבצע הקריאה את ההרשאות שבתפקיד.
לחלופין, אפשר להשתמש ב-RBAC או ב-IAM כדי להעניק למבצע הקריאה את הפועל escalate, את הפועל bind או את שניהם. עם זאת, ב-GKE לא מומלץ להשתמש בגישה הזו, כי הגורם שמבצע את הקריאה יכול להעניק כל הרשאה לכל תפקיד.
המאמרים הבאים
- איך מגדירים קבוצות Google ל-RBAC
- איך יוצרים כללי מדיניות הרשאות ב-IAM
- מידע נוסף על בקרת גישה
- מידע נוסף על שיטות מומלצות ל-RBAC ב-GKE
- איך מבצעים אימות בשרת ה-API של Kubernetes