GKE上KubernetesPodOperator权限问题:403认证范围不足
环境与场景
- 部署环境:GCP Kubernetes集群,通过Helm部署Airflow 2.5.3
- 执行逻辑:DAG使用
KubernetesPodOperator启动Docker镜像,镜像内Python脚本通过以下代码访问Secret Manager:
client = secretmanager.SecretManagerServiceClient() response = client.access_secret_version(request={ "name": client.secret_version_path(PROJECT_ID, SECRET_ID, VERSION)})
- 对比情况:此前使用
DockerOperator搭配LocalExecutor可正常运行该脚本,切换到Kubernetes集群后报错。
错误信息
[2023-06-09, 00:33:54 UTC] {pod_manager.py:235} INFO - PermissionDenied: 403 Request had insufficient authentication scopes. [reason: "ACCESS_TOKEN_SCOPE_INSUFFICIENT"
[2023-06-09, 00:33:54 UTC] {pod_manager.py:235} INFO - domain: "googleapis.com"
[2023-06-09, 00:33:54 UTC] {pod_manager.py:235} INFO - metadata {
[2023-06-09, 00:33:54 UTC] {pod_manager.py:235} INFO - key: "service"
[2023-06-09, 00:33:54 UTC] {pod_manager.py:235} INFO - value: "secretmanager.googleapis.com"
[2023-06-09, 00:33:54 UTC] {pod_manager.py:235} INFO - }
[2023-06-09, 00:33:54 UTC] {pod_manager.py:235} INFO - metadata {
[2023-06-09, 00:33:54 UTC] {pod_manager.py:235} INFO - key: "method"
[2023-06-09, 00:33:54 UTC] {pod_manager.py:235} INFO - value: "google.cloud.secretmanager.v1.SecretManagerService.AccessSecretVersion"
[2023-06-09, 00:33:54 UTC] {pod_manager.py:235} INFO - }
[2023-06-09, 00:33:54 UTC] {pod_manager.py:235} INFO - ]
已做检查
- 服务账号已授予
Secret Manager Secret Accessor角色 - Airflow WebUI配置了Google连接,将私钥内容粘贴到Keyfile json字段,但输入乱码私钥仍报相同错误,怀疑Airflow未识别该配置
解决建议
1. 显式配置KubernetesPodOperator的服务账号
KubernetesPodOperator默认使用Airflow Worker的服务账号,若需指定集群内绑定GCP权限的服务账号,需显式配置:
KubernetesPodOperator( # 其他必填参数 service_account_name="你的K8s服务账号名称", # 若使用GKE工作负载身份,添加注释绑定GCP服务账号 annotations={"iam.gke.io/gcp-service-account": "你的GCP服务账号邮箱"}, )
注意:需确保K8s服务账号已通过gcloud iam service-accounts add-iam-policy-binding命令绑定到对应的GCP服务账号。
2. 检查Pod/节点的OAuth2权限范围
错误提示为权限范围不足,需确保Pod或所在节点池包含Secret Manager的访问范围:
- 节点池级别:检查节点池是否包含
https://www.googleapis.com/auth/cloud-platform(全权限)或https://www.googleapis.com/auth/secretmanager.readonly(只读权限) - Pod级别:在KubernetesPodOperator中通过环境变量或PodSpec配置范围,或通过Helm values.yaml统一配置Worker的默认范围:
workers: podAnnotations: iam.gke.io/gcp-service-account: "你的GCP服务账号邮箱" env: - name: GOOGLE_APPLICATION_CREDENTIALS value: "/var/secrets/google/key.json"
3. 手动传递Airflow Google连接凭据到Pod
Airflow WebUI配置的Google连接不会自动传递给KubernetesPodOperator启动的独立容器,需手动注入:
- 方式一:将Google连接的密钥存储为K8s Secret,在Pod中挂载该Secret并设置
GOOGLE_APPLICATION_CREDENTIALS环境变量指向密钥路径 - 方式二:通过脚本读取连接凭据并注入到Pod(仅用于测试,不推荐生产):
from airflow.models import Connection from airflow.utils.session import create_session def get_gcp_key(): with create_session() as session: conn = session.query(Connection).filter(Connection.conn_id == "你的GCP连接ID").first() return conn.extra_dejson["keyfile_json"] KubernetesPodOperator( # 其他参数 env_vars={ "GCP_KEYFILE_JSON": get_gcp_key() }, cmds=["bash", "-c", "echo $GCP_KEYFILE_JSON > /tmp/key.json && export GOOGLE_APPLICATION_CREDENTIALS=/tmp/key.json && python your_script.py"] )
4. 验证服务账号权限
用gcloud命令直接测试服务账号是否能访问Secret Manager,排除权限配置问题:
gcloud auth activate-service-account --key-file=你的服务账号密钥.json gcloud secrets versions access 版本号 --secret=密钥ID --project=项目ID
若测试成功,说明问题出在Airflow Pod的身份传递逻辑;若失败,重新检查服务账号的角色绑定。
5. 配置Helm的工作负载身份参数
若使用GKE工作负载身份,需在Airflow Helm values.yaml中开启相关配置:
airflow: config: AIRFLOW__KUBERNETES__WORKLOAD_IDENTITY: "true" AIRFLOW__KUBERNETES__GCP_SERVICE_ACCOUNT: "你的GCP服务账号邮箱"
内容的提问来源于stack exchange,提问作者lancen

