ריבוי דיירים בין פרויקטים במילוי בקשות מסוג Knative

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

מודל הפעלה נפוץ ב-Knative serving הוא שצוות של מפתחי אפליקציות משתמש בפרויקט Google Cloud כדי לפרוס ולנהל שירותים שפועלים באשכולות GKE שונים בפרויקטים של צוותים אחריםGoogle Cloud . היכולת הזו, שנקראת multi-tenancy, מאפשרת לכם, כמפעילים של פלטפורמה, להתאים את הגישה של צוותי הפיתוח רק לשירותים שלהם שפועלים בסביבות השונות של הארגון (לדוגמה, סביבת ייצור לעומת סביבת ביניים).

מילוי בקשות מסוג Knative תומך באופן ספציפי בריבוי דיירים (multi-tenancy) בארגונים. סוג כזה של ריבוי דיירים מאפשר לפרויקט של אשכול Google Cloud לתת גישה למשאבים ספציפיים באשכול GKE שלו. Google Cloud הפרויקט שמקבל גישה לפרויקט האשכול Google Cloud הוא פרויקט הדייר Google Cloud . דיירים בפרויקט של אשכול Google Cloud יכולים להשתמש ב-Knative Serving כדי לגשת לשירותים ולמשאבים שהם קיבלו גישה אליהם, להפעיל אותם ולהיות הבעלים שלהם.

באופן עקרוני, יש ארבעה שלבים להגדרת ריבוי דיירים בארגון באמצעות Knative serving:

  1. מגדירים את הגישה לדייר לפרויקט Google Cloud האשכול באמצעות קבוצת Google וניהול זהויות והרשאות גישה.
  2. ממפים כל פרויקט של דייר Google Cloud לפרויקט של האשכול Google Cloud .
  3. ניתוב נתוני היומן של פרויקט Google Cloud האשכול לפרויקטים Google Cloud של הדייר באמצעות מאגרי יומנים ויעדים.
  4. הגדרת הרשאות לאשכול לדיירים באמצעות בקרת גישה מבוססת-תפקידים.

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

מפעיל הפלטפורמה שאחראי להגדרת ריבוי דיירים צריך להבין את הדרישות הבאות ולעמוד בהן:

הגדרה של משתני סביבה מקומיים

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

  1. מחליפים את YOUR_CLUSTER_PROJECT_ID במזהה של פרויקט Google Cloud האשכול ומריצים את הפקודה הבאה:

    export CLUSTER_PROJECT_ID=YOUR_CLUSTER_PROJECT_ID
    
  2. מחליפים את YOUR_TENANT_PROJECT_ID במזהה של פרויקט הדייר Google Cloud ומריצים את הפקודה הבאה:

    export TENANT_PROJECT_ID=$YOUR_TENANT_PROJECT_ID
    
  3. מריצים את הפקודות הבאות כדי לוודא שמשתני הסביבה המקומיים תקינים:

    echo "cluster Google Cloud project is:" $CLUSTER_PROJECT_ID
    echo "tenant Google Cloud project is:" $TENANT_PROJECT_ID
    

מזהה הפרויקט של האשכול Google Cloud ומזהה הפרויקט של הדייר Google Cloud משמשים עכשיו בכל הפקודות הבאות שבהן מצוינים $CLUSTER_PROJECT_ID ו-$TENANT_PROJECT_ID.

אימות הרשאות IAM

מריצים את הפקודות הבאות של testIamPermissions כדי לוודא שיש לכם את הרשאות ה-IAM הנדרשות לגישה למשאבים בפרויקט של אשכול Google Cloud וגם בפרויקטים של הדייר Google Cloud .

מריצים את הפקודה הבאה כדי לאמת את ההרשאות שלכם בפרויקט Google Cloud של האשכול:

curl -X POST \
  -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
  --header "Content-Type: application/json" \
  --data '{"permissions":["logging.sinks.create", "logging.sinks.get", "resourcemanager.projects.setIamPolicy"]}' \
  https://cloudresourcemanager.googleapis.com/v1/projects/$CLUSTER_PROJECT_ID:testIamPermissions

תוצאות צפויות עבור פרויקט האשכול Google Cloud :

{
  "permissions": [
    "logging.sinks.create",
    "logging.sinks.get",
    "resourcemanager.projects.setIamPolicy"
  ]
}

מריצים את הפקודה הבאה כדי לאמת את ההרשאות בכל פרויקט של דייר Google Cloud :

