יצירת משאבים ב-Google Cloud שתואמים למדיניות

במדריך הזה מוסבר איך מנהלי פלטפורמות יכולים להשתמש בכללי המדיניות של Policy Controller כדי לקבוע איך ליצור משאבי Google Cloud באמצעות Config Connector.

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

ההוראות במדריך הזה מניחות שיש לכם ידע בסיסי ב-Kubernetes או ב-Google Kubernetes Engine ‏ (GKE). במדריך תגדירו מדיניות שמגבילה את המיקומים המותרים לקטגוריות של Cloud Storage.

הכלי Policy Controller בודק את התאימות של משאבי אשכול Kubernetes למדיניות שקשורה לאבטחה, לתקנות או לכללים עסקיים, מבצע ביקורות ומחיל את המדיניות. ‫Policy Controller מבוסס על פרויקט הקוד הפתוח OPA Gatekeeper.

‫Config Connector יוצר ומנהל את מחזור החיים של משאביGoogle Cloud , על ידי תיאור שלהם בתור משאבים בהתאמה אישית של Kubernetes. כדי ליצור Google Cloud משאב, יוצרים משאב ב-Kubernetes במרחב שמות שמנוהל על ידי Config Connector. הדוגמה הבאה מראה איך לתאר קטגוריה של Cloud Storage באמצעות Config Connector:

apiVersion: storage.cnrm.cloud.google.com/v1beta1
kind: StorageBucket
metadata:
  name: my-bucket
spec:
  location: us-east1

אם מנהלים את Google Cloud המשאבים באמצעות Config Connector, אפשר להחיל על המשאבים כללי מדיניות של Policy Controller בזמן שיוצרים אותם באשכול Google Kubernetes Engine. כללי המדיניות האלה מאפשרים לכם למנוע או לדווח על פעולות שיוצרות או משנות משאבים באופן שמפר את כללי המדיניות שלכם. לדוגמה, אפשר לאכוף מדיניות שמגבילה את המיקומים של קטגוריות של Cloud Storage.

הגישה הזו, שמבוססת על מודל המשאבים של Kubernetes ‏ (KRM), מאפשרת להשתמש בקבוצה עקבית של כלים ותהליכי עבודה כדי לנהל גם את Kubernetes וגם את המשאבים של Google Cloud . במדריך הזה מוסבר איך לבצע את הפעולות הבאות:

  • הגדרת מדיניות שחלה על Google Cloud המשאבים.
  • להטמיע אמצעי בקרה שמונעים ממפתחים ומאדמינים ליצור משאבי Google Cloud שמפירים את המדיניות שלכם.
  • כדאי להטמיע אמצעי בקרה שיבדקו את המשאבים הקיימים ב- Google Cloud בהתאם למדיניות שלכם, גם אם יצרתם את המשאבים האלה מחוץ ל-Config Connector.
  • לתת משוב מהיר למפתחים ולאדמינים כשהם יוצרים ומעדכנים הגדרות של משאבים.
  • מאמתים Google Cloud הגדרות של משאבים מול כללי המדיניות לפני שמנסים להחיל את ההגדרות על אשכול Kubernetes.

מטרות

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

עלויות

במסמך הזה משתמשים ברכיבים הבאים של Google Cloud, והשימוש בהם כרוך בתשלום:

כדי ליצור הערכת עלויות בהתאם לשימוש החזוי, אתם יכולים להשתמש במחשבון התמחור.

משתמשים חדשים של Google Cloud ? יכול להיות שאתם זכאים לתקופת ניסיון בחינם.

