You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GKE Autopilot Pod向GCP Pub/Sub发布消息时遇权限错误

GKE Autopilot 工作负载身份配置后 Pub/Sub 发布权限被拒问题

我在GKE Autopilot集群中部署了一个向GCP Pub/Sub主题发布测试消息的服务,已完成以下配置:

  • 创建了Kubernetes服务账号(KSA)
  • 通过工作负载身份管理授权KSA扮演GCP服务账号(GSA)
  • 为GSA分配了Pub/Sub编辑器角色

执行的命令如下:

kubectl create serviceaccount KSA_NAME
gcloud iam service-accounts add-iam-policy-binding GSA_NAME@PROJECT_ID.iam.gserviceaccount.com \
    --role roles/iam.workloadIdentityUser \
    --member "serviceAccount:PROJECT_ID.svc.id.goog[KSA_NAME]"

但调用服务发布消息时,收到权限拒绝错误:

ERROR:google.cloud.pubsub_v1.publisher._batch.thread:Failed to publish 1 messages.
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/google/api_core/grpc_helpers.py", line 65, in error_remapped_callable
    return callable_(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/grpc/_channel.py", line 946, in __call__
    return _end_unary_response_blocking(state, call, False, None)
  File "/usr/local/lib/python3.7/site-packages/grpc/_channel.py", line 849, in _end_unary_response_blocking
    raise _InactiveRpcError(state)
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
        status = StatusCode.PERMISSION_DENIED
        details = "User not authorized to perform this action."
        debug_error_string = "UNKNOWN:Error received from peer ipv4:142.250.192.42:443 {grpc_message:"User not authorized to perform this action.", grpc_status:7, created_time:"2022-11-01T10:27:21.972013149+00:00"}"
>

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/google/cloud/pubsub_v1/publisher/_batch/thread.py", line 272, in _commit
    timeout=self._commit_timeout,
  File "/usr/local/lib/python3.7/site-packages/google/pubsub_v1/services/publisher/client.py", line 613, in publish
    response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
  File "/usr/local/lib/python3.7/site-packages/google/api_core/gapic_v1/method.py", line 154, in __call__
    return wrapped_func(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/google/api_core/retry.py", line 288, in retry_wrapped_func
    on_error=on_error,
  File "/usr/local/lib/python3.7/site-packages/google/api_core/retry.py", line 190, in retry_target
    return target()
  File "/usr/local/lib/python3.7/site-packages/google/api_core/timeout.py", line 99, in func_with_timeout
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/google/api_core/grpc_helpers.py", line 67, in error_remapped_callable
    raise exceptions.from_grpc_error(exc) from exc
google.api_core.exceptions.PermissionDenied: 403 User not authorized to perform this action.

服务相关代码:

from flask import Flask, request, jsonify
app = Flask(__name__)

@app.route('/new_pub/<pages>')
def new_pubsub(pages: int):
    publish_message(pages)
    return json.dumps({'success': True}), 200, {
        'ContentType': 'application/json'}

from google.cloud import pubsub_v1
import json
def publish_message(data):
    d = {"message": data}
    publisher = pubsub_v1.PublisherClient()
    topic_path = publisher.topic_path("MY_PROJECT", "TOPIC_NAME")
    publisher.publish(topic_path, json.dumps(d).encode('utf-8'))

排查与解决步骤

1. 补全KSA与GSA的绑定配置

已完成GSA侧的权限绑定,但需在KSA上添加注解指定关联的GSA:

kubectl annotate serviceaccount KSA_NAME \
    iam.gke.io/gcp-service-account=GSA_NAME@PROJECT_ID.iam.gserviceaccount.com

2. 确认Pod关联了目标KSA

检查部署的Pod模板,确保指定了使用该KSA:

spec:
  serviceAccountName: KSA_NAME

若已部署,需重启Pod使配置生效:

kubectl rollout restart deployment YOUR_DEPLOYMENT_NAME

3. 验证GSA的Pub/Sub权限

确认GSA已正确获得Pub/Sub发布权限,可使用更细粒度的roles/pubsub.publisher角色:

gcloud projects get-iam-policy PROJECT_ID \
    --filter="bindings.members:GSA_NAME@PROJECT_ID.iam.gserviceaccount.com" \
    --format="value(bindings.role)"

若权限缺失,重新添加:

gcloud projects add-iam-policy-binding PROJECT_ID \
    --role roles/pubsub.publisher \
    --member "serviceAccount:GSA_NAME@PROJECT_ID.iam.gserviceaccount.com"

4. 检查集群工作负载身份配置

确认GKE集群已启用工作负载身份(Autopilot集群默认启用):

gcloud container clusters describe CLUSTER_NAME \
    --zone CLUSTER_ZONE \
    --format="value(workloadIdentityConfig.workloadPool)"

输出需包含PROJECT_ID.svc.id.goog,与之前命令中的命名空间匹配。

5. 核对代码中的项目与主题名称

确认代码中publisher.topic_path("MY_PROJECT", "TOPIC_NAME")的项目ID和主题名称与实际资源一致,避免因名称错误导致权限校验失败。

6. 等待权限生效

IAM权限变更可能需要数分钟才能完全同步,若刚完成配置,等待片刻后再测试。

内容的提问来源于stack exchange,提问作者Prashant Sengar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 02:10:57