מעבר מ-Policy Controller

במאמר הזה מוסבר איך להעביר את מדיניות בקרת הגישה מ-Policy Controller כדי לצמצם את הסיכון לפערים באכיפת המדיניות. התמיכה ב-Policy Controller תופסק ב-12 בנובמבר 2026, והתמיכה תסתיים ב-31 בדצמבר 2027. בגרסה 1.39 ואילך, אשכולות של Google Kubernetes Engine (GKE) לא תומכים ב-Policy Controller.

אתם יכולים להעביר את מדיניות הקבלה שאתם אוכפים באמצעות Policy Controller אל ValidatingAdmissionPolicies של Kubernetes או אל Open Policy Agent (OPA) Gatekeeper בניהול עצמי. ההעברה לא משפיעה על עומסי עבודה שכבר פועלים. ‫Policy Controller מעריך בקשות ליצירה או לעדכון של משאבים, כך שהסרה שלו לא מפעילה מחדש או משנה עומסי עבודה שפועלים.

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

שדרוגים חסומים לגרסה 1.39 של GKE

‫GKE חוסם שדרוגים לגרסה 1.39 ואילך באשכולות שמותקן בהם Policy Controller. לפני שמשדרגים אשכול לגרסה 1.39, צריך להעביר את כללי המדיניות ולהסיר את Policy Controller מהאשכול. אל תסירו את Policy Controller רק כדי לבטל את חסימת השדרוג לפני שאתם מעבירים את כללי המדיניות, כי פעולה כזו תשאיר את האשכול בלי אכיפת מדיניות.

בחירת תמונה אחרת

בודקים כל מדיניות בקרת גישה ב-Policy Controller ובוחרים אפשרות חלופית למדיניות הזו מהטבלה הבאה. אתם לא חייבים לבחור תחליף אחד לכל האשכול. אפשר לשלב אפשרויות באותו אשכול בהתאם לדרישות המדיניות של כל מדיניות:

השוואה בין האפשרויות להחלפת Policy Controller
אפשרות מתי משתמשים תפעול ותמיכה
‫ValidatingAdmissionPolicy (מומלץ) כללי מדיניות שבודקים משאב יחיד כשהוא נוצר או מתעדכן. רוב התבניות בספריית התבניות של Policy Controller פועלות כך. כללי המדיניות ValidatingAdmissionPolicies מובנים ב-Kubernetes וזמינים ב-GKE בגרסה 1.30 ואילך ללא עלות נוספת. ב-Cloud Customer Care יש תמיכה ב-ValidatingAdmissionPolicies כחלק מ-GKE.
Pod Security Admission (מומלץ לחבילות אבטחה של Pod) אמצעי בקרה מוגדרים מראש לאבטחת Pod מהחבילה pss-baseline-v2022, pss-restricted-v2022 או psp-v2022. מידע נוסף זמין במאמר שימוש ב-Pod Security Admission לחבילות אבטחה של Pod. ‫Pod Security Admission מובנה ב-Kubernetes ומופעל כברירת מחדל ב-GKE ללא עלות נוספת. שירות הלקוחות תומך ב-Pod Security Admission כחלק מ-GKE.
‫OPA Gatekeeper בניהול עצמי כללי מדיניות שאי אפשר לבטא באמצעות ValidatingAdmissionPolicies, כמו כללי מדיניות של הפניות שקוראים משאבים אחרים באשכול, כללי מדיניות שרוצים לשמור ב-Rego וביקורות של משאבים קיימים. אתם יכולים גם להוסיף כללים של Common Expression Language‏ (CEL) ל-ConstraintTemplates של Gatekeeper, כדי ש-Gatekeeper ייצור ValidatingAdmissionPolicies לאכיפה של שרת ה-API, ובקר הביקורת שלו יבדוק את המשאבים הקיימים. אתם מתקינים, משדרגים ומפעילים את Gatekeeper. שירות הלקוחות לא תומך ב-Gatekeeper בקוד פתוח. קהילת Gatekeeper מספקת תמיכה דרך GitHub.

מלאי וסיווג של כללי המדיניות

כברירת מחדל, ספריית התבניות של Policy Controller מתקינה את כל התבניות, וחבילות המדיניות מתקינות את האילוצים שלהן עם פעולת האכיפה dryrun. לכן, התבניות והאילוצים באשכול לא בהכרח תואמים למדיניות שאתם אוכפים. כדי לבדוק מה אתם אוכפים, בצעו את השלבים הבאים:

  1. מזהים את האשכולות בצי שמריצים את Policy Controller:

    gcloud container fleet policycontroller describe \
        --project=PROJECT_ID
    

    מחליפים את PROJECT_ID במזהה של הפרויקט המארח של ה-fleet.

  2. בכל אשכול שזיהיתם, ציינו את האילוצים:

    kubectl get constraints \
        -o custom-columns='KIND:.kind,NAME:.metadata.name,'\
    'ACTION:.spec.enforcementAction,VIOLATIONS:.status.totalViolations,'\
    'BUNDLE:.metadata.labels.policycontroller\.gke\.io/bundleName'
    

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

  3. מגבים את ConstraintTemplates ואת האילוצים בקבצים נפרדים:

    kubectl get constrainttemplates -o yaml \
        > policy-controller-templates-backup.yaml
    kubectl get constraints -o yaml \
        > policy-controller-constraints-backup.yaml
    
  4. אופציונלי: מבצעים את פעולות הגיבוי הנוספות הבאות:

    • אם הפעלתם כללי הפניה ב-Policy Controller, אתם צריכים לגבות את הגדרות הסנכרון:

      kubectl get config.config.gatekeeper.sh -n gatekeeper-system -o yaml \
          > policy-controller-config-backup.yaml
      
    • אם הפעלתם מוטציה ב-Policy Controller, גבו את המוטטורים:

      kubectl get assign,assignmetadata,assignimage,modifyset -o yaml \
          > policy-controller-mutators-backup.yaml
      