לפני שמתחילים

  1. בדף לבחירת הפרויקט במסוף Google Cloud , בוחרים פרויקט ב- Google Cloud או יוצרים אותו.

    תפקידים שנדרשים כדי לבחור או ליצור פרויקט

    • Select a project: כדי לבחור פרויקט לא צריך תפקיד IAM ספציפי – אפשר לבחור כל פרויקט שקיבלתם בו תפקיד.
    • יצירת פרויקט: כדי ליצור פרויקט, צריך את התפקיד Project Creator (roles/resourcemanager.projectCreator), שכולל את ההרשאה resourcemanager.projects.create. איך מקצים תפקידים

    כניסה לדף לבחירת הפרויקט

  2. מוודאים שהחיוב מופעל בפרויקט Google Cloud .

  3. מפעילים את Cloud Shell במסוף Google Cloud .

    הפעלת Cloud Shell

  4. ב-Cloud Shell, מגדירים את הפרויקט ב- Google Cloud שבו רוצים להשתמש במדריך הזה:

    gcloud config set project PROJECT_ID
    

    מחליפים את PROJECT_ID בGoogle Cloud מזהה הפרויקט של הפרויקט. כשמריצים את הפקודה הזו, Cloud Shell יוצר משתנה סביבה מיוצא בשם GOOGLE_CLOUD_PROJECT שמכיל את מזהה הפרויקט. אם אתם לא משתמשים ב-Cloud Shell, אתם יכולים ליצור את משתנה הסביבה באמצעות הפקודה הבאה:

    export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value core/project)
    
  5. מפעילים את GKE API:

    gcloud services enable container.googleapis.com
    
  6. מפעילים את Policy Controller API:

    gcloud services enable anthospolicycontroller.googleapis.com
    
  7. יוצרים ספרייה לאחסון הקבצים שנוצרו במדריך הזה:

    mkdir -p ~/cnrm-gatekeeper-tutorial
    
  8. עוברים לספרייה שיצרתם:

    cd ~/cnrm-gatekeeper-tutorial
    

יצירת אשכול GKE

  1. ב-Cloud Shell, יוצרים אשכול GKE עם התוסף Config Connector ועם איחוד זהויות של עומסי עבודה ל-GKE:

    gcloud container clusters create CLUSTER_NAME \
      --addons ConfigConnector \
      --enable-ip-alias \
      --num-nodes 4 \
      --release-channel regular \
      --scopes cloud-platform \
      --workload-pool $GOOGLE_CLOUD_PROJECT.svc.id.goog \
      --zone ZONE
    

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

    • ‫CLUSTER_NAME: השם של האשכול שרוצים להשתמש בו בפרויקט הזה, לדוגמה, cnrm-gatekeeper-tutorial.
    • ‫ZONE: אזור Compute Engine שקרוב למיקום שלכם, לדוגמה, asia-southeast1-b.

    התוסף Config Connector מתקין הגדרות מותאמות אישית של משאבים (CRD) עבור Google Cloud משאבים באשכול GKE.

  2. אופציונלי: אם אתם משתמשים באשכול פרטי בסביבה שלכם, מוסיפים כלל לחומת האש שמאפשר למישור הבקרה של אשכול GKE להתחבר ל-webhook של Policy Controller:

    gcloud compute firewall-rules create allow-cluster-control-plane-tcp-8443 \
      --allow tcp:8443 \
      --network default \
      --source-ranges CONTROL_PLANE_CIDR \
      --target-tags NODE_TAG
    

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

    • ‫CONTROL_PLANE_CIDR: טווח ה-IP של מישור הבקרה של אשכול GKE, לדוגמה 172.16.0.16/28.
    • ‫NODE_TAG: תג שמוחל על כל הצמתים באשכול GKE.

    כלל חומת האש האופציונלי הזה נדרש כדי שה-webhook של Policy Controller יפעל כשהאשכול משתמש בצמתים פרטיים.

הגדרת Config Connector

