我部署了一个利用 google cloud pub/sub 的 kotlin 后端应用程序。我最近使用 Cloud Run 部署了该应用程序,它运行良好,可以完全访问 Pub/Sub。 现在由于某些原因我必须使用 GKE 部署应用程序。然而现在对 Pub/Sub 的访问似乎不再起作用了。
我检查了我的 GKE 集群正在使用的服务帐户,发现它是默认帐户。因此,我向该服务帐户授予了
Pub/Sub Editor
权限。
我认为有了这个一切都应该可行。
但我仍然在日志中看到此错误消息:
com.google.api.gax.rpc.PermissionDeniedException: io.grpc.StatusRuntimeException: PERMISSION_DENIED: User not authorized to perform this action.
我错过了什么想法吗?
这可能是两件事:
最好的解决方案是使用自定义服务帐户重新创建节点池。这样,您可以在节点池级别强制执行最低权限,并且避免旧的计算引擎范围定义和限制。如果您使用工作负载身份,则可以在安全性方面更上一层楼,并在 Pod 级别强制执行最小权限。
我认为,最好解释一下特定的工作流程。 Autopilot GKE 集群默认使用 Workload Identity,无法编辑此配置参数(这肯定是好事)。
接下来,您需要使 GKE Pod 以适当的方式与 GCP 服务进行通信,这应该通过设置 Kubernetes 服务帐户、GCP 服务帐户并将它们相互连接来实现。这些是如何完成的步骤:
先决条件 - 让我们设置我们要使用的环境变量:
$ export GCP_PROJECT_ID=__YOUR_PROJECT_ID__
$ export K8S_SA=__YOUR_KUBERNETES_SERVICE_ACCOUNT_NAME__
$ export GCP_SA=__YOUR_GCP_SERVICE_ACCOUNT_FOR_K8S_NAME__
$ export K8S_NAMESPACE=__YOUR_KUBERNETES_NAMESPACE__
创建 Kubernetes 服务帐户:
kubectl create serviceaccount $K8S_SA -n $K8S_NAMESPACE
创建 GCP 服务帐户:
gcloud iam service-accounts create $GCP_SA --project=$GCP_PROJECT_ID
分配 GCP 服务帐户“Pub/Sub 编辑器”角色(这是非常基本的方法,但可以根据您的要求通过 IAM 设置更精细的权限):
gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \
--member=serviceAccount:$GCP_SA@$GCP_PROJECT_ID.iam.gserviceaccount.com \
--role=roles/pubsub.editor
Kubernetes 知道如何链接服务帐户的方式是注释,让我们注释我们的 Kubernetes 服务帐户:
kubectl annotate serviceaccount $K8S_SA -n $K8S_NAMESPACE \
iam.gke.io/gcp-service-account=$GCP_SA@$GCP_PROJECT_ID.iam.gserviceaccount.com
最后,GCP 应该知道哪个服务帐户名为 Kubernetes SA:
gcloud iam service-accounts add-iam-policy-binding \
$GCP_SA@$GCP_PROJECT_ID.iam.gserviceaccount.com \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:$GCP_PROJECT_ID.svc.id.goog[$K8S_NAMESPACE/$K8S_SA]" \
--project $GCP_PROJECT_ID
就这样,现在您的 Kubernetes 服务帐户模拟 GCP 服务帐户,您可以在部署中照常使用它:
template:
metadata:
…
spec:
automountServiceAccountToken: false
serviceAccountName: __YOUR_KUBERNETES_SERVICE_ACCOUNT_NAME__