שמרו את קובצי הגיבוי האלה במקום בטוח. כשמסירים את Policy Controller, נמחקים כל ConstraintTemplate, אילוץ, הגדרת סנכרון ומוטטור באשכול, כולל אלה שיצרתם. אתם צריכים את הגיבויים כדי לתרגם או ליצור מחדש את כללי המדיניות.

אחרי שגיביתם את כללי המדיניות, אתם צריכים לבדוק את סוג האילוץ בטבלה הבאה כדי לקבוע את נתיב ההעברה של כל אילוץ:

נתיבי העברה לפי סוג האילוץ
סוג המגבלה נתיב ההעברה
אילוץ על משאב יחיד אם האילוץ מעריך שדות רק במשאב הנכנס בלי לקרוא את data.inventory או להשתייך לחבילת אבטחה של Pod, צריך להשתמש ב-ValidatingAdmissionPolicy.
אילוץ dryrun שלא נאכף אם באילוץ מסוים מוגדרת פעולת האכיפה dryrun ואתם לא מתכוונים לאכוף אותו, מחקו את האילוץ.
אילוץ של חבילת אבטחה של Pod אם האילוץ מגיע מהחבילה pss-baseline-v2022, pss-restricted-v2022 או psp-v2022, צריך להשתמש ב-Pod Security Admission. השתמשו ב-ValidatingAdmissionPolicies לכל אמצעי הבקרה שלא נכללים ב-Pod Security Admission.
אילוץ הפניה אם באילוץ נעשה שימוש בתבנית הפניה שקוראת משאבים אחרים באשכול, צריך להשתמש ב-Gatekeeper בניהול עצמי. כדי למצוא תבניות עם הפניות, מחפשים בקובץ הגיבוי את ההפניה data.inventory.
‫Cloud Service Mesh,‏ Istio או אילוץ של Google Cloud בודקים את האילוץ בנפרד כדי לראות אם תכונה מובנית של GKE מחליפה את המדיניות, או אם ConstraintTemplate בקובץ הגיבוי קורא את data.inventory. רוב התבניות האלה בודקות רק את המשאב הנכנס ופועלות ב-ValidatingAdmissionPolicies, חוץ מהתבניות הרפרנציאליות AsmAuthzPolicyDefaultDeny ו-AsmPeerAuthnMeshStrictMtls, שדורשות Gatekeeper בניהול עצמי. כדי להחליף את התבניות המובנות, מפעילים את Binary Authorization במקום להשתמש ב-ConstraintTemplate של K8sRequireBinAuthZ, ומגדירים את קובץ האימג' של מאגרי הצמתים במקום להשתמש ב-ConstraintTemplate של K8sRequireCosNodeImage.

מעבר ל-ValidatingAdmissionPolicy

‫ValidatingAdmissionPolicy מכיל את הלוגיקה של המדיניות, כמו ConstraintTemplate. ‫ValidatingAdmissionPolicyBinding מחיל את המדיניות, כמו אילוץ. ב-ValidatingAdmissionPolicy נעשה שימוש בביטויי CEL במקום ב-Rego, ושרת ה-API מעריך את הביטויים ישירות, בלי לפנות ל-webhook.

דוגמה: מאגרי תמונות מותרים

האילוץ הבא של Policy Controller מחייב את Pods להשתמש בתמונות ממאגר אחד של Artifact Registry. הוא לא כולל את מרחב השמות kube-system:

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sAllowedRepos
metadata:
  name: allowed-repos
spec:
  enforcementAction: deny
  match:
    kinds:
    - apiGroups: [""]
      kinds: ["Pod"]
    excludedNamespaces: ["kube-system"]
  parameters:
    repos:
    - "us-docker.pkg.dev/example-project/example-repo/"

ה-ValidatingAdmissionPolicy וה-ValidatingAdmissionPolicyBinding הבאים אוכפים את אותו כלל. ה-ValidatingAdmissionPolicyBinding משתמש בפעולות Warn ו-Audit כדי שתוכלו להשוות את התוצאות לפני שאתם אוכפים את ה-ValidatingAdmissionPolicy:

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: allowed-repos
spec:
  failurePolicy: Fail
  matchConstraints:
    resourceRules:
    - apiGroups: [""]
      apiVersions: ["v1"]
      operations: ["CREATE", "UPDATE"]
      resources: ["pods", "pods/ephemeralcontainers"]
  variables:
  - name: repos
    expression: "['us-docker.pkg.dev/example-project/example-repo/']"
  - name: images
    expression: >-
      object.spec.containers.map(c, c.image) +
      (has(object.spec.initContainers) ?
        object.spec.initContainers.map(c, c.image) : []) +
      (has(object.spec.ephemeralContainers) ?
        object.spec.ephemeralContainers.map(c, c.image) : [])
  validations:
  - expression: >-
      variables.images.all(image,
        variables.repos.exists(repo, image.startsWith(repo)))
    messageExpression: >-
      'container images must come from one of these repositories: ' +
      variables.repos.join(', ')
    reason: Forbidden
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
  name: allowed-repos