Google Cloud הפרויקט שבו מתקינים את Config Connector נקרא הפרויקט המארח. הפרויקטים שבהם משתמשים ב-Config Connector כדי לנהל משאבים נקראים פרויקטים מנוהלים. במדריך הזה, אתם משתמשים ב-Config Connector כדי ליצור משאביGoogle Cloud באותו פרויקט שבו נמצא אשכול GKE, כך שהפרויקט המארח והפרויקט המנוהל הם אותו פרויקט.

  1. ב-Cloud Shell, יוצרים חשבון שירות של Google עבור Config Connector:

    gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
      --display-name "Config Connector Gatekeeper tutorial"
    

    מחליפים את SERVICE_ACCOUNT_NAME בשם שרוצים לתת לחשבון השירות, לדוגמה, cnrm-gatekeeper-tutorial. ‫Config Connector משתמש בחשבון השירות הזה של Google כדי ליצור משאבים בפרויקט המנוהל.

  2. מקצים את התפקיד אדמין של Storage לחשבון השירות ב-Google:

    gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
      --member "serviceAccount:SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \
      --role roles/storage.admin
    

    במדריך הזה משתמשים בתפקיד 'אדמין אחסון' כי משתמשים ב-Config Connector כדי ליצור קטגוריות של Cloud Storage. בסביבה שלכם, צריך להעניק את התפקידים שנדרשים כדי לנהל את משאבי Google Cloud שרוצים ליצור עבור Config Connector. מידע נוסף על תפקידים מוגדרים מראש זמין במאמר הסבר על תפקידים במסמכי התיעוד של IAM.

  3. יוצרים מרחב שמות ב-Kubernetes למשאבי Config Connector שיוצרים במדריך הזה:

    kubectl create namespace NAMESPACE
    

    מחליפים את NAMESPACE במרחב השמות של Kubernetes שרוצים להשתמש בו במדריך, לדוגמה, tutorial.

  4. מוסיפים הערה למרחב השמות כדי לציין באיזה פרויקט Config Connector צריך להשתמש כדי ליצור משאבי Google Cloud (הפרויקט המנוהל):

    kubectl annotate namespace NAMESPACE \
        cnrm.cloud.google.com/project-id=$GOOGLE_CLOUD_PROJECT
    
  5. יוצרים ConfigConnectorContext משאב שמפעיל את Config Connector עבור מרחב השמות של Kubernetes ומקשר אותו לחשבון השירות של Google שיצרתם:

    cat << EOF | kubectl apply -f -
    apiVersion: core.cnrm.cloud.google.com/v1beta1
    kind: ConfigConnectorContext
    metadata:
      name: configconnectorcontext.core.cnrm.cloud.google.com
      namespace: NAMESPACE
    spec:
      googleServiceAccount: SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
    EOF
    

    כשיוצרים את המשאב ConfigConnectorContext, Config Connector יוצר חשבון שירות של Kubernetes ו-StatefulSet במרחב השמות cnrm-system כדי לנהל את המשאבים של Config Connector במרחב השמות.

  6. מחכים עד ש-Pod של בקר Config Connector יופיע במרחב השמות:

    kubectl wait --namespace cnrm-system --for=condition=Ready pod \
      -l cnrm.cloud.google.com/component=cnrm-controller-manager,cnrm.cloud.google.com/scoped-namespace=NAMESPACE
    

    כשה-Pod מוכן, מופיעה ההנחיה של Cloud Shell. אם מופיעה ההודעה error: no matching resources found, כדאי לחכות דקה ולנסות שוב.

  7. כדי לקשר את חשבון השירות של Kubernetes ב-Config Connector לחשבון השירות שלכם ב-Google, צריך ליצור קישור למדיניות IAM:

    gcloud iam service-accounts add-iam-policy-binding \
      SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \
      --member "serviceAccount:$GOOGLE_CLOUD_PROJECT.svc.id.goog[cnrm-system/cnrm-controller-manager-NAMESPACE]" \
      --role roles/iam.workloadIdentityUser
    

    הקישור הזה מאפשר לחשבון השירות של Kubernetes‏ cnrm-controller-manager-NAMESPACE במרחב השמות cnrm-system לפעול בתור חשבון השירות של Google שיצרתם.

התקנת Policy Controller

מתקינים את Policy Controller לפי הוראות ההתקנה.

משתמשים במרווח ביקורת של 60 שניות.

יצירת Google Cloud משאב באמצעות Config Connector

  1. ב-Cloud Shell, יוצרים מניפסט של Config Connector שמייצג קטגוריה של Cloud Storage באזור us-central1:

    cat << EOF > tutorial-storagebucket-us-central1.yaml
    apiVersion: storage.cnrm.cloud.google.com/v1beta1
    kind: StorageBucket
    metadata:
      name: tutorial-us-central1-$GOOGLE_CLOUD_PROJECT
      namespace: NAMESPACE
    spec:
      location: us-central1
      uniformBucketLevelAccess: true
    EOF
    
  2. כדי ליצור את הקטגוריה של Cloud Storage, מפעילים את המניפסט:

    kubectl apply -f tutorial-storagebucket-us-central1.yaml
    
  3. מוודאים ש-Config Connector יצר את הקטגוריה של Cloud Storage:

    gcloud storage ls | grep tutorial
    

    הפלט אמור להיראות כך:

    gs://tutorial-us-central1-PROJECT_ID/
    

    הפלט כולל את PROJECT_ID, שהוא מזהה הפרויקט Google Cloud .

    אם הפלט הזה לא מופיע, המתינו דקה ובצעו את השלב שוב.

