服务帐号无法与另一个项目中的 GKE 集群交互

时间:2021-07-01 02:22:29

标签: kubernetes google-cloud-platform google-kubernetes-engine service-accounts google-iam

来自一个 Google Cloud Platform (GCP) 项目 ($SERVICE_ACCOUNT_A) 的服务帐户 ($PROJECT_A) 无法与 Google Kubernetes Engine (GKE) 集群交互( $GKE_CLUSTER_B) 在另一个 GCP 项目 ($PROJECT_B) 中;其中:

  • $PROJECT_A$SERVICE_ACCOUNT_A 所在项目的名称
  • $SERVICE_ACCOUNT_A 的形式为 some-name@some-project-name@.iam.gserviceaccount.com
  • $PROJECT_B$GKE_CLUSTER_B 集群所在项目的名称
  • $GKE_CLUSTER_B 是 GKE 集群名称,不是上下文,格式为:some_cluster

$SERVICE_ACCOUNT_A 无法与 $GKE_CLUSTER_B 尽管 拥有来自 $PROJECT_B 的角色进行交互,该角色包含应该允许它这样做的权限。

即,首先我创建了一个自定义角色$ROLE

gcloud iam roles create $ROLE \
--description="$ROLE_DESCRIPTION" \
--permissions=container.clusters.get,container.clusters.list \
--project=$PROJECT_B \
--title='$ROLE_TITLE'

#=>

Created role [$ROLE].
description: $ROLE_DESCRIPTION
etag: . . .
includedPermissions:
- container.clusters.get
- container.clusters.list
name: projects/$PROJECT_B/roles/$ROLE
stage: . . .
title: $ROLE_TITLE

然后我将来自 $ROLE$PROJECT_B$SERVICE_ACCOUNT_A 相关联:

gcloud projects add-iam-policy-binding $PROJECT_B \
--member=serviceAccount:$SERVICE_ACCOUNT_A \
--role=projects/$PROJECT_B/roles/$ROLE

#=>

Updated IAM policy for project [$PROJECT_B].
auditConfigs:
. . .

并且我能够在 $ROLE 下看到 $SERVICE_ACCOUNT_A

gcloud projects get-iam-policy $PROJECT_B \
--flatten='bindings[].members' \
--format='value(bindings.role)' \
--filter="bindings.members:${SERVICE_ACCOUNT_A}"

#=>

projects/$PROJECT_B/roles/$ROLE

具有适当的权限:

gcloud iam roles describe $ROLE \
--flatten='includedPermissions' \
--format='value(includedPermissions)' \
--project=$PROJECT_B

#=>

container.clusters.get
container.clusters.list

但仍然无法让$SERVICE_ACCOUNT_A$GKE_CLUSTER_B互动。

为什么?

1 个答案:

答案 0 :(得分:0)

您需要为 $PROJECT_A 启用 Kubernetes Engine API(找到 here),即使 $PROJECT_A 没有或不需要 GKE 集群。

您可以通过为 $SERVICE_ACCOUNT_A 创建新的 JSON 密钥来确认这一点:

gcloud iam service-accounts keys create \
./some-key.json \
--iam-account="${SERVICE_ACCOUNT_A}" \
--key-file-type="json"

#=>

created key [$KEY_ID] of type [json] as [./some-key.json] for [$SERVICE_ACCOUNT_A]

激活服务帐号:

gcloud auth activate-service-account \
"${SERVICE_ACCOUNT_A}" \
--key-file=./some-key.json

#=>

Activated service account credentials for: [$SERVICE_ACCOUNT_A]

确认它处于活动状态:

cloud auth list
                        Credentialed Accounts
ACTIVE  ACCOUNT
        . . .
*       $SERVICE_ACCOUNT_A
        your@account.user
        . . .

To set the active account, run:
    $ gcloud config set account `ACCOUNT`

并尝试与$GKE_CLUSTER_B互动:

gcloud container clusters list --project=$PROJECT_B

#=>

ERROR: (gcloud.container.clusters.list) ResponseError: code=403, message=Kubernetes Engine API has not
been used in project $PROJECT_A_ID before or it is disabled. Enable it by visiting
https://console.developers.google.com/apis/api/container.googleapis.com/overview?project=$PROJECT_A_ID
then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our
systems and retry.

其中 $PROJECT_A_ID 是以下形式的数字 ID:xxxxxxxxxxxxx

访问与上面的 403 一起返回的地址 (here) 并启用 Kubernetes Engine API。 $SERVICE_ACCOUNT_A 应该现在能够与 $PROJECT_B 内的 GKE 集群交互:

gcloud container clusters list \
--project=$PROJECT_B \
--format='value(name)

#=>

. . .
some_cluster
. . .

包括$GKE_CLUSTER_B