使用 Google Cloud Dataflow 如何 运行 在 GCE Compute 实例上使用正确的凭据?

Using Google Cloud Dataflow how do I run with proper credentials on a GCE Compute instance?

我是 Google Cloud Dataflow 的新手,从我下面的问题中可以明显看出这一点。

我已经编写了一个数据流应用程序,并且可以在本地和 GCE 实例上使用我的个人凭据毫无问题地将它传送到 运行。但是,我似乎无法使用计算引擎实例的服务凭据或我使用控制台的 API & AUTH 部分创建的服务凭据破解正确的步骤使其达到 运行。当我 运行.

时,我总是收到 401 未授权错误

这是我试过的...

1) 创建虚拟机,授予对存储、数据存储、sql 和计算引擎的访问权限。我的理解是,这应该创建了一个 CI 特定服务帐户,该帐户是服务器的默认凭据。这些应该与应用程序在此实例上 运行 时使用用户身份验证的方式相同。这是我得到 401 的地方。我的问题是......我在哪里可以看到这个应该创建的服务帐户?还是我只是相信它存在于某处?

2) 在开发人员控制台的 API & Auth 部分创建了服务凭证。然后使用 cloud auth activate-service-account 并通过将命令指向我下载的凭据 json 文件来激活该帐户。有点像使用 gcloud auth 登录时的 OAUTH 往返。在这里我也得到了 401.

3) 最后一件事是使用步骤 2 中的服务凭证与 GCE 实例分开,然后创建一个实现 CredentialFactory 接口的对象并将其传递给 PipelineOptions。但是,当它 运行s 时,应用程序现在崩溃并出现错误,指出它正在寻找一种方法,fromOptions,该方法不在 CredentialFactory 接口中。选项的配置方式、凭据工厂的外观以及堆栈跟踪如下。

我很乐意使用上述 3 种方法中的任何一种来使用服务凭证,如果我能让其中任何一种起作用的话。您可以就我做错了什么、我遗漏的步骤以及其他未探索的选项提供任何见解,我们将不胜感激。文档有点杂乱无章。如果有明确的分步指南,link 就足够了。到目前为止,我自己发现的帮助不大。

如果我可以提供任何其他信息,请告诉我。

下面是一些可能有用的代码,以及当代码 运行s 使用凭据工厂时我得到的堆栈跟踪。

选项设置代码如下所示:

GcrDataflowPipelineOptions options = PipelineOptionsFactory.fromArgs(args)
        .withValidation()
        .as(GcrDataflowPipelineOptions.class);
options.setKind("Counties");
options.setCredentialFactoryClass(GoogleCredentialProvider.class);

GoogleCredentialProvider.java

请注意,我作为创建服务帐户(重命名)的一部分下载的 json 文件是从我的应用 class 路径作为资源加载的文件。

public class GoogleCredentialProvider implements CredentialFactory {

    @Override
    public Credential getCredential() throws IOException, GeneralSecurityException {
        final String env = System.getProperty("gcr_dataflow_env", "local");
        Properties props = new Properties();
        ClassLoader loader = this.getClass().getClassLoader();
        props.load(loader.getResourceAsStream(env + "-gcr-dataflow.properties"));
        final String credFileName = props.getProperty("gcloud.dataflow.service.account.file");
        InputStream credStream = loader.getResourceAsStream(credFileName);
        GoogleCredential credential = GoogleCredential.fromStream(credStream);
        return credential;
    }

}

堆栈跟踪:

java.lang.RuntimeException: java.lang.RuntimeException: Unable to find factory method com.scotcro.gcr.dataflow.components.pipelines.GoogleCredentialProvider#fromOptions
    at com.google.cloud.dataflow.sdk.runners.dataflow.BasicSerializableSourceFormat.evaluateReadHelper(BasicSerializableSourceFormat.java:268)
    at com.google.cloud.dataflow.sdk.io.Read$Bound.evaluate(Read.java:123)
    at com.google.cloud.dataflow.sdk.io.Read$Bound.evaluate(Read.java:120)
    at com.google.cloud.dataflow.sdk.runners.DirectPipelineRunner$Evaluator.visitTransform(DirectPipelineRunner.java:684)
    at com.google.cloud.dataflow.sdk.runners.TransformTreeNode.visit(TransformTreeNode.java:200)
    at com.google.cloud.dataflow.sdk.runners.TransformTreeNode.visit(TransformTreeNode.java:196)
    at com.google.cloud.dataflow.sdk.runners.TransformHierarchy.visit(TransformHierarchy.java:99)
    at com.google.cloud.dataflow.sdk.Pipeline.traverseTopologically(Pipeline.java:208)
    at com.google.cloud.dataflow.sdk.runners.DirectPipelineRunner$Evaluator.run(DirectPipelineRunner.java:640)
    at com.google.cloud.dataflow.sdk.runners.DirectPipelineRunner.run(DirectPipelineRunner.java:354)
    at com.google.cloud.dataflow.sdk.runners.DirectPipelineRunner.run(DirectPipelineRunner.java:76)
    at com.google.cloud.dataflow.sdk.Pipeline.run(Pipeline.java:149)
    at com.scotcro.gcr.dataflow.app.GcrDataflowApp.run(GcrDataflowApp.java:65)
    at com.scotcro.gcr.dataflow.app.GcrDataflowApp.main(GcrDataflowApp.java:49)