curl -X POST \
  -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
  --header "Content-Type: application/json" \
  --data '{"permissions":["logging.buckets.create", "logging.buckets.get", "resourcemanager.projects.setIamPolicy", "resourcesettings.settingvalues.create", "serviceusage.services.enable"]}' \
  https://cloudresourcemanager.googleapis.com/v1/projects/$TENANT_PROJECT_ID:testIamPermissions

תוצאות צפויות לכל פרויקט של דייר: Google Cloud

{
  "permissions": [
    "logging.buckets.create",
    "logging.buckets.get",
    "resourcemanager.projects.setIamPolicy",
    "resourcesettings.settingvalues.create",
    "serviceusage.services.enable",
  ]
}

שימוש בקבוצת Google ובניהול זהויות והרשאות גישה (IAM) כדי להגדיר גישה לדייר

משתמשים בקבוצת Google כדי לאפשר לדיירים לגשת לאשכול GKE. הרשאות ה-IAM נותנות לדיירים את ההרשאות לקבל אישורים, אבל הם לא יוכלו לעשות שום דבר באשכול עד שיוגדר ב-Kubernetes בקרת גישה מבוססת-תפקידים בשלב מאוחר יותר.

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

יוצרים את משתנה הסביבה המקומי הבא לקבוצת Google:

export SECURITY_GROUP=gke-security-groups@company.com

Kubernetes Cluster Viewer

מריצים את הפקודות הבאות כדי לאפשר לדיירים לקבל פרטי כניסה לאשכול. הפקודות האלה לא מאפשרות לדיירים לקרוא או לשנות משאבים באשכול GKE.

חומרי עזר בנושא IAM

gcloud projects add-iam-policy-binding $CLUSTER_PROJECT_ID \
   --member=group:$SECURITY_GROUP \
   --role='roles/container.clusterViewer' \
   --condition=None

כדי להגביל את הגישה לאשכול ספציפי, אפשר להשתמש בתנאי IAM.

gcloud projects add-iam-policy-binding $CLUSTER_PROJECT_ID \
   --member=group:$SECURITY_GROUP \
   --role='roles/container.clusterViewer' \
   --condition="expression=resource.name == 'cluster-name',title=Restrict cluster access"

כלי לצפייה בניטור

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

הפניה לתפקידי מעקב

gcloud projects add-iam-policy-binding $CLUSTER_PROJECT_ID \
   --member=group:$SECURITY_GROUP \
   --role='roles/monitoring.viewer' \
   --condition=None

מיפוי של כל פרויקט של דייר Google Cloud לפרויקט של האשכול Google Cloud

אתם משתמשים בערכי הגדרות משאבים כדי למפות פרויקטים של דיירים Google Cloud לפרויקט של אשכול Google Cloud .

אפשר להגדיר את הגדרת המשאב לכל פרויקט של דייר Google Cloud בנפרד, או להגדיר אותה בכל רמה בהיררכיית התיקיות. קל יותר להגדיר את זה ברמת התיקייה של דייר יחיד, אבל גמיש יותר להגדיר את זה ברמת כל פרויקט דייר (tenant). אחרי ההגדרה, בכל פעם שדיירים יגלשו בממשק המשתמש של Knative serving, הם יוכלו לראות את השירותים שלהם גם בפרויקט Google Cloud של האשכול. הפעולה הזו לא משנה את הרשאות ה-IAM בפרויקט של אשכול Google Cloud או באשכולות GKE, אלא רק ממפה מפרויקט דייר (tenant) (או תיקייה) לפרויקט של אשכול Google Cloud .

  1. מפעילים את resourcesettings API בפרויקט של הדייר Google Cloud .

    gcloud services enable resourcesettings.googleapis.com \
      --project=$TENANT_PROJECT_ID
    
  2. מריצים את הפקודה הבאה כדי להוסיף את ההרשאות של Organization Admin (roles/resourcesettings.admin) למזהה המשתמש:

    gcloud organizations add-iam-policy-binding YOUR_ORGANIZATION_ID \
      --member=YOUR_ADMIN_MEMBER_ID \
      --role='roles/resourcesettings.admin'
    

    מחליפים את YOUR_ORGANIZATION_ID במזהה הארגון ואת YOUR_ADMIN_MEMBER_ID במזהה המשתמש, לדוגמה user:my-email@my-domain.com.

  3. בוחרים אחת מהשיטות הבאות כדי להגדיר את המיפוי.

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

פרויקטים של דיירים (tenants)