spec:
  policyName: allowed-repos
  validationActions: ["Warn", "Audit"]
  matchResources:
    namespaceSelector:
      matchExpressions:
      - key: kubernetes.io/metadata.name
        operator: NotIn
        values: ["kube-system", "gatekeeper-system"]

בדוגמה הזו, המשתנה repos מכיל את הערך מהשדה parameters של האילוץ. ביטוי האימות מחזיר ערך true לפודים שתואמים ל-ValidatingAdmissionPolicy, שהוא ההפך מכלל הפרה של Rego. כדי להשתמש שוב ב-ValidatingAdmissionPolicy אחד בכמה ValidatingAdmissionPolicyBindings שמספקים ערכים שונים, צריך להשתמש במשאב פרמטר במקום במשתנה. מידע נוסף על משאבי פרמטרים זמין במאמר משאבי פרמטרים במסמכי התיעוד של Kubernetes.

בטבלה הבאה מוצג המיפוי של שדות האילוצים לשדות ValidatingAdmissionPolicy ו-ValidatingAdmissionPolicyBinding:

מיפוי של שדות האילוצים של Policy Controller לשדות ValidatingAdmissionPolicy ו-ValidatingAdmissionPolicyBinding
שדה האילוץ שדה ValidatingAdmissionPolicy או ValidatingAdmissionPolicyBinding
spec.enforcementAction השדה validationActions ב-ValidatingAdmissionPolicyBinding, שממפה את הפעולות deny, warn ו-dryrun לערכים ["Deny"], ["Warn"] ו-["Audit"]
spec.parameters השדה variables ב-ValidatingAdmissionPolicy, או משאב פרמטרים שה-ValidatingAdmissionPolicyBinding מפנה אליו בשדה paramRef
spec.match.kinds השדה matchConstraints.resourceRules ב-ValidatingAdmissionPolicy, שמשתמש בקבוצות API ובשמות של משאבים, כמו המשאב pods, במקום בסוגים
‫spec.match.namespaces ו-spec.match.excludedNamespaces השדה matchResources.namespaceSelector ב-ValidatingAdmissionPolicyBinding, באמצעות האופרטור In או NotIn בתווית kubernetes.io/metadata.name
spec.match.labelSelector השדה matchResources.objectSelector ב-ValidatingAdmissionPolicyBinding
spec.match.namespaceSelector השדה matchResources.namespaceSelector ב-ValidatingAdmissionPolicyBinding
spec.match.scope השדה scope של כל כלל משאבים

מידע נוסף על כתיבת ביטויים זמין במאמר CEL ב-Kubernetes במסמכי התיעוד של Kubernetes.

בדיקת כללי מדיניות לצד Policy Controller

כדי להחליף אילוץ בלי פער באכיפה, מריצים את ValidatingAdmissionPolicy לצד האילוץ לפני שאוכפים את ValidatingAdmissionPolicy:

  1. מחילים את ValidatingAdmissionPolicy ואת ValidatingAdmissionPolicyBinding עם ההגדרה validationActions: ["Warn", "Audit"]. משאירים את האילוץ של Policy Controller במקום.
  2. משווים את התוצאות באמצעות השאילתה של יומן הביקורת בקטע החלפת הדיווח על הפרות. אם ValidatingAdmissionPolicy מסמן בקשות ש-Policy Controller מאפשר, או להיפך, צריך לתקן את ValidatingAdmissionPolicy. במדיניות ValidatingAdmissionPolicies שתואמת לפודים, אל תסתמכו על אזהרות. הבקרים יוצרים את ה-Pods לפריסות ולעומסי עבודה אחרים, ולכן הבקר מקבל את האזהרה.
  3. אחרי שהתוצאות תואמות, משנים את ValidatingAdmissionPolicyBinding כדי להשתמש בהגדרה validationActions: ["Deny"].
  4. מוחקים את האילוץ של Policy Controller.

התכוננו להבדלים בהתנהגות

