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

使用Java客户端库创建Dataproc集群报compute.regions.get权限缺失错误

问题描述

我参照官方示例使用java-dataproc客户端库创建Dataproc集群,将官方Java示例改写为Scala版本,代码如下:

import com.google.cloud.dataproc.v1._

object CreateCluster extends App {

  val projectId = "my-project-id"
  val region = "europe-west1"
  val clusterName = "test-cluster"

  val regionEndpoint = s"$region-dataproc.googleapis.com:443"
  
  val clusterControllerSettings = ClusterControllerSettings.newBuilder()
    .setEndpoint(regionEndpoint)
    .build()

  val clusterControllerClient = ClusterControllerClient.create(clusterControllerSettings)

  val masterConfig = InstanceGroupConfig.newBuilder.setMachineTypeUri("n1-standard-2").setNumInstances(1).build
  val workerConfig = InstanceGroupConfig.newBuilder.setMachineTypeUri("n1-standard-2").setNumInstances(2).build
  val clusterConfig = ClusterConfig.newBuilder.setMasterConfig(masterConfig).setWorkerConfig(workerConfig).build

  val cluster = Cluster.newBuilder().setClusterName(clusterName).setConfig(clusterConfig).build()

  val createClusterAsyncRequest = clusterControllerClient.createClusterAsync(projectId, region, cluster)

  val createResponse: Cluster = createClusterAsyncRequest.get()

  println(s"Created cluster: ${createResponse.getClusterName}")

  clusterControllerClient.close()

}

运行代码时抛出报错:
io.grpc.StatusRuntimeException: PERMISSION_DENIED: Required 'compute.regions.get' permission for 'projects/my-project/regions/europe-west1'

我已查阅客户端库的授权说明文档,本地运行前已经执行命令配置应用默认登录凭证,确认使用的账号本身拥有所需权限:

  • 可以在Compute API参考页面成功执行对应项目、区域的regions.get请求
  • 不通过该Java/Scala客户端库时可以正常创建Dataproc集群

补充排查记录

  • 后续尝试不带--scopes参数直接执行gcloud auth application-default login配置凭证,仍然出现相同的权限报错。
  • 编写单独测试代码验证getApplicationDefault获取的凭证权限,测试代码如下:
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport
import com.google.api.client.json.gson.GsonFactory
import com.google.api.services.compute.Compute
import com.google.auth.http.HttpCredentialsAdapter
import com.google.auth.oauth2.GoogleCredentials.getApplicationDefault

object GetRegions extends App {

  val project = "my-project-id"
  val region = "europe-west1"

  val httpTransport = GoogleNetHttpTransport.newTrustedTransport
  val jsonFactory = GsonFactory.getDefaultInstance
  val httpCredentials = new HttpCredentialsAdapter(getApplicationDefault)

  val computeService =  new Compute.Builder(httpTransport, jsonFactory, httpCredentials).build

  val request = computeService.regions.get(project, region)
  val response = request.execute

  System.out.println(response) // 该代码可成功打印区域详情信息

}

该测试代码可以正常调用regions.get接口返回区域详情,但创建Dataproc集群的代码始终提示权限不足。


问题根因

该报错不是账号本身权限不足导致,是Dataproc gRPC客户端的配置问题,核心触发原因有两个:

  1. 本地应用默认凭证(ADC)没有绑定正确的配额项目,调用时权限校验的项目和代码中传入的项目ID不一致
  2. 本地网络代理配置没有被gRPC客户端识别,请求被代理拦截后返回了伪造的权限拒绝响应
修复步骤
  • 重新配置本地ADC凭证,强制指定配额项目和代码里的projectId完全一致:
    gcloud auth application-default login --project=代码中填写的项目ID实际值
    
    执行完成后清理本地旧的凭证缓存,避免加载到过期凭证文件。
  • 不要依赖客户端自动加载凭证逻辑,显式在构建配置时指定凭证和权限范围,修改clusterControllerSettings初始化代码:
    import com.google.api.gax.core.FixedCredentialsProvider
    import com.google.auth.oauth2.GoogleCredentials
    import java.util.Arrays
    
    val credentials = GoogleCredentials.getApplicationDefault()
      .createScoped(Arrays.asList("https://www.googleapis.com/auth/cloud-platform"))
    
    val clusterControllerSettings = ClusterControllerSettings.newBuilder()
      .setEndpoint(regionEndpoint)
      .setCredentialsProvider(FixedCredentialsProvider.create(credentials))
      .build()
    
  • 如果本地使用代理访问公网,gRPC Java客户端默认不会读取系统代理配置,需要在JVM启动参数中显式指定gRPC代理,或者临时关闭代理直连测试:
    -Dhttps.proxyHost=代理地址 -Dhttps.proxyPort=代理端口 -Dhttp.proxyHost=代理地址 -Dhttp.proxyPort=代理端口
    
  • 检查引入的java-dataproc客户端依赖版本,升级到1.4.0及以上的稳定版本,旧版本存在gRPC凭证加载丢失权限范围的已知bug。

验证时可以先调用查询集群的接口做连通性测试,不需要直接走创建集群的长耗时流程,确认接口正常返回后再执行创建操作即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 06:03:12