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

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

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

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

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

  1. מגדירים את הגישה של הדייר ל Google Cloud פרויקט האשכול באמצעות קבוצת Google וניהול הזהויות והרשאות הגישה (IAM).
  2. ממפים כל פרויקט של דייר Google Cloud לפרויקט של האשכול Google Cloud .
  3. ניתוב נתוני היומן של פרויקט Google Cloud האשכול לפרויקטים Google Cloud של הדייר באמצעות מאגרי יומנים ו-sinks.
  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. מריצים את הפקודה הבאה כדי להוסיף את הרשאות האדמין בארגון (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. יוצרים קובץ ערכי הגדרות משאבים כדי להגדיר את המיפוי מפרויקט הדייר [tenant] Google Cloud לפרויקט האשכול [cluster] 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

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

לכל דייר יוצרים קטגוריית יומנים, יעד וגם הרשאות לניתוב נתוני היומנים של פרויקט אשכול 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, צריך להגדיר הרשאות באמצעות RBAC ב-Kubernetes.

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

אחרי שמגדירים ויוצרים את התפקידים הבאים באשכול, אפשר להמשיך להשתמש בהם בעתיד כדי להוסיף את כל הדיירים הבאים של פרויקט האשכול 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