כללי המדיניות של ValidatingAdmissionPolicies פועלים באופן שונה מ-Policy Controller בדרכים הבאות, שיכולות לחסום בקשות או להשאיר פערים באכיפה:

  • מדיניות כשל: ה-webhook של Policy Controller נכשל במצב פתוח, כלומר שרת ה-API מאשר בקשה אם Policy Controller לא מגיב. אם ValidatingAdmissionPolicy כולל את ההגדרה failurePolicy: Fail, הבקשה נדחית אם הביטוי מחזיר שגיאה או חורג ממגבלת העלות של CEL. בנוסף, ValidatingAdmissionPolicy דוחה בקשה אם משאב הפרמטר שאליו מפנים לא קיים, והערך של השדה paramRef.parameterNotFoundAction ב-ValidatingAdmissionPolicyBinding הוא Deny. אם הערך הוא Allow, שרת ה-API מדלג על משאב של פרמטר חסר, בלי קשר להגדרה של failurePolicy. בודקים כל ValidatingAdmissionPolicy ובוחרים ערכים לשני השדות.
  • שדות חסרים: ב-Rego, שדה חסר לא נחשב להפרה, אבל ב-CEL מוחזרת שגיאה. לפני שקוראים שדה אופציונלי, משתמשים במאקרו has() כדי לבדוק אם השדה קיים.
  • פטורים: מדיניות ValidatingAdmissionPolicy לא פוטרת מרחבי שמות כברירת מחדל ולא משתמשת בתווית admission.gatekeeper.sh/ignore. באשכולות GKE Standard, ‏ValidatingAdmissionPolicyBinding חל על כל מרחב שמות באשכול, כולל מרחבי שמות של המערכת כמו מרחב השמות kube-system, אלא אם מחריגים אותם בשדה matchResources.namespaceSelector ב-ValidatingAdmissionPolicyBinding או בשדות matchConstraints.namespaceSelector או matchConditions ב-ValidatingAdmissionPolicy. באשכולות Autopilot, ‏GKE מחריג באופן אוטומטי מרחבי שמות מנוהלים ודוחה את ValidatingAdmissionPolicies שתואמים למשאבים nodes, persistentVolumes, certificatesigningrequests או tokenreviews. אמצעי האבטחה של GKE Autopilot
  • משאבי משנה: Policy Controller בודק עדכונים של Pod שמוסיפים קונטיינרים זמניים. כדי לשמור על הכיסוי הזה, צריך לכלול את משאב המשנה pods/ephemeralcontainers בכללי המשאבים, כמו בדוגמה.
  • אין ביקורת על משאבים קיימים: ValidatingAdmissionPolicy מעריך רק בקשות נכנסות לשרת ה-API. הוא לא מדווח על משאבים קיימים שמפירים את ValidatingAdmissionPolicy.
  • הודעה אחת לכל בקשה: ValidatingAdmissionPolicy מדווח על האימות הראשון שנכשל, ולא על כל הפרה.

שימוש ב-Pod Security Admission לחבילות אבטחה של Pod

אם אתם משתמשים בחבילות pss-baseline-v2022 או pss-restricted-v2022, החליפו את החבילה ב-Pod Security Admission במקום לתרגם כל אילוץ. ב-Pod Security Admission נעשה שימוש ב-PodSecurityadmission controller המובנה של Kubernetes כדי לאכוף כללים מוגדרים מראש מתקני האבטחה של Kubernetes Pod על סמך תוויות של מרחב שמות. החבילה pss-baseline-v2022 תואמת לרמה baseline, והחבילה pss-restricted-v2022 תואמת לרמה restricted.

בקרת הגישה לאבטחת Pod לא כוללת את כל אמצעי הבקרה בחבילה psp-v2022, כמו רשימות היתרים לנתיבי מארח, משתמשים, יכולות ו-sysctls. כדי להשתמש באמצעי הבקרה האלה, צריך להשתמש ב-ValidatingAdmissionPolicies. בנוסף, אי אפשר להחריג קובצי אימג' ספציפיים ב-Pod Security Admission, כמו אילוצים של Policy Controller שמשתמשים בפרמטר exemptImages. ב-GKE אין תמיכה בהגדרת פטורים מ-Pod Security Admission. אם אתם צריכים חריגים, השתמשו ב-ValidatingAdmissionPolicies למדיניות המושפעת.

מידע נוסף על הגדרת Pod Security Admission זמין במאמר החלת מדיניות אבטחה מוגדרת מראש ברמת ה-Pod באמצעות PodSecurity.

מעבר ל-OPA Gatekeeper בניהול עצמי

בחרו ב-Gatekeeper למדיניות שאי אפשר לבטא באמצעות ValidatingAdmissionPolicies. ‫Policy Controller מבוסס על Gatekeeper, ולכן ConstraintTemplates והאילוצים משתמשים באותם ממשקי API ב-Gatekeeper. כל התבניות בספריית התבניות של Policy Controller פועלות ב-Gatekeeper בלי שינויים בלוגיקה שלהן. עם זאת, Gatekeeper משתמש במנוע Rego חדש יותר ובאימות מחמיר יותר שיכול לדחות ConstraintTemplate בהתאמה אישית.

כשמשתמשים ב-Gatekeeper בניהול עצמי, אתם אחראים למשימות ש-Google Cloud מבצע בשביל Policy Controller, כמו התקנה, שדרוג, התאמה לעומס (scaling) ומעקב אחרי Gatekeeper בכל אשכול. שירות הלקוחות לא תומך ב-Gatekeeper בקוד פתוח. לקבלת עזרה, אפשר להשתמש בכלי למעקב אחר בעיות של Gatekeeper ב-GitHub.

‫Gatekeeper לא כולל את ספריית התבניות או את חבילות המדיניות של Policy Controller. קובצי הגיבוי מכילים את ה-ConstraintTemplates ואת האילוצים מהאשכולות. לתבניות שמקורן בספריית הקוד הפתוח של Gatekeeper, אתם יכולים להשתמש בתבניות שבספריית המדיניות של Gatekeeper. שמות התבניות נשארים זהים, אבל הפרמטרים וההודעות יכולים להיות שונים בין הגרסאות.