מגדירים את ערך הגדרת המשאב לכל פרויקט Google Cloud בדייר:

  1. מקבלים את name של פרויקט הדייר Google Cloud ומגדירים אותו כמשתנה בסביבה מקומית:
    export TENANT_PROJECT_NUMBER=$(gcloud projects describe $TENANT_PROJECT_ID --format="value(projectNumber)")
  2. יוצרים קובץ ערכי הגדרות משאבים כדי להגדיר את המיפוי מפרויקט הדייר [ Google Cloud ] לפרויקט האשכול [ Google Cloud ]. אפשר להגדיר בקובץ הזה כמה מזהי פרויקטים של אשכולות Google Cloud ולהוסיף אותם לפרויקט אחד של דייר Google Cloud .
    cat > value-file.json << EOF
    {
    "name": "projects/$TENANT_PROJECT_NUMBER/settings/cloudrun-multiTenancy/value",
    "value": {
      "stringSetValue": {
        "values": [ "projects/$CLUSTER_PROJECT_ID" ]
      }
    }
    }
    EOF
  3. פורסים את הגדרות המשאב בפרויקט Google Cloud של הדייר:
    gcloud resource-settings set-value cloudrun-multiTenancy --value-file value-file.json --project $TENANT_PROJECT_ID

תיקיות של דיירים

הגדרת ערך של הגדרת משאב בתיקיית דייר ראשית כדי להגדיר את הערך הזה לכל הפרויקטים והתיקיות של דייר הצאצא: Google Cloud

  1. מקבלים את number של תיקיית הדייר ומגדירים אותו כמשתנה סביבה מקומי:
    export TENANT_FOLDER_NUMBER=$TENANT_FOLDER_NUMBER
  2. יוצרים קובץ של ערכי הגדרות משאבים כדי להגדיר את המיפוי מתיקיית הדייר לפרויקט של אשכול Google Cloud . אפשר להגדיר בקובץ הזה כמה מזהי פרויקטים של אשכולות Google Cloud ולהוסיף אותם לתיקייה אחת של דייר.
    cat > value-file.json << EOF
    {
    "name": "folders/$TENANT_FOLDER_NUMBER/settings/cloudrun-multiTenancy/value",
    "value": {
      "stringSetValue": {
        "values": [ "projects/$CLUSTER_PROJECT_ID" ]
      }
    }
    }
    EOF
  3. פורסים את הגדרות המשאב בתיקיית הדייר:
    gcloud resource-settings set-value cloudrun-multiTenancy --value-file value-file.json --folder $TENANT_FOLDER_NUMBER

הגדרת דליים ומאגרי יומנים לניתוב נתוני יומנים

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

יוצרים את משתני הסביבה המקומיים הבאים:

  • מציינים את מרחב השמות של אשכול GKE שהדיירים ניגשים אליו.
  • השם של יעד הנתונים. כדי לפשט את השלב הזה, השם הוא שילוב של משתני הסביבה המקומיים של הפרויקט Google Cloud cluster ושל הפרויקט Google Cloud tenant שיצרתם קודם. אפשר לשנות את הערך הזה.
export NAMESPACE=$NAMESPACE
export SINK_NAME=$CLUSTER_PROJECT_ID-$TENANT_PROJECT_ID

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

gcloud logging buckets \
   create $CLUSTER_PROJECT_ID \
   --location=global \
   --project=$TENANT_PROJECT_ID

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

gcloud logging sinks \
   create $SINK_NAME \
   logging.googleapis.com/projects/$TENANT_PROJECT_ID/locations/global/buckets/$CLUSTER_PROJECT_ID \
   --log-filter=resource.labels.namespace_name=$NAMESPACE \
   --project $CLUSTER_PROJECT_ID

מריצים את הפקודות הבאות כדי להוסיף את ההרשאה מחשבון השירות של sink ביומן אל הקטגוריה שיצרתם.

export SINK_SERVICE_ACCOUNT=$(gcloud logging sinks \
   describe $SINK_NAME \
   --project $CLUSTER_PROJECT_ID \
   --format="value(writerIdentity)")
gcloud projects add-iam-policy-binding $TENANT_PROJECT_ID \
   --member=$SINK_SERVICE_ACCOUNT \
   --role='roles/logging.bucketWriter' \
   --condition="expression=resource.name.endsWith\
   (\"locations/global/buckets/$CLUSTER_PROJECT_ID\"),\
   title=Log bucket writer from $CLUSTER_PROJECT_ID"

הגדרת הרשאות דייר באמצעות בקרת גישה מבוססת-תפקידים (RBAC)

