如何为服务账号授予GCP项目中单个Kubernetes集群权限?
核心原因
你之前的尝试失败,是因为**roles/container.developer包含的Kubernetes资源操作权限(如创建命名空间),其权限检查的对象不是GCP层面的Cluster资源,而是Kubernetes集群内部的资源**。GCP IAM条件只能控制对GCP资源(如集群本身)的访问,无法直接限制Kubernetes内部资源的操作权限。同时你之前的条件语法有误:正确的资源类型是单数container.googleapis.com/Cluster,而非复数Clusters。
正确实现方式
要实现最小权限,需要结合GCP IAM限制集群访问范围 + Kubernetes RBAC控制集群内操作权限两步完成:
第一步:通过GCP IAM限制服务账号仅能访问目标集群
给你的GCP服务账号绑定以下角色,并添加IAM条件锁定到目标集群:
roles/container.clusterViewer:用于获取集群kubeconfig信息roles/container.developer:允许调用目标集群的Kubernetes API
IAM条件配置(替换占位符为你的实际信息):
resource.type == "container.googleapis.com/Cluster" && resource.name == "projects/<PROJECT_ID>/locations/<LOCATION>/clusters/<CLUSTER_NAME>"
也可以用通配符简化:
resource.type == "container.googleapis.com/Cluster" && resource.name.endsWith("/clusters/<CLUSTER_NAME>")
这一步确保服务账号只能访问指定的GKE集群,无法触碰项目内其他集群。
第二步:在目标集群内配置Kubernetes RBAC,细化操作权限
默认情况下roles/container.developer会授予集群的cluster-admin权限,不符合最小权限原则,需要在集群内创建自定义RBAC规则:
- 创建Kubernetes服务账号(KSA):
apiVersion: v1 kind: ServiceAccount metadata: name: github-actions-sa namespace: default
- 创建自定义ClusterRole,仅授予所需权限(示例为管理命名空间和Deployment):
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: github-actions-limited-role rules: - apiGroups: [""] resources: ["namespaces"] verbs: ["create", "delete", "get", "list", "update"] - apiGroups: ["apps"] resources: ["deployments", "statefulsets"] verbs: ["create", "delete", "get", "list", "patch", "update"]
- 将ClusterRole绑定到KSA:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: github-actions-role-binding subjects: - kind: ServiceAccount name: github-actions-sa namespace: default roleRef: kind: ClusterRole name: github-actions-limited-role apiGroup: rbac.authorization.k8s.io
- 通过工作负载身份关联GCP服务账号与KSA:
在GCP终端执行命令:
gcloud iam service-accounts add-iam-policy-binding \ <你的GCP服务账号邮箱> \ --member="serviceAccount:<PROJECT_ID>.svc.id.goog[default/github-actions-sa]" \ --role="roles/iam.workloadIdentityUser"
然后给KSA添加注释完成关联:
apiVersion: v1 kind: ServiceAccount metadata: name: github-actions-sa namespace: default annotations: iam.gke.io/gcp-service-account: <你的GCP服务账号邮箱>
最终流水线配置
在Github Actions中,使用google-github-actions/auth完成认证后,通过google-github-actions/get-gke-credentials获取目标集群的kubeconfig,此时会自动通过工作负载身份使用绑定的KSA权限执行操作,既限制了GCP层面的集群访问范围,又细化了Kubernetes内部的操作权限。
内容的提问来源于stack exchange,提问作者Alyssa

