בדף הזה נסביר איך לכתוב תבנית אילוץ בהתאמה אישית ולהשתמש בה כדי להרחיב את Policy Controller אם לא מצאתם תבנית אילוץ מוכנה מראש שמתאימה לצרכים שלכם.
הדף הזה מיועד לאדמינים ולמפעילים בתחום ה-IT שרוצים לוודא שכל המשאבים שפועלים בפלטפורמת הענן עומדים בדרישות התאימות של הארגון. כדי לעשות את זה, הם יכולים לספק ולתחזק אוטומציה לביקורת או לאכיפה, ולהשתמש בתבניות של הגדרות הצהרתיות. כדי לקבל מידע נוסף על תפקידים נפוצים ועל משימות לדוגמה שאנחנו מתייחסים אליהן ב Google Cloud תוכן, אפשר לעיין במאמר תפקידים נפוצים של משתמשי GKE ומשימות.
כללי המדיניות של Policy Controller מתוארים באמצעות OPA Constraint Framework ונכתבים ב-Rego. מדיניות יכולה להעריך כל שדה של אובייקט Kubernetes.
כתיבת כללי מדיניות באמצעות Rego היא מיומנות מיוחדת. לכן, כברירת מחדל מותקנת ספרייה של תבניות אילוצים נפוצות. סביר להניח שאפשר להפעיל את תבניות האילוצים האלה כשיוצרים אילוצים. אם יש לכם צרכים מיוחדים, אתם יכולים ליצור תבניות אילוצים משלכם.
תבניות אילוצים מאפשרות להפריד את הלוגיקה של מדיניות מהדרישות הספציפיות שלה, כדי לעשות בהן שימוש חוזר ולהעביר אותן. אפשר ליצור אילוצים באמצעות תבניות אילוצים שפותחו על ידי צדדים שלישיים, כמו פרויקטים של קוד פתוח, ספקי תוכנה או מומחים בתחום הרגולציה.
לפני שמתחילים
- מתקינים את Policy Controller.
דוגמה לתבנית אילוצים
בהמשך מופיעה דוגמה לתבנית אילוצים שמונעת גישה לכל המשאבים שהשם שלהם תואם לערך שסופק על ידי יוצר האילוץ. בהמשך הדף מוסבר על התוכן של התבנית, ומוצגים מושגים חשובים.
אם אתם משתמשים ב-סנכרון תצורות עם מאגר היררכי, מומלץ ליצור את האילוצים בספרייה cluster/.
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8sdenyname
spec:
crd:
spec:
names:
kind: K8sDenyName
validation:
# Schema for the `parameters` field
openAPIV3Schema:
properties:
invalidName:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8sdenynames
violation[{"msg": msg}] {
input.review.object.metadata.name == input.parameters.invalidName
msg := sprintf("The name %v is not allowed", [input.parameters.invalidName])
}
מגבלה לדוגמה
הדוגמה הבאה היא אילוץ שאפשר להטמיע כדי לדחות את כל המשאבים שנקראים policy-violation:
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sDenyName
metadata:
name: no-policy-violation
spec:
parameters:
invalidName: "policy-violation"
החלקים של תבנית אילוצים
תבניות של אילוצים מורכבות משני חלקים חשובים:
הסכימה של האילוץ שרוצים שהמשתמשים ייצרו. הסכימה של תבנית אילוצים מאוחסנת בשדה
crd.קוד המקור של Rego שמופעל כשמתבצעת הערכה של האילוץ. קוד המקור של Rego לתבנית מאוחסן בשדה
targets.
סכימה (שדה crd)
שדה ה-CRD הוא תוכנית ליצירת Kubernetes Custom Resource Definition שמגדיר את משאב האילוץ עבור שרת ה-API של Kubernetes. צריך למלא רק את השדות הבאים.
| שדה | תיאור |
|---|---|
spec.crd.spec.names.kind |
סוג האילוץ. כשממירים לאותיות קטנות, הערך בשדה הזה צריך להיות שווה ל-metadata.name. |
spec.crd.spec.validation.openAPIV3Schema |
הסכימה של השדה |
הוספת הקידומת K8s לתבנית האילוצים היא מוסכמה שמאפשרת לכם להימנע מהתנגשויות עם סוגים אחרים של תבניות אילוצים, כמו תבניות Forseti שמטרגטות משאביK8s. Google Cloud
קוד מקור של Rego (שדה targets)
בקטעים הבאים מפורט מידע נוסף על קוד המקור של Rego.
מיקום
קוד המקור של Rego מאוחסן בשדה spec.targets, כאשר targets
הוא מערך של אובייקטים בפורמט הבא:
{"target": "admission.k8s.gatekeeper.sh","rego": REGO_SOURCE_CODE, "libs": LIST_OF_REGO_LIBRARIES}
-
target: מציין ל-Policy Controller את המערכת שאנחנו בודקים (במקרה הזה Kubernetes). מותרת רק רשומה אחת ב-targets. -
rego: קוד המקור של האילוץ. -
libs: רשימה אופציונלית של ספריות של קוד Rego שזמינות לתבנית האילוצים. הרשימה הזו נועדה להקל על השימוש בספריות משותפות, אבל היא לא נכללת במסגרת המסמך הזה.
קוד מקור
קוד המקור של Rego לאילוץ הקודם:
package k8sdenynames
violation[{"msg": msg}] {
input.review.object.metadata.name == input.parameters.invalidName
msg := sprintf("The name %v is not allowed", [input.parameters.invalidName])
}
שימו לב לנקודות הבאות:
- השדה
package k8sdenynamesנדרש על ידי OPA (זמן הריצה של Rego). המערכת מתעלמת מהערך. - כלל Rego ש-Policy Controller מפעיל כדי לבדוק אם יש הפרות נקרא
violation. אם יש התאמות לכלל הזה, סימן שהייתה הפרה של האילוץ. - הכלל
violationכולל את החתימהviolation[{"msg": "violation message for the user"}], כאשר הערך של"msg"הוא הודעת ההפרה שמוחזרת למשתמש. - הפרמטרים שמועברים לאילוץ זמינים תחת מילת המפתח
input.parameters. - ה-
request-under-testמאוחסן תחת מילת המפתחinput.review.
מילת המפתח input.review כוללת את השדות הבאים.
| שדה | תיאור |
|---|---|
uid |
המזהה הייחודי של הבקשה הספציפית הזו. המזהה לא זמין במהלך ביקורת. |
kind |
המידע על הסוג של
|
name |
שם המשאב יכול להיות שהשדה יהיה ריק אם המשתמש מסתמך על שרת ה-API כדי ליצור את השם בבקשת CREATE. |
namespace |
מרחב השמות של המשאב (לא מסופק למשאבים בהיקף אשכול). |
operation |
הפעולה המבוקשת (לדוגמה, CREATE או UPDATE). היא לא זמינה במהלך ביקורת. |
userInfo |
המידע של המשתמש ששלח את הבקשה. המידע הזה לא זמין במהלך ביקורת. הפורמט הוא:
|
object |
האובייקט שהמשתמש מנסה לשנות או ליצור. |
oldObject |
המצב המקורי של האובייקט. הערך הזה זמין רק בפעולות UPDATE. |
dryRun |
האם הבקשה הזו הופעלה באמצעות kubectl --dry-run. הערך הזה לא זמין במהלך ביקורת. |
כתיבה של תבניות אילוצים הפניות
תבניות של אילוצים הפנייתיים הן תבניות שמאפשרות למשתמש להגביל אובייקט אחד ביחס לאובייקטים אחרים. לדוגמה, 'לא לאפשר יצירת Pod לפני שמתגלה Ingress תואם'. דוגמה נוספת: "אסור לאפשר לשני שירותים להיות בעלי אותו שם מארח".
באמצעות Policy Controller אפשר לכתוב אילוצים רפרנציאליים על ידי מעקב אחרי שרת ה-API עבור קבוצת משאבים שסופקה על ידי המשתמש. כשמשנים משאב, Policy Controller שומר אותו במטמון באופן מקומי כדי שאפשר יהיה להפנות אליו בקלות מקוד המקור של Rego. Policy Controller מאפשר גישה למטמון הזה באמצעות מילת המפתח data.inventory.
משאבים בהיקף אשכול נשמרים במטמון במיקום הבא:
data.inventory.cluster["GROUP_VERSION"]["KIND"]["NAME"]
לדוגמה, צומת בשם my-favorite-node יכול להימצא בקטע
data.inventory.cluster["v1"]["Node"]["my-favorite-node"]
משאבים בהיקף מרחב השמות נשמרים במטמון כאן:
data.inventory.namespace["NAMESPACE"]["GROUP_VERSION"]["KIND"]["NAME"]
לדוגמה, אפשר למצוא ConfigMap בשם production-variables במרחב השמות shipping-prod בנתיב
data.inventory.namespace["shipping-prod"]["v1"]["ConfigMap"]["production-variables"]
התוכן המלא של האובייקט מאוחסן במיקום הזה במטמון, ואפשר להפנות אליו בקוד המקור של Rego בכל דרך שמתאימה לכם.
מידע נוסף על Rego
המידע שלמעלה מתאר את התכונות הייחודיות של Policy Controller, שמקלות על כתיבת אילוצים על משאבי Kubernetes ב-Rego. המדריך הזה לא כולל הדרכה מלאה על כתיבה ב-Rego. עם זאת, במסמכי התיעוד של Open Policy Agent יש מידע על התחביר והתכונות של שפת Rego עצמה.
התקנה של תבנית האילוצים
אחרי שיוצרים תבנית אילוץ, משתמשים ב-kubectl apply כדי להחיל אותה, ו-Policy Controller דואג להטמעה שלה. חשוב לבדוק את השדה status בתבנית האילוץ כדי לוודא שלא היו שגיאות בהפעלת התבנית. אם ההעלאה תצליח, בשדה status יוצג הערך created: true, והערך observedGeneration שצוין בשדה status יהיה שווה לערך בשדה metadata.generation.
אחרי שהתבנית נטענת, אפשר להחיל עליה אילוצים כמו שמתואר במאמר בנושא יצירת אילוצים.
הסרה של תבנית אילוצים
כדי להסיר תבנית אילוצים:
מוודאים שאף אילוץ שרוצים לשמור לא משתמש בתבנית האילוצים:
kubectl get TEMPLATE_NAME
אם יש התנגשות בשמות בין השם של תבנית האילוצים לבין אובייקט אחר באשכול, משתמשים בפקודה הבאה במקום:
kubectl get TEMPLATE_NAME.constraints.gatekeeper.sh
מסירים את תבנית האילוצים:
kubectl delete constrainttemplate CONSTRAINT_TEMPLATE_NAME
כשמסירים תבנית אילוצים, אי אפשר יותר ליצור אילוצים שמפנים אליה.
המאמרים הבאים
- מידע נוסף על Policy Controller
- אפשר לעיין במאמרי העזרה בנושא ספריית תבניות האילוצים.
- איך משתמשים במגבלות במקום ב-PodSecurityPolicies