כדי להעביר כללי מדיניות ל-Gatekeeper, צריך לפעול לפי השלבים הבאים:

  1. אופציונלי: אם אתם לא יכולים לקבל פער באכיפה בזמן שאתם מחליפים את Policy Controller, קודם אתם צריכים להעביר את כללי המדיניות הכי חשובים שלכם ל-ValidatingAdmissionPolicies. חשוב לוודא שהמרחב השמי gatekeeper-system לא נכלל ב-ValidatingAdmissionPolicyBindings האלה, כדי שהם לא יחסמו את משימות ההתקנה של Gatekeeper. אחרי שמסירים את Policy Controller, האשכול מפסיק לאכוף את כללי המדיניות של Gatekeeper עד שמחילים את האילוצים התואמים של Gatekeeper. מדיניות ValidatingAdmissionPolicies ממשיכה לאכוף כי היא לא תלויה ב-Policy Controller או ב-Gatekeeper.
  2. אם אתם משתמשים ב-ConstraintTemplates בהתאמה אישית, אתם צריכים לבדוק כל מניפסט של תבנית בהתאמה אישית באמצעות כלי שורת הפקודה gator מגרסת Gatekeeper שאתם מתכננים להתקין:

    gator test --filename=TEMPLATE_FILE
    

    מחליפים את TEMPLATE_FILE בנתיב לקובץ המניפסט של ConstraintTemplate. לפני שמסירים את Policy Controller, צריך לתקן את כל ה-ConstraintTemplates בהתאמה אישית שנדחו על ידי Gatekeeper.

  3. אם אתם פורסים אילוצים ממאגר Git באמצעות כלי GitOps, אתם צריכים להכין את ה-ConstraintTemplates שבהם האילוצים משתמשים ולהוסיף אותם למאגר כשאתם מתקינים את Gatekeeper. אחרת, האילוצים לא יחולו אחרי הסרת Policy Controller כי ה-ConstraintTemplates שלהם לא קיימים יותר.

  4. מסירים את Policy Controller לפי השלבים שמפורטים במאמר הסרת Policy Controller. אל תתקינו את Gatekeeper באשכול שעדיין פועל בו Policy Controller. שניהם משתמשים במרחב השמות gatekeeper-system, באותם CustomResourceDefinitions ובאותם שמות של webhook.

  5. מתקינים את Gatekeeper באמצעות Helm, לפי ההגדרות שבוחרים מהטבלה בקטע הבא, הגדרות Gatekeeper ששונות מ-Policy Controller. למידע נוסף על התקנת Gatekeeper, קראו את הקטע Installation במסמכי התיעוד של Gatekeeper.

    באשכולות Autopilot, ההתקנה של תרשים Helm שמוגדר כברירת מחדל נכשלת כי GKE דוחה כללי תו כללי לחיפוש ב-webhooks של מוטציות. מגדירים את הערך disableMutation: true ב-Helm, או מגדירים את הערך mutatingWebhookCustomRules ב-Helm כדי להציג רק את המשאבים הספציפיים שהמוטציות מטרגטות. אל תכללו את המשאבים nodes,‏ persistentvolumes,‏ certificatesigningrequests או tokenreviews.

  6. בקבצי הגיבוי, מסירים את השדות, התוויות וההערות הבאים מכל משאב שרוצים להחיל מחדש:

    • השדה status.
    • ‫השדות resourceVersion,‏ uid,‏ creationTimestamp,‏ generation,‏ managedFields ו-ownerReferences בקטע metadata.
    • ההערה kubectl.kubernetes.io/last-applied-configuration.
    • התווית app.kubernetes.io/managed-by: anthospolicycontroller.googleapis.com . אם Policy Controller מופעל שוב באשכול, למשל באמצעות הגדרת ברירת מחדל ברמת ה-fleet, הוא מנהל את המשאבים עם התווית הזו ויכול לשנות או למחוק אותם.
    • תוויות והערות שהמפתחות שלהן כוללים את הקידומת policycontroller..
  7. מחילים את ConstraintTemplates שבהם משתמשים האילוצים, ואז בודקים ש-Gatekeeper יצר CustomResourceDefinition לכל תבנית:

    kubectl get constrainttemplates \
        -o custom-columns='NAME:.metadata.name,CREATED:.status.created'
    

    כשהערך true מופיע בעמודה CREATED בכל התבניות, אפשר להחיל את האילוצים.

הגדרות של Gatekeeper ששונות מ-Policy Controller

לפני שמתקינים את Gatekeeper, כדאי לבדוק את ההגדרות בטבלה הבאה, שבה ברירות המחדל של תרשים ה-Helm של Gatekeeper שונות מאלה של Policy Controller:

השוואה בין ברירות המחדל של Policy Controller לבין ברירות המחדל של תרשים Gatekeeper Helm
הגדרה ברירת המחדל של Policy Controller ברירת המחדל של תרשים Gatekeeper Helm המלצה
מוטציה מושבת, אלא אם הפעלתם אותו מופעל אם אתם לא משתמשים במוטציה, הגדירו את ערך Helm של disableMutation: true. באשכולות Autopilot, צריך להגדיר את הערך disableMutation: true של Helm או להגדיר את הערך mutatingWebhookCustomRules של Helm בלי תווים כלליים לחיפוש או משאבים מוגבלים. אם לא מציינים אחד מהערכים האלה, GKE דוחה את ההתקנה.
מרחבי שמות פטורים מרחב השמות gatekeeper-system ומרחבי השמות ברשימה exemptableNamespaces מרחב השמות שבו מותקן Gatekeeper מוסיפים את מרחבי השמות הפטורים לערך controllerManager.exemptNamespaces של Helm. ‫Gatekeeper דוחה שינויים במרחבי שמות עם התווית admission.gatekeeper.sh/ignore, אלא אם מרחבי השמות האלה פטורים.
נתונים להפניה מסונכרנים באופן אוטומטי בחבילות של קובצי עזר לא מסונכרן יוצרים Gatekeeper Config או SyncSet שמפרט את הסוגים שתבניות ההפניה קוראות. עד שהסוגים האלה יסונכרנו עם האובייקט data.inventory, בדיקות של התנגשויות יאפשרו בקשות שמפרות את המדיניות, ובדיקות קיום, כמו ConstraintTemplate‏ K8sRequireNamespaceNetworkPolicies, ידחו כל בקשה תואמת גם אם המשאב הנדרש קיים.
יצירת ValidatingAdmissionPolicy לא זמין מופעל בתבניות שמכילות קוד CEL התבניות של Policy Controller מכילות רק Rego, לכן Gatekeeper יוצר ValidatingAdmissionPolicies רק אם מוסיפים CEL ל-ConstraintTemplates. כדי להמשיך לאכוף את ה-webhook, מגדירים את ערכי Helm של defaultCreateVAPForTemplates: false ו-defaultCreateVAPBindingForConstraints: false. מידע נוסף זמין במאמר Integration with Kubernetes Validating Admission Policy במסמכי התיעוד של Gatekeeper.
רפליקות ומשאבים רפליקה אחת לכל רכיב, עם מגבלת זיכרון של 1,024 MiB שלוש רפליקות של webhook, עם מגבלות שונות על המשאבים מגדירים את מספר הרפליקות ואת מגבלות המשאבים על סמך השימוש הנוכחי.
תמונות נשלף ממאגר בניהול Google נשלף מ-Docker Hub (קובצי האימג' openpolicyagent/gatekeeper,‏ openpolicyagent/gatekeeper-crds ו-curlimages/curl) באשכולות פרטיים או באשכולות שבהם נאכפת Binary Authorization, צריך לשכפל את כל שלוש התמונות ל-Artifact Registry ולשנות את ערכי התמונות שלהן בתרשים. אם לא משכפלים את קובץ האימג' של curlimages/curl, צריך להשבית את ה-Job של בדיקת ה-webhook.

כברירת מחדל, Gatekeeper חושף רק מדדי Prometheus, ושמות המדדים שלו שונים מהשמות ש-Policy Controller שולח ל-Cloud Monitoring. מעדכנים את כל מרכזי הבקרה וההתראות שמשתמשים במדדים של Policy Controller.

העברת כללי מדיניות של שינוי ערכים

אם הפעלתם מוטציה ב-Policy Controller, אתם יכולים להציג את רשימת המוטטורים:

kubectl get assign,assignmetadata,assignimage,modifyset

לכל מוטטור, בוחרים אחת מהאפשרויות הבאות:

  • ‫MutatingAdmissionPolicy: אפשר להשתמש ב-MutatingAdmissionPolicy ב-GKE מגרסה 1.36 ואילך. בדומה ל-ValidatingAdmissionPolicy, גם MutatingAdmissionPolicy משתמשת בביטויי CEL ופועלת בשרת ה-API בלי webhook. ‫Kubernetes מריץ את כל כללי המדיניות מסוג MutatingAdmissionPolicies לפני כללי המדיניות מסוג ValidatingAdmissionPolicies, לכן כדאי לבדוק אותם ביחד כדי לוודא שמוטציה לא גורמת ל-ValidatingAdmissionPolicy לדחות מניפסט תקין. באשכולות Autopilot, ‏GKE מחריג מרחבי שמות מנוהלים מ-MutatingAdmissionPolicies. למידע נוסף על מדיניות מוטציה, קראו את המאמר Mutating Admission Policy במסמכי התיעוד של Kubernetes.
  • Gatekeeper בניהול עצמי: באשכולות Standard, המוטציות פועלות ללא שינויים כי Gatekeeper מפעיל מוטציות כברירת מחדל. באשכולות Autopilot, צריך להגדיר את הערך mutatingWebhookCustomRules של Helm בתרשים של Gatekeeper כדי לציין את המשאבים הספציפיים שהמוטטורים מטרגטים, במקום כללי תווים כלליים לחיפוש. מידע נוסף זמין במאמר אמצעי האבטחה של GKE Autopilot. אחרי שמתקינים את Gatekeeper, מסירים את המטא-נתונים של Policy Controller מקובץ הגיבוי של המוטטורים ומחילים מחדש את המוטטורים, כמו שעושים עם אילוצים.

עדכון בדיקות המדיניות בצינורות עיבוד נתונים של גרסאות build

יכול להיות שצינור עיבוד הנתונים של ה-build יבדוק את המניפסטים מול האילוצים של Policy Controller לפני הפריסה. לדוגמה, יכול להיות שהצינור משתמש בפונקציה gatekeeper ב-kpt או בכלי שורת הפקודה gator. למידע נוסף, קראו את המאמר אימות אפליקציות בהתאם למדיניות החברה בצינור עיבוד נתונים של CI.

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

  • אם אתם משתמשים ב-Gatekeeper, אתם יכולים להמשיך להשתמש בצינור עיבוד הנתונים שלכם. מעדכנים את הקובץ או את נתיבי הספרייה בפקודה gator או kpt כדי להפנות למאגר או לספרייה שמכילים את המניפסטים של ConstraintTemplate ושל האילוצים של Gatekeeper אחרי הניקוי.
  • אם אתם משתמשים ב-ValidatingAdmissionPolicies, הכלים האלה לא בודקים את כללי המדיניות שלכם. במקום זאת, צריך להריץ הרצה יבשה בצד השרת באשכול בדיקה שכולל את ValidatingAdmissionPolicies ואת ValidatingAdmissionPolicyBindings שמשתמשים בפעולה Deny:

    kubectl apply --dry-run=server -f MANIFEST_DIRECTORY
    

    מחליפים את MANIFEST_DIRECTORY בספרייה שמכילה את המניפסטים. הפקודה נכשלת אם ValidatingAdmissionPolicy דוחה מניפסט.

החלפת הדיווח על הפרה

‫ValidatingAdmissionPolicy לא כולל מרכז בקרה, והוא לא מבצע ביקורת על משאבים שכבר קיימים באשכול. במקום זאת, השתמשו בשיטות הבאות:

  • אזהרות: אם ValidatingAdmissionPolicyBinding משתמש בפעולה Warn, שרת ה-API מחזיר אזהרה ללקוח ששלח את הבקשה, כמו כלי שורת הפקודה kubectl. ב-Pods שנוצרים על ידי בקר, כמו Pods ב-Deployment, הבקר מקבל את האזהרה.
  • יומני ביקורת: אם ValidatingAdmissionPolicyBinding משתמש בפעולה Audit, שרת ה-API מוסיף הערה לרשומה ביומן הביקורת לכל אימות שנכשל. ‫GKE כותב בקשות ליצירה, לעדכון ולמחיקה ביומני הביקורת של פעילות האדמין ב-Cloud Logging. כדי למצוא אימותים שנכשלו, מריצים את השאילתה הבאה ב-Logs Explorer:

    resource.type="k8s_cluster"
    logName:"cloudaudit.googleapis.com%2Factivity"
    labels."validation.policy.admission.k8s.io/validation_failure":*
    

אם אתם משתמשים באילוצים שכוללים את פעולת האכיפה dryrun כדוח תאימות במשאבים קיימים, ValidatingAdmissionPolicies לא יכול להחליף את הדוח הזה. כדאי להשאיר את כללי המדיניות האלה ב-Gatekeeper בניהול עצמי, שבקר הביקורת שלו בודק את המשאבים הקיימים לפי לוח זמנים.

הסרת Policy Controller

לפני שמסירים את Policy Controller מאשכול, צריך לבצע את הפעולות הבאות:

  • מוודאים שכל כללי המדיניות שהעברתם ל-ValidatingAdmissionPolicies או ל-Pod Security Admission נאכפים, ושיש לכם גיבוי של ConstraintTemplates, של האילוצים ושל המוטציות. הסרת Policy Controller מוחקת את ה-CustomResourceDefinitions שלו, וכתוצאה מכך נמחקים כל ConstraintTemplate, אילוץ ומוטטור באשכול, כולל אלה שיצרתם.
  • אם אתם פורסים אילוצים ממאגר Git באמצעות כלי GitOps כמו סנכרון תצורות או Argo CD, הסירו את האילוצים שהוחלפו מהמאגר. מוודאים שהאילוצים הוסרו מהאשכולות.
  • אופציונלי: כדי לוודא ששום דבר לא תלוי ב-webhook של Policy Controller, קודם משעים את Policy Controller. ההשעיה מסירה רק את ההגדרות של ה-webhook, ואפשר לשחזר אותן.

כדי להסיר את Policy Controller:

  1. מסירים את Policy Controller מהאשכולות:

    gcloud container fleet policycontroller disable \
        --memberships=MEMBERSHIP_NAME \
        --project=PROJECT_ID
    

    מחליפים את מה שכתוב בשדות הבאים:

    • ‫MEMBERSHIP_NAME: שם המינוי של האשכול הרשום שממנו רוצים להסיר את Policy Controller. כדי להסיר את Policy Controller מכמה אשכולות, מציינים רשימה של שמות חברים שמופרדים בפסיקים, או מחליפים את הדגל --memberships=MEMBERSHIP_NAME בדגל --all-memberships.
    • ‫PROJECT_ID: המזהה של הפרויקט המארח של ה-Fleet.
  2. מוודאים שההסרה של Policy Controller מהאשכולות הסתיימה:

    gcloud container fleet policycontroller describe \
        --memberships=MEMBERSHIP_NAME \
        --project=PROJECT_ID \
        --format="yaml(membershipStates)"
    

    ממתינים עד שהערך של השדה policycontroller.state ברמה העליונה של כל חברות יהיה NOT_INSTALLED, ולא DECOMMISSIONING. רשומות componentStates נפרדות מגיעות למצב NOT_INSTALLED לפני שהניקוי של CustomResourceDefinition מסתיים.

    אם אתם מתכננים להתקין Gatekeeper בניהול עצמי, ודאו שמרחב השמות gatekeeper-system לא קיים יותר:

    kubectl get namespace gatekeeper-system
    

    מחכים עד שמופיעה הודעה שמרחב השמות gatekeeper-system לא נמצא.

  3. אופציונלי: כדי למנוע מאשכולות שתרשמו בהמשך לקבל את Policy Controller, הסירו את הגדרת ברירת המחדל ברמת ה-Fleet:

    gcloud container fleet policycontroller enable \
        --no-fleet-default-member-config \
        --project=PROJECT_ID
    

    הפקודה הזו מסירה רק את הגדרות ברירת המחדל. היא לא מתקינה את Policy Controller באף אשכול.

הסרת Policy Controller מאשכולות שלא שייכים ל-fleet

הפקודה gcloud container fleet policycontroller disable מסירה את Policy Controller רק מאשכולות שמנוהלים על ידי ה-fleet. אפשר להריץ את Policy Controller באשכול בלי ניהול צי במקרים הבאים:

  • התקנתם את Policy Controller באמצעות ConfigManagement Operator.
  • ביטלתם את הרישום של האשכול מה-fleet שלו, או שהרצתם את הפקודה gcloud container fleet policycontroller detach לפני שההסרה של Policy Controller הסתיימה.

כדי להסיר את Policy Controller מהאשכולות האלה, צריך להעביר את האשכול לניהול ה-fleet ואז להסיר את Policy Controller:

  1. מגבים את ConstraintTemplates, את האילוצים, את הגדרות הסנכרון ואת המוטציות, כפי שמתואר בקטע מלאי וסיווג של כללי המדיניות. כשמנקים מטא-נתונים מגיבויים שנוצרו מהתקנה של ConfigManagement Operator, צריך להסיר גם את התוויות configmanagement.gke.io/* ו-k8s-app: kubernetes-config-management, בנוסף לשדה ownerReferences ולמטא-נתונים של policycontroller.*.
  2. אם התקנתם את Policy Controller באמצעות ConfigManagement Operator, הסירו את השדה policyController מהמשאב המותאם אישית של ConfigManagement באשכול. מחכים עד שההתאמה תסתיים. ההתאמה יכולה להימשך כשתי דקות. לאחר מכן, בודקים אם מרחב השמות gatekeeper-system עדיין קיים:

    kubectl get namespace gatekeeper-system
    

    בגרסה 1.17 ומטה של ConfigManagement Operator, הסרת השדה policyController מסירה אוטומטית את Policy Controller. אם מרחב השמות gatekeeper-system לא נמצא, דלגו על שאר השלבים בקטע הזה. בגרסה 1.18 ואילך של ConfigManagement Operator, מרחב השמות gatekeeper-system נשאר באשכול, אז אפשר להמשיך לשלב הבא.

  3. אם האשכול לא רשום ב-Fleet, צריך לרשום אותו. למידע נוסף, קראו את המאמר רישום אשכול ב- Google Cloud ל-fleet.

  4. בודקים אם המוטציה מופעלת באשכול:

    kubectl get mutatingwebhookconfiguration \
        gatekeeper-mutating-webhook-configuration
    
  5. מפעילים את Policy Controller במינוי של האשכול כדי שה-fleet ינהל את ההתקנה הקיימת. אם הפקודה הקודמת החזירה את המשאב gatekeeper-mutating-webhook-configuration, צריך לכלול את הדגל --mutation כדי שה-fleet יאמץ משאבי מוטציה ברמת האשכול, ובהמשך יסיר אותם:

    gcloud container fleet policycontroller enable \
        --memberships=MEMBERSHIP_NAME \
        --project=PROJECT_ID
    

    מחליפים את מה שכתוב בשדות הבאים:

    • ‫MEMBERSHIP_NAME: שם המינוי של האשכול הרשום.
    • ‫PROJECT_ID: המזהה של הפרויקט המארח של ה-Fleet.
  6. מחכים עד שהערך בשדה policycontroller.state של החברות יהיה ACTIVE:

    gcloud container fleet policycontroller describe \
        --memberships=MEMBERSHIP_NAME \
        --project=PROJECT_ID \
        --format="yaml(membershipStates)"
    
  7. מסירים את Policy Controller לפי השלבים שמפורטים במאמר הסרת Policy Controller. אם אתם לא מתקינים את Gatekeeper בניהול עצמי, מחקו את כל ה-CustomResourceDefinitions של האילוצים שנותרו אחרי שהסרתם את מרחב השמות gatekeeper-system:

    kubectl get crd -o name \
        | grep '\.constraints\.gatekeeper\.sh$' \
        | xargs -r kubectl delete
    
  8. אופציונלי: אם רשמתם את האשכול רק כדי להשלים את התהליך הזה, בטלו את הרישום שלו אחרי שהפקודה describe מציגה את המצב NOT_INSTALLED של המינוי. באשכולות שרשמתם באמצעות הדגל --enable-fleet, מריצים את הפקודה gcloud container clusters update עם הדגל --clear-fleet-project במקום הפקודה gcloud container fleet memberships unregister. למידע נוסף, קראו את המאמר ביטול הרישום של אשכול.

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