הוספה של כלל מדיניות

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

  1. ב-Cloud Shell, יוצרים תבנית אילוצים שמגבילה את המיקומים של קטגוריות Cloud Storage:

    cat << EOF > tutorial-storagebucket-location-template.yaml
    apiVersion: templates.gatekeeper.sh/v1beta1
    kind: ConstraintTemplate
    metadata:
      name: gcpstoragelocationconstraintv1
    spec:
      crd:
        spec:
          names:
            kind: GCPStorageLocationConstraintV1
          validation:
            openAPIV3Schema:
              properties:
                locations:
                  type: array
                  items:
                    type: string
                exemptions:
                  type: array
                  items:
                    type: string
      targets:
      - target: admission.k8s.gatekeeper.sh
        rego: |
          package gcpstoragelocationconstraintv1
    
          allowedLocation(reviewLocation) {
              locations := input.parameters.locations
              satisfied := [ good | location = locations[_]
                                    good = lower(location) == lower(reviewLocation)]
              any(satisfied)
          }
    
          exempt(reviewName) {
              input.parameters.exemptions[_] == reviewName
          }
    
          violation[{"msg": msg}] {
              bucketName := input.review.object.metadata.name
              bucketLocation := input.review.object.spec.location
              not allowedLocation(bucketLocation)
              not exempt(bucketName)
              msg := sprintf("Cloud Storage bucket <%v> uses a disallowed location <%v>, allowed locations are %v", [bucketName, bucketLocation, input.parameters.locations])
          }
    
          violation[{"msg": msg}] {
              not input.parameters.locations
              bucketName := input.review.object.metadata.name
              msg := sprintf("No permitted locations provided in constraint for Cloud Storage bucket <%v>", [bucketName])
          }
    EOF
    
  2. מחילים את התבנית כדי ליצור את הקטגוריה של Cloud Storage:

    kubectl apply -f tutorial-storagebucket-location-template.yaml
    
  3. יוצרים אילוץ שמאפשר רק קטגוריות באזורים סינגפור וג'קרטה (asia-southeast1 ו-asia-southeast2). האילוץ חל על מרחב השמות שיצרתם קודם. היא לא חלה על קטגוריית Cloud Storage שמוגדרת כברירת מחדל ב-Cloud Build.

    cat << EOF > tutorial-storagebucket-location-constraint.yaml
    apiVersion: constraints.gatekeeper.sh/v1beta1
    kind: GCPStorageLocationConstraintV1
    metadata:
      name: singapore-and-jakarta-only
    spec:
      enforcementAction: deny
      match:
        kinds:
        - apiGroups:
          - storage.cnrm.cloud.google.com
          kinds:
          - StorageBucket
        namespaces:
        - NAMESPACE
      parameters:
        locations:
        - asia-southeast1
        - asia-southeast2
        exemptions:
        - ${GOOGLE_CLOUD_PROJECT}_cloudbuild
    EOF
    
  4. כדי להגביל את האזורים שבהם יכולים להתקיים מאגרי מידע, צריך להחיל את האילוץ:

    kubectl apply -f tutorial-storagebucket-location-constraint.yaml
    