Caused by: java.lang.RuntimeException: Unable to find factory method com.scotcro.gcr.dataflow.components.pipelines.GoogleCredentialProvider#fromOptions
    at com.google.cloud.dataflow.sdk.util.InstanceBuilder.buildFromMethod(InstanceBuilder.java:224)
    at com.google.cloud.dataflow.sdk.util.InstanceBuilder.build(InstanceBuilder.java:161)
    at com.google.cloud.dataflow.sdk.options.GcpOptions$GcpUserCredentialsFactory.create(GcpOptions.java:180)
    at com.google.cloud.dataflow.sdk.options.GcpOptions$GcpUserCredentialsFactory.create(GcpOptions.java:175)
    at com.google.cloud.dataflow.sdk.options.ProxyInvocationHandler.getDefault(ProxyInvocationHandler.java:288)
    at com.google.cloud.dataflow.sdk.options.ProxyInvocationHandler.invoke(ProxyInvocationHandler.java:127)
    at com.sun.proxy.$Proxy42.getGcpCredential(Unknown Source)
    at com.google.cloud.dataflow.sdk.io.DatastoreIO$Source.getDatastore(DatastoreIO.java:335)
    at com.google.cloud.dataflow.sdk.io.DatastoreIO$Source.createReader(DatastoreIO.java:320)
    at com.google.cloud.dataflow.sdk.io.DatastoreIO$Source.createReader(DatastoreIO.java:186)
    at com.google.cloud.dataflow.sdk.runners.dataflow.BasicSerializableSourceFormat.evaluateReadHelper(BasicSerializableSourceFormat.java:259)
    ... 13 more
java.lang.RuntimeException: java.lang.RuntimeException: Unable to find factory method com.scotcro.gcr.dataflow.components.pipelines.GoogleCredentialProvider#fromOptions
2015-07-03 09:55:42,519 | main | DEBUG | co.sc.gc.da.ap.GcrDataflowApp | destroying
    at com.google.cloud.dataflow.sdk.runners.dataflow.BasicSerializableSourceFormat.evaluateReadHelper(BasicSerializableSourceFormat.java:268)
    at com.google.cloud.dataflow.sdk.io.Read$Bound.evaluate(Read.java:123)
    at com.google.cloud.dataflow.sdk.io.Read$Bound.evaluate(Read.java:120)
    at com.google.cloud.dataflow.sdk.runners.DirectPipelineRunner$Evaluator.visitTransform(DirectPipelineRunner.java:684)
    at com.google.cloud.dataflow.sdk.runners.TransformTreeNode.visit(TransformTreeNode.java:200)
    at com.google.cloud.dataflow.sdk.runners.TransformTreeNode.visit(TransformTreeNode.java:196)
    at com.google.cloud.dataflow.sdk.runners.TransformHierarchy.visit(TransformHierarchy.java:99)
    at com.google.cloud.dataflow.sdk.Pipeline.traverseTopologically(Pipeline.java:208)
    at com.google.cloud.dataflow.sdk.runners.DirectPipelineRunner$Evaluator.run(DirectPipelineRunner.java:640)
    at com.google.cloud.dataflow.sdk.runners.DirectPipelineRunner.run(DirectPipelineRunner.java:354)
    at com.google.cloud.dataflow.sdk.runners.DirectPipelineRunner.run(DirectPipelineRunner.java:76)
    at com.google.cloud.dataflow.sdk.Pipeline.run(Pipeline.java:149)
    at com.scotcro.gcr.dataflow.app.GcrDataflowApp.run(GcrDataflowApp.java:65)
    at com.scotcro.gcr.dataflow.app.GcrDataflowApp.main(GcrDataflowApp.java:49)
Caused by: java.lang.RuntimeException: Unable to find factory method com.scotcro.gcr.dataflow.components.pipelines.GoogleCredentialProvider#fromOptions
    at com.google.cloud.dataflow.sdk.util.InstanceBuilder.buildFromMethod(InstanceBuilder.java:224)
    at com.google.cloud.dataflow.sdk.util.InstanceBuilder.build(InstanceBuilder.java:161)
    at com.google.cloud.dataflow.sdk.options.GcpOptions$GcpUserCredentialsFactory.create(GcpOptions.java:180)
    at com.google.cloud.dataflow.sdk.options.GcpOptions$GcpUserCredentialsFactory.create(GcpOptions.java:175)
    at com.google.cloud.dataflow.sdk.options.ProxyInvocationHandler.getDefault(ProxyInvocationHandler.java:288)
    at com.google.cloud.dataflow.sdk.options.ProxyInvocationHandler.invoke(ProxyInvocationHandler.java:127)
    at com.sun.proxy.$Proxy42.getGcpCredential(Unknown Source)
    at com.google.cloud.dataflow.sdk.io.DatastoreIO$Source.getDatastore(DatastoreIO.java:335)
    at com.google.cloud.dataflow.sdk.io.DatastoreIO$Source.createReader(DatastoreIO.java:320)
    at com.google.cloud.dataflow.sdk.io.DatastoreIO$Source.createReader(DatastoreIO.java:186)
    at com.google.cloud.dataflow.sdk.runners.dataflow.BasicSerializableSourceFormat.evaluateReadHelper(BasicSerializableSourceFormat.java:259)
    ... 13 more

您可能没有正确的凭据。当您从 GCE 执行 Dataflow 作业时,附加到实例的服务帐户将用于 DataFlow 的验证。

您在创建机器时是否这样做了?