בדף הזה מוסבר איך לאשר פעולות במשאבים באשכולות Google Kubernetes Engine (GKE) באמצעות מנגנון בקרת הגישה מבוססת-תפקידים (RBAC) המובנה ב-Kubernetes. מערכת Kubernetes RBAC מופעלת כברירת מחדל, ומאפשרת לכם שליטה פרטנית בגישה לאשכול.
תלמדו איך להגדיר ולהקצות הרשאות מדויקות, ליצור תפקידים וקשרי תפקידים כדי לנהל את גישת המשתמשים, לאמת את הגישה ל-API כדי לבדוק את רמת הגישה, לפתור בעיות נפוצות ולהבין את המגבלות כשעובדים עם RBAC ב-GKE.
הדף הזה מיועד למומחי אבטחה ולמפעילים שרוצים להשתמש ב-RBAC כדי לשפר את האבטחה באשכולות GKE שלהם. כדי לקבל מידע נוסף על תפקידים נפוצים ועל משימות לדוגמה שאנחנו מתייחסים אליהן ב Google Cloud תוכן, אפשר לעיין במאמר תפקידים נפוצים של משתמשי GKE ומשימות.
לפני שקוראים את הדף הזה, חשוב לוודא שמכירים את המושגים הבאים:
- סקירה כללית של RBAC ב-Kubernetes
- שיטות מומלצות ל-GKE RBAC לקבלת הנחיות לשיפור העיצוב של מדיניות RBAC.
לפני שמתחילים
לפני שמתחילים, חשוב לוודא שביצעתם את הפעולות הבאות:
- מפעילים את ממשק Google Kubernetes Engine API. הפעלת Google Kubernetes Engine API
- אם רוצים להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז להפעיל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה
gcloud components updateכדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
אינטראקציה עם ניהול זהויות והרשאות גישה (IAM)
אתם יכולים להשתמש גם בניהול זהויות והרשאות גישה (IAM) וגם ב-Kubernetes RBAC כדי לשלוט בגישה לאשכול GKE:
IAM לא ספציפי ל-Kubernetes, הוא מספק ניהול זהויות למספר מוצרים של Google Cloud , והוא פועל בעיקר ברמת הפרויקט של Google Cloud .
RBAC ב-Kubernetes הוא רכיב ליבה של Kubernetes שמאפשר ליצור תפקידים (קבוצות של הרשאות) ולהעניק אותם לכל אובייקט או סוג של אובייקט באשכול.
כדי לאשר פעולה, מערכת GKE בודקת קודם אם יש מדיניות RBAC. אם אין מדיניות RBAC, GKE בודק את הרשאות ה-IAM.
ב-GKE, מערכות IAM ו-Kubernetes RBAC משולבות כדי לאשר למשתמשים לבצע פעולות אם יש להם הרשאות מספיקות לפי אחד מהכלים. זהו חלק חשוב בהפעלה הראשונית של אשכול GKE, כי כברירת מחדל למשתמשים אין RoleBindings של Kubernetes RBAC. Google Cloud
כדי לאשר למשתמשים גישה באמצעות חשבונות 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.
הגדרת הרשאות באמצעות תפקידים או תפקידים באשכול
אתם מגדירים הרשאות באובייקט Role או ClusterRole. תפקיד מגדיר גישה למשאבים במרחב שמות יחיד, ותפקיד ברמת האשכול מגדיר גישה למשאבים באשכול כולו.
ל-Roles ול-ClusterRoles יש תחביר זהה. לכל כלל יש קטע rules שבו מגדירים את המשאבים שהכלל חל עליהם ואת הפעולות שמותרות לתפקיד. לדוגמה, התפקיד הבא מעניק גישת קריאה (get, watch ו-list) לכל הפודים במרחב השמות 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 חלות על כל האשכול, ולכן אפשר להשתמש ב-ClusterRole כדי לשלוט בגישה לסוגים שונים של משאבים, שלא ניתן לשלוט בהם באמצעות Roles. למשל:
- משאבים בהיקף אשכול, כמו צמתים
- נקודות קצה של 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, משתמשים ביומן הביקורת Admin activity, שמופעל בכל האשכולות כברירת מחדל. אם הגישה למשאב או לפעולה נדחית בגלל חוסר הרשאות מספיקות, שרת ה-API מתעד שגיאה RBAC DENY, יחד עם מידע נוסף כמו חברי קבוצה של המשתמש באופן מרומז וגלוי. אם אתם משתמשים בקבוצות Google ל-RBAC, google groups
מופיע בהודעת היומן.
מגבלות
בקטעים הבאים מתוארות אינטראקציות שאולי לא ברורות כשעובדים עם RBAC ב-Kubernetes ועם IAM.
תפקידי ברירת המחדל של Discovery
אשכולות נוצרים עם קבוצה של תפקידים באשכולות וקישורי ClusterRole שמוגדרים כברירת מחדל.
בקשות שמתבצעות עם פרטי כניסה תקינים ממוקמות בקבוצה system:authenticated, ואילו כל הבקשות האחרות ממוקמות בקבוצה system:unauthenticated.
ה-ClusterRole system:basic-user מאפשר למשתמשים לבצע SelfSubjectAccessReviews כדי לבדוק את ההרשאות שלהם באשכול. system:discovery התפקיד מאפשר למשתמשים לקרוא ממשקי API של גילוי, שיכולים לחשוף מידע על CustomResourceDefinitions שנוספו לאשכול.
משתמשים אנונימיים (system:unauthenticated) מקבלים במקום זאת את system:public-info-viewer ClusterRole, שמעניק גישת קריאה בלבד לממשקי 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 או ליצור קשר חדש בין תפקיד למשתמש שמשתמש במזהה הייחודי.
כדי ליצור מכונת VM חדשה עם היקף userinfo-email, מריצים את הפקודה הבאה:
gcloud compute instances create INSTANCE_NAME \
--service-account SERVICE_ACCOUNT_EMAIL \
--scopes userinfo-email
כדי ליצור קישור תפקיד חדש שמשתמש במזהה הייחודי של חשבון השירות עבור מכונת VM קיימת, מבצעים את השלבים הבאים:
מזהים את המזהה הייחודי של חשבון השירות:
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
- מידע נוסף על בקרת גישה
- מידע נוסף על שיטות מומלצות ל-GKE RBAC
- איך מאמתים את השרת של Kubernetes API