אימות המדיניות

  1. יוצרים מניפסט שמייצג קטגוריה של Cloud Storage במיקום שאסור (us-west1):

    cat << EOF > tutorial-storagebucket-us-west1.yaml
    apiVersion: storage.cnrm.cloud.google.com/v1beta1
    kind: StorageBucket
    metadata:
      name: tutorial-us-west1-$GOOGLE_CLOUD_PROJECT
      namespace: NAMESPACE
    spec:
      location: us-west1
      uniformBucketLevelAccess: true
    EOF
    
  2. כדי ליצור את הקטגוריה של Cloud Storage, מפעילים את המניפסט:

    kubectl apply -f tutorial-storagebucket-us-west1.yaml
    

    הפלט אמור להיראות כך:

    Error from server ([singapore-and-jakarta-only] Cloud Storage bucket
    <tutorial-us-west1-PROJECT_ID> uses a disallowed location
    <us-west1>, allowed locations are ["asia-southeast1",
    "asia-southeast2"]): error when creating
    "tutorial-storagebucket-us-west1.yaml": admission webhook
    "validation.gatekeeper.sh" denied the request: [singapore-and-jakarta-only]
    Cloud Storage bucket <tutorial-us-west1-PROJECT_ID> uses a
    disallowed location <us-west1>, allowed locations are
    ["asia-southeast1", "asia-southeast2"]
    
  3. אופציונלי: אפשר לראות רשומה של ההחלטה לדחות את הבקשה ביומני הביקורת של Cloud. שולחים שאילתה ליומני Admin Activity של הפרויקט:

    gcloud logging read --limit=1 \
        "logName=\"projects/$GOOGLE_CLOUD_PROJECT/logs/cloudaudit.googleapis.com%2Factivity\""'
        resource.type="k8s_cluster"
        resource.labels.cluster_name="CLUSTER_NAME"
        resource.labels.location="ZONE"
        protoPayload.authenticationInfo.principalEmail!~"system:serviceaccount:cnrm-system:.*"
        protoPayload.methodName:"com.google.cloud.cnrm."
        protoPayload.status.code=7'
    

    הפלט אמור להיראות כך:

    insertId: 3c6940bb-de14-4d18-ac4d-9a6becc70828
    labels:
      authorization.k8s.io/decision: allow
      authorization.k8s.io/reason: ''
      mutation.webhook.admission.k8s.io/round_0_index_0: '{"configuration":"mutating-webhook.cnrm.cloud.google.com","webhook":"container-annotation-handler.cnrm.cloud.google.com","mutated":true}'
      mutation.webhook.admission.k8s.io/round_0_index_1: '{"configuration":"mutating-webhook.cnrm.cloud.google.com","webhook":"management-conflict-annotation-defaulter.cnrm.cloud.google.com","mutated":true}'
    logName: projects/PROJECT_ID/logs/cloudaudit.googleapis.com%2Factivity
    operation:
      first: true
      id: 3c6940bb-de14-4d18-ac4d-9a6becc70828
      last: true
      producer: k8s.io
    protoPayload:
      '@type': type.googleapis.com/google.cloud.audit.AuditLog
      authenticationInfo:
        principalEmail: user@example.com
      authorizationInfo:
      - permission: com.google.cloud.cnrm.storage.v1beta1.storagebuckets.create
        resource: storage.cnrm.cloud.google.com/v1beta1/namespaces/NAMESPACE/storagebuckets/tutorial-us-west1-PROJECT_ID
      methodName: com.google.cloud.cnrm.storage.v1beta1.storagebuckets.create
      requestMetadata:
        callerIp: 203.0.113.1
        callerSuppliedUserAgent: kubectl/v1.21.1 (linux/amd64) kubernetes/5e58841
      resourceName: storage.cnrm.cloud.google.com/v1beta1/namespaces/NAMESPACE/storagebuckets/tutorial-us-west1-PROJECT_ID
      serviceName: k8s.io
      status:
        code: 7
        message: Forbidden
    receiveTimestamp: '2021-05-21T06:56:24.940264678Z'
    resource:
      labels:
        cluster_name: CLUSTER_NAME
        location: CLUSTER_ZONE
        project_id: PROJECT_ID
      type: k8s_cluster
    timestamp: '2021-05-21T06:56:09.060635Z'

    השדה methodName מציג את הפעולה שניסו לבצע, השדה resourceName מציג את השם המלא של המשאב של Config Connector, והקטע status מציג שהבקשה נכשלה, עם קוד השגיאה 7 וההודעה Forbidden.

  4. יוצרים מניפסט שמייצג קטגוריה של Cloud Storage במיקום מותר (asia-southeast1):

    cat << EOF > tutorial-storagebucket-asia-southeast1.yaml
    apiVersion: storage.cnrm.cloud.google.com/v1beta1
    kind: StorageBucket
    metadata:
      name: tutorial-asia-southeast1-$GOOGLE_CLOUD_PROJECT
      namespace: NAMESPACE
    spec:
      location: asia-southeast1
      uniformBucketLevelAccess: true
    EOF
    
  5. כדי ליצור את הקטגוריה של Cloud Storage, מפעילים את המניפסט:

    kubectl apply -f tutorial-storagebucket-asia-southeast1.yaml
    

    הפלט אמור להיראות כך:

    storagebucket.storage.cnrm.cloud.google.com/tutorial-asia-southeast1-PROJECT_ID created
    

    הפלט כולל את PROJECT_ID, שהוא מזהה הפרויקט Google Cloud .

  6. בודקים ש-Config Connector יצר את הקטגוריה של Cloud Storage:

    gcloud storage ls | grep tutorial
    

    הפלט אמור להיראות כך:

    gs://tutorial-asia-southeast1-PROJECT_ID/
    gs://tutorial-us-central1-PROJECT_ID/
    

    אם הפלט הזה לא מופיע, מחכים דקה ומבצעים את השלב הזה שוב.