בעבר השתמשתם בקבוצות Google וב-IAM כדי להגדיר הרשאות שיאפשרו לדיירים לגשת ל Google Cloud פרויקט של אשכול GKE. כדי לאפשר לדיירים גישה למשאבים באשכול GKE, צריך להגדיר הרשאות באמצעות Kubernetes RBAC.

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

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

תפקידים בממשק המשתמש

התפקיד הזה מאפשר לדיירים לשלוח שאילתות לכל מרחבי השמות. ההרשאה הזו נדרשת כדי לגלות לאילו מרחבי שמות יש למשתמשים גישה ליצירת שירותים של /sdk/gcloud/reference/logging/sinks/create.

kubectl create clusterrole \
   namespace-lister \
   --verb=list \
   --resource=namespaces

התפקיד הזה מאפשר לדיירים לצפות בשירותי Knative serving. הפעולה הזו נדרשת כדי לרשום את השירותים בממשק המשתמש של Knative serving.

kubectl create clusterrole \
   ksvc-lister \
   --verb=list \
   --resource=services.serving.knative.dev

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

נדרשת רק אחת מההרשאות האלה. ההרשאה הראשונה מאפשרת לדיירים לשנות כל משאב במרחב השמות שלהם. ההרשאה השנייה מאפשרת ליצור רק שירותים של Knative serving.

kubectl create clusterrole \
   kubernetes-developer \
   --verb="*" \
   --resource="*.*"

אם ההרשאה kubernetes-developer רחבה מדי, ההרשאה הבאה מאפשרת לדיירים ליצור שירותי Knative במרחבי השמות שלהם ולצפות במשאבי Knative אחרים.

cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: knative-developer
rules:
- apiGroups: ["serving.knative.dev"]
  resources: ["services"]
  verbs: ["*"]
- apiGroups: ["serving.knative.dev"]
  resources: ["*"]
  verbs: ["get", "list", "watch"]
EOF

יוצרים מרחב שמות של דייר ומקצים הרשאות.

הערה: ההנחה היא שההגדרה בוצעה באמצעות קבוצות Google ל-GKE. צריך לעשות את זה לכל דייר.

export TENANT_GROUP=tenant-a@company.com

הקבוצה TENANT_GROUP צריכה להיות חלק מהקבוצה SECURITY_GROUP

אפשרות לראות את כל מרחבי השמות

כדי לשלוח שאילתה לאשכול GKE, לכל הדיירים צריכה להיות אפשרות להציג את מרחבי השמות. אין כרגע פקודה auth can-i שמחזירה מרחבי שמות שאפשר לבצע בהם פעולה. הפתרון היחיד הוא לפרט את מרחבי השמות ואז לשלוח שאילתה לכל מרחב שמות בנפרד.

kubectl create clusterrolebinding \
   all-namespace-listers \
   --clusterrole=namespace-lister \
   --group=$TENANT_GROUP

יכולת להציג רשימה של שירותים למילוי בקשות מסוג Knative

kubectl create clusterrolebinding \
   all-ksvc-listers \
   --clusterrole=ksvc-lister \
   --group=$TENANT_GROUP

יכולת לשנות משאבים במרחב השמות

קודם יוצרים את מרחב השמות:

kubectl create namespace $NAMESPACE

אם משתמשים בתפקיד kubernetes-developer:

kubectl create rolebinding \
   kubernetes-developer \
   --namespace=$NAMESPACE \
   --clusterrole=kubernetes-developer \
   --group=$TENANT_GROUP

אם משתמשים בתפקיד knative-developer:

kubectl create rolebinding \
   kubernetes-developer \
   --namespace=$NAMESPACE \
   --clusterrole=knative-developer \
   --group=$TENANT_GROUP

הוספת אפשרות לדייר לגשת לכתובת IP חיצונית

cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: ingress-reader
rules:
- apiGroups: [""]
  resources: ["services"]
  verbs: ["get"]
EOF
kubectl create rolebinding \
   ingress-reader-$TENANT_GROUP \
   --namespace=istio-system \
   --clusterrole=ingress-reader \
   --group=$TENANT_GROUP

אימות

כדי לוודא שהגדרתם בהצלחה ריבוי דיירים בארגון, פותחים את פרויקט הדייר Google Cloud ב-Knative serving ומבצעים פריסה של שירות לאשכול GKE.

מעבר אל Knative serving

הצלחתם! עכשיו הדייר יכול לקיים אינטראקציה עם השירותים והמשאבים במרחב השמות של אשכול GKE, שקיבל גישה אליהם.

הפניה ל-Multi-tenancy