本指南將逐步說明如何設定 Knative Serving,允許一或多個 Google Cloud 專案執行及管理在不同 Google Cloud 專案的 GKE 叢集上執行的工作負載。
使用 Knative Serving 時,常見的運作模式是應用程式開發人員團隊使用 Google Cloud 專案,在其他團隊的Google Cloud 專案中,部署及管理在不同 GKE 叢集中執行的服務。這項功能稱為「多租戶」,可讓平台營運商調整開發團隊的存取權,只允許他們存取在貴機構各種環境 (例如正式版與預先發布版) 中執行的服務。
Knative serving 專門支援企業多租戶。這類多租戶可讓叢集 Google Cloud 專案存取 GKE 叢集的特定資源。獲准存取叢集專案的專案是 Google Cloud Google Cloud 租戶 Google Cloud 專案。叢集 Google Cloud 專案的租戶可以使用 Knative serving 存取、操作及擁有獲准存取的服務和資源。
從概念上來說,使用 Knative Serving 設定企業多租戶有四個步驟:
- 使用 Google 群組和 Identity and Access Management,設定租戶對叢集專案的存取權 Google Cloud 。
- 將每個租戶 Google Cloud 專案對應至叢集 Google Cloud 專案。
- 使用記錄檔值區和接收器,將叢集 Google Cloud 專案記錄資料傳送至租戶 Google Cloud 專案。
- 使用角色型存取權控管,為租戶定義叢集權限。
事前準備
負責設定多租戶的平台營運人員必須瞭解並滿足下列需求:
如 GKE 說明文件所述,您必須瞭解下列多租戶概念:
本文假設您要啟用多重租戶的 Google Cloud 專案已存在。
您必須能存取下列專案服務和資源: Google Cloud
租戶 Google Cloud 專案中的身分與存取權管理權限:
- roles/logging.configWriter
- Google 群組的租戶管理員
叢集 Google Cloud 專案中的 Identity and Access Management 權限:
您必須安裝最新版的 [Google Cloud CLI]](/sdk/docs/install)。
定義本機環境變數
如要簡化這個程序中使用的指令,請為叢集 Google Cloud 專案和租戶 Google Cloud 專案定義本機環境變數:
將
YOUR_CLUSTER_PROJECT_ID
替換為叢集專案的 ID,然後執行下列指令: Google Cloudexport CLUSTER_PROJECT_ID=YOUR_CLUSTER_PROJECT_ID
將
YOUR_TENANT_PROJECT_ID
替換為租戶專案的 ID,然後執行下列指令: Google Cloudexport TENANT_PROJECT_ID=$YOUR_TENANT_PROJECT_ID
執行下列指令,確認本機環境變數:
echo "cluster Google Cloud project is:" $CLUSTER_PROJECT_ID echo "tenant Google Cloud project is:" $TENANT_PROJECT_ID
現在,所有指定 $CLUSTER_PROJECT_ID
和 $TENANT_PROJECT_ID
的下列指令都會使用叢集 Google Cloud 專案 ID 和租戶 Google Cloud 專案 ID。
驗證身分與存取權管理權限
執行下列 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 群組和 Identity and Access Management 設定房客存取權
使用 Google 群組,允許房客存取 GKE 叢集。 IAM 權限可讓租戶取得憑證,但必須在後續步驟中設定 Kubernetes 角色式存取控管,租戶才能在叢集中執行任何操作。
您必須建立包含所有房客 Google Cloud 專案使用者的 Google 群組。 如要進一步瞭解如何使用安全性群組,請參閱「使用 Google 群組管理 GKE」。
為 Google 群組建立下列本機環境變數:
export SECURITY_GROUP=gke-security-groups@company.com
Kubernetes 叢集檢視者
執行下列指令,允許租戶取得叢集的憑證,但這不會允許租戶讀取或操控 GKE 叢集上的任何資源。
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 專案設定資源,也可以在資料夾階層的任何層級設定資源。在單一租戶資料夾層級設定較為簡單,但在每個租戶專案層級設定則更具彈性。設定完成後,房客瀏覽 Knative Serving UI 時,也會在叢集 Google Cloud 專案中看到自己的服務。這不會變更叢集 Google Cloud 專案或 GKE 叢集的 IAM 權限,只會將租戶專案 (或資料夾) 對應至叢集 Google Cloud 專案。
在租戶 Google Cloud 專案中啟用
resourcesettings
API。gcloud services enable resourcesettings.googleapis.com \ --project=$TENANT_PROJECT_ID
執行下列指令,將機構管理員權限 (
roles/resourcesettings.admin
) 新增至使用者 ID:gcloud organizations add-iam-policy-binding YOUR_ORGANIZATION_ID \ --member=YOUR_ADMIN_MEMBER_ID \ --role='roles/resourcesettings.admin'
將
YOUR_ORGANIZATION_ID
替換為機構 ID,並將YOUR_ADMIN_MEMBER_ID
替換為使用者 ID,例如user:my-email@my-domain.com
。選擇下列其中一種方法來定義對應。
如果所有子項 Google Cloud 專案和 Google Cloud 資料夾都使用相同的值,您可以在上層 Google Cloud 資料夾中設定資源設定值。
用戶群專案
為每個租戶 Google Cloud 專案設定資源設定值:
- 取得租戶
name
專案的 Google Cloud ,並將其設為本機環境變數:export TENANT_PROJECT_NUMBER=$(gcloud projects describe $TENANT_PROJECT_ID --format="value(projectNumber)")
- 建立資源設定值檔案,定義從租戶 Google Cloud 專案到叢集 Google Cloud 專案的對應關係。您可以在這個檔案中定義多個叢集 Google Cloud 專案 ID,並新增至單一租戶 Google Cloud 專案。
cat > value-file.json << EOF { "name": "projects/$TENANT_PROJECT_NUMBER/settings/cloudrun-multiTenancy/value", "value": { "stringSetValue": { "values": [ "projects/$CLUSTER_PROJECT_ID" ] } } } EOF
- 將資源設定部署至租戶 Google Cloud 專案:
gcloud resource-settings set-value cloudrun-multiTenancy --value-file value-file.json --project $TENANT_PROJECT_ID
租戶資料夾
為父項租戶資料夾設定資源設定值,將該值設定給所有子項租戶 Google Cloud 專案和資料夾:
- 取得租戶資料夾的
number
,並將其設為本機環境變數:export TENANT_FOLDER_NUMBER=$TENANT_FOLDER_NUMBER
- 建立資源設定值檔案,定義從租戶資料夾到叢集 Google Cloud 專案的對應關係。您可以在這個檔案中定義多個叢集 Google Cloud 專案 ID,並新增至單一租戶資料夾。
cat > value-file.json << EOF { "name": "folders/$TENANT_FOLDER_NUMBER/settings/cloudrun-multiTenancy/value", "value": { "stringSetValue": { "values": [ "projects/$CLUSTER_PROJECT_ID" ] } } } EOF
- 將資源設定部署至租戶資料夾:
gcloud resource-settings set-value cloudrun-multiTenancy --value-file value-file.json --folder $TENANT_FOLDER_NUMBER
設定記錄檔 bucket 和接收器,以轉送記錄資料
為每個租戶建立記錄值區、接收器和權限,將叢集 Google Cloud 專案記錄資料傳送至租戶 Google Cloud 專案。在下列步驟中,叢集 Google Cloud 專案中命名空間的所有記錄檔都會傳送至該值區。如要進一步瞭解如何限制共用的記錄,請參閱下方的設定。
建立下列本機環境變數:
- 指定租戶可存取的 GKE 叢集命名空間。
- 接收器的名稱。為簡化這個步驟,名稱會結合您先前建立的叢集 Google Cloud 專案和租戶 Google Cloud 專案本機環境變數。您可以修改這個值。
export NAMESPACE=$NAMESPACE
export SINK_NAME=$CLUSTER_PROJECT_ID-$TENANT_PROJECT_ID
執行下列指令,在租戶專案中建立記錄 bucket。請注意,記錄值區名稱必須是叢集專案的 ID Google Cloud ,且無法變更或修改。
gcloud logging buckets \
create $CLUSTER_PROJECT_ID \
--location=global \
--project=$TENANT_PROJECT_ID
執行下列指令,從叢集 Google Cloud 專案的指定命名空間建立接收器,傳送至租戶 Google Cloud 專案 bucket。請注意,您可以縮小記錄的範圍,例如定義其他 log-filter
值,只分享個別 GKE 叢集或特定 Knative 服務資源。
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
執行下列指令,將記錄接收器服務帳戶的權限新增至您建立的值區。
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 設定權限,允許租戶存取 GKE 叢集的 Google Cloud 專案。如要允許租戶存取 GKE 叢集內的資源,您必須使用 Kubernetes RBAC 定義權限。
建立叢集角色
定義並建立下列叢集角色後,日後即可繼續使用這些角色,新增叢集 Google Cloud 專案的所有後續租戶。
UI 角色
這個角色可讓租戶查詢所有命名空間。這是必要步驟,因為您需要找出使用者有權建立 /sdk/gcloud/reference/logging/sinks/create
服務的命名空間。
kubectl create clusterrole \
namespace-lister \
--verb=list \
--resource=namespaces
這個角色可讓房客查看 Knative serving 服務。這是列出 Knative serving UI 中服務的必要條件。
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
建立租戶命名空間並指派權限。
請注意,這項假設的前提是您已使用 GKE 的 Google 網路論壇完成設定。每個租戶都必須執行這項操作。
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 serving 服務
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
驗證
如要確認是否已成功設定企業多租戶,請在 Knative Serving 中開啟租戶 Google Cloud 專案,並將服務部署至 GKE 叢集。
恭喜!現在租戶可以與已獲授權的 GKE 叢集命名空間內服務和資源互動。