אילוצי ביקורת

ב-Policy Controller, בקרת הביקורת מעריכה מעת לעת את המשאבים בהתאם למגבלות שלהם. הבקר מזהה הפרות מדיניות במשאבים שנוצרו לפני המגבלה, ובמשאבים שנוצרו מחוץ ל-Config Connector.

  1. ב-Cloud Shell, מציגים את ההפרות של כל האילוצים שמשתמשים בתבנית האילוצים GCPStorageLocationConstraintV1:

    kubectl get gcpstoragelocationconstraintv1 -o json \
      | jq '.items[].status.violations'
    

    הפלט אמור להיראות כך:

    [
      {
        "enforcementAction": "deny",
        "kind": "StorageBucket",
        "message": "Cloud Storage bucket <tutorial-us-central1-PROJECT_ID>
        uses a disallowed location <us-central1>, allowed locations are
        \"asia-southeast1\", \"asia-southeast2\"",
        "name": "tutorial-us-central1-PROJECT_ID",
        "namespace": "NAMESPACE"
      }
    ]
    

    אתם רואים את הקטגוריה של Cloud Storage שיצרתם ב-us-central1 לפני שיצרתם את האילוץ.

אימות משאבים במהלך הפיתוח

במהלך הפיתוח וה-builds של אינטגרציה רציפה (CI), כדאי לאמת את המשאבים מול האילוצים לפני שמחילים את המשאבים האלה על אשכול GKE. האימות מספק משוב מהיר ומאפשר לכם לגלות בעיות במשאבים ובאילוצים בשלב מוקדם. בשלבים הבאים מוסבר איך לאמת משאבים באמצעות kpt. כלי שורת הפקודה kpt מאפשר לכם לנהל וליישם מניפסטים של משאבים ב-Kubernetes.

  1. ב-Cloud Shell, מריצים את gatekeeper הפונקציה KRM באמצעות kpt:

    kpt fn eval . --image=gcr.io/kpt-fn/gatekeeper:v0.2 --truncate-output=false
    

    פונקציית KRM היא תוכנית שיכולה לשנות או לאמת משאבים ב-Kubernetes שמאוחסנים במערכת הקבצים המקומית כקובצי YAML. הפונקציה gatekeeper של KRM מאמתת את משאבי הקטגוריה של Cloud Storage ב-Config Connector מול מדיניות Gatekeeper. פונקציית gatekeeper KRM ארוזה כקובץ אימג' של קונטיינר שזמין ב-Artifact Registry.

    הפונקציה מדווחת שקובצי המניפסט של קטגוריות Cloud Storage באזורים us-central1 ו-us-west1 מפרים את האילוץ.

    הפלט אמור להיראות כך:

    [RUNNING] "gcr.io/kpt-fn/gatekeeper:v0.2"
    [FAIL] "gcr.io/kpt-fn/gatekeeper:v0.2"
      Results:
        [ERROR] Cloud Storage bucket <tutorial-us-central1-PROJECT_ID> uses a disallowed location <us-central1>, allowed locations are ["asia-southeast1", "asia-southeast2"] violatedConstraint: singapore-and-jakarta-only in object "storage.cnrm.cloud.google.com/v1beta1/StorageBucket/tutorial/tutorial-us-central1-GOOGLE_CLOUD_PROJECT" in file "tutorial-storagebucket-us-central1.yaml"
        [ERROR] Cloud Storage bucket <tutorial-us-west1-PROJECT_ID> uses a disallowed location <us-west1>, allowed locations are ["asia-southeast1", "asia-southeast2"] violatedConstraint: singapore-and-jakarta-only in object "storage.cnrm.cloud.google.com/v1beta1/StorageBucket/tutorial/tutorial-us-west1-GOOGLE_CLOUD_PROJECT" in file "tutorial-storagebucket-us-west1.yaml"
      Stderr:
        "[error] storage.cnrm.cloud.google.com/v1beta1/StorageBucket/test/tutorial-us-central1-PROJECT_ID : Cloud Storage bucket <tutorial-us-central1-PROJECT_ID> uses a disallowed location <us-central1>, allowed locations are [\"asia-southeast1\", \"asia-southeast2\"]"
        "violatedConstraint: singapore-and-jakarta-only"
        ""
        "[error] storage.cnrm.cloud.google.com/v1beta1/StorageBucket/test/tutorial-us-west1-PROJECT_IDT : Cloud Storage bucket <tutorial-us-west1-PROJECT_IDgt; uses a disallowed location <us-west1>, allowed locations are [\"asia-southeast1\", \"asia-southeast2\"]"
        "violatedConstraint: singapore-and-jakarta-only"
        ""
      Exit code: 1
    

אימות משאבים שנוצרו מחוץ ל-Config Connector

אפשר לאמת Google Cloud משאבים שנוצרו מחוץ ל-Config Connector על ידי ייצוא המשאבים. אחרי שמייצאים את המשאבים, אפשר להשתמש באחת מהאפשרויות הבאות כדי להעריך את כללי Policy Controller ביחס למשאבים המיוצאים:

  • מאמתים את המשאבים באמצעות הפונקציה gatekeeper KRM.

  • מייבאים את המשאבים ל-Config Connector.

כדי לייצא את המשאבים, משתמשים במאגר משאבי ענן.

  1. ב-Cloud Shell, מפעילים את Cloud Asset API:

    gcloud services enable cloudasset.googleapis.com
    
  2. מוחקים את קובצי המניפסט של משאבי Kubernetes לקטגוריות של Cloud Storage ב-us-central1 וב-us-west1:

    rm tutorial-storagebucket-us-*.yaml
    
  3. לייצא את כל המשאבים של Cloud Storage בפרויקט הנוכחי ולשמור את הפלט בקובץ בשם export.yaml:

    gcloud beta resource-config bulk-export \
      --project $GOOGLE_CLOUD_PROJECT \
      --resource-format krm \
      --resource-types StorageBucket > export.yaml
    

    הפלט אמור להיראות כך:

    Exporting resource configurations to stdout...
    
    Export complete.
    
  4. יוצרים פייפליין kpt על ידי שרשור של פונקציות KRM. הצינור הזה מאמת את המשאבים בספרייה הנוכחית מול מדיניות המיקום של הקטגוריה של Cloud Storage:

    kpt fn source . \
      | kpt fn eval - --image=gcr.io/kpt-fn/set-namespace:v0.1 -- namespace=NAMESPACE \
      | kpt fn eval - --image=gcr.io/kpt-fn/gatekeeper:v0.2 --truncate-output=false
    

    למשאבים שמייצאים אין ערך במאפיין מטא הנתונים namespace. בצינור הזה נעשה שימוש בפונקציית KRM שנקראת set-namespace כדי להגדיר את הערך namespace של כל המשאבים.

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

    [RUNNING] "gcr.io/kpt-fn/set-namespace:v0.1"
    [PASS] "gcr.io/kpt-fn/set-namespace:v0.1"
    [RUNNING] "gcr.io/kpt-fn/gatekeeper:v0.2"
    [FAIL] "gcr.io/kpt-fn/gatekeeper:v0.2"
      Results:
        [ERROR] Cloud Storage bucket <tutorial-us-central1-PROJECT_ID> uses a disallowed location <us-central1>, allowed locations are ["asia-southeast1", "asia-southeast2"] violatedConstraint: singapore-and-jakarta-only in object "storage.cnrm.cloud.google.com/v1beta1/StorageBucket/tutorial/tutorial-us-central1-GOOGLE_CLOUD_PROJECT" in file "export.yaml"
      Stderr:
        "[error] storage.cnrm.cloud.google.com/v1beta1/StorageBucket/test/tutorial-us-central1-PROJECT_ID : Cloud Storage bucket <tutorial-us-central1-PROJECT_ID> uses a disallowed location <us-central1>, allowed locations are [\"asia-southeast1\", \"asia-southeast2\"]"
        "violatedConstraint: singapore-and-jakarta-only"
        ""
      Exit code: 1
    

    אם Google Cloud בפרויקט יש קטגוריות של Cloud Storage שיצרתם לפני שהתחלתם לעבוד על המדריך הזה, והמיקום שלהן לא עומד בדרישות המגבלה, הקטגוריות שנוצרו קודם יופיעו בפלט.

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

פתרון בעיות

אם Config Connector לא יוצר את המשאבים Google Cloud הצפויים, משתמשים בפקודה הבאה ב-Cloud Shell כדי לראות את היומנים של מנהל הבקרים של Config Connector:

kubectl logs --namespace cnrm-system --container manager \
  --selector cnrm.cloud.google.com/component=cnrm-controller-manager,cnrm.cloud.google.com/scoped-namespace=NAMESPACE

אם Policy Controller לא אוכף את כללי המדיניות בצורה נכונה, אפשר להשתמש בפקודה הבאה כדי להציג את היומנים של מנהל הבקרה:

kubectl logs deployment/gatekeeper-controller-manager \
  --namespace gatekeeper-system

אם Policy Controller לא מדווח על הפרות בשדה status של אובייקטי האילוצים, אפשר להציג את יומני הביקורת של הבקר באמצעות הפקודה הבאה:

kubectl logs deployment/gatekeeper-audit --namespace gatekeeper-system

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

הסרת המשאבים

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

מחיקת הפרויקט

  1. במסוף Google Cloud , נכנסים לדף Manage resources.

    כניסה לדף Manage resources

  2. אם הפרויקט שרוצים למחוק מחובר לארגון, מרחיבים את הרשימה Organization בעמודה Name.
  3. ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
  4. כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.

מחיקת המשאבים

אם אתם רוצים לשמור את Google Cloud הפרויקט שבו השתמשתם במדריך הזה, אתם צריכים למחוק את המשאבים בנפרד.

  1. ב-Cloud Shell, מוחקים את האילוץ על מיקום הקטגוריה של Cloud Storage:

    kubectl delete -f tutorial-storagebucket-location-constraint.yaml
    
  2. מוסיפים את ההערה cnrm.cloud.google.com/force-destroy עם ערך מחרוזת של true לכל המשאבים מסוג storagebucket במרחב השמות שמנוהל על ידי Config Connector:

    kubectl annotate storagebucket --all --namespace NAMESPACE \
      cnrm.cloud.google.com/force-destroy=true
    

    ההערה הזו היא הנחיה שמאפשרת ל-Config Connector למחוק קטגוריה של Cloud Storage כשמוחקים את משאב storagebucket התואם באשכול GKE, גם אם הקטגוריה מכילה אובייקטים.

  3. מוחקים את המשאבים של Config Connector שמייצגים את הקטגוריות של Cloud Storage:

    kubectl delete --namespace NAMESPACE storagebucket --all
    
  4. מוחקים את אשכול GKE:

    gcloud container clusters delete CLUSTER_NAME \
      --zone ZONE --async --quiet
    
  5. מוחקים את קישור המדיניות של Workload Identity ב-IAM:

    gcloud iam service-accounts remove-iam-policy-binding \
      SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \
      --member "serviceAccount:$GOOGLE_CLOUD_PROJECT.svc.id.goog[cnrm-system/cnrm-controller-manager-NAMESPACE]" \
      --role roles/iam.workloadIdentityUser
    
  6. מוחקים את קישור התפקיד 'אדמין של Cloud Storage' לחשבון השירות של Google:

    gcloud projects remove-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
      --member "serviceAccount:SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \
      --role roles/storage.admin
    
  7. מוחקים את חשבון השירות ב-Google שיצרתם בשביל Config Connector:

    gcloud iam service-accounts delete --quiet \
      SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
    

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