0

我正在尝试对一个应用程序进行 docker 化,该应用程序对 bigquery 进行数据调用,我提供了凭据 .json(尝试通过 oauth-service 帐户进行身份验证),但我面临的是当我运行我的应用程序运行的容器时,但它当我通过笔记本电脑上的 jupyter 或云功能(GCP)简单地运行脚本时,要求提供身份验证码它使用 .json 并进行身份验证并提供数据。

愿意将此容器部署到云运行。我在这里做错了什么?任何帮助都会很棒!

我用来对 bigquery 进行 api 调用的示例方法。

PS:不是算法代码,但这只是我想要工作的方法,即对 bigquery 的 api 调用。在这段代码中也面临同样的问题。

def pfy_algorithm_1_1():


    import pandas as pd
    import numpy as np
    import datetime
    import requests
    import json
    from pandas import json_normalize
    from google.cloud import bigquery
    from google.oauth2 import service_account
    credentials = service_account.Credentials.from_service_account_file('mylo_bigquery.json')
    project_id = 'xyz'
    client = bigquery.Client(credentials= credentials,project=project_id)

    user_data=query_big_query('''select * from dataset_id.table_id limit 5''')
   
    destination_table1 = 'dataset-id.table-id'
    if_exists='replace'
    private_key='mylo_bigquery.json'
    authcode = 'xyz1xyz23'
    
    user_data.to_gbq(destination_table = destination_table1, 
      project_id = project_id, 
      chunksize=None,  
      reauth=False, 
      if_exists=if_exists, 
      auth_local_webserver=False, 
      table_schema=None)

码头文件:

#setting base image
FROM python:3
#setting the working directory in the container
WORKDIR /usr/src/app

#copy the dependencies file to working directory
COPY . .

#installing dependencies
RUN pip install -r requirements.txt


#command to run on container start
EXPOSE 8080

ENTRYPOINT ["python3","main.py"]
4

1 回答 1

4

首先,包装一个包含秘密的容器是不安全的。容器并不安全,进入其中并获取秘密非常容易。不要那样做。

其次,使用Cloud Run,您不需要服务帐户密钥文件元数据服务器为您提供 Cloud Run 服务的凭据。如果未设置,则使用计算引擎默认服务帐户,否则使用提供的此帐户。

元数据服务器为您的 API 调用生成令牌,GCP 库与它兼容,所以不用担心。

代码中的解决方案是创建没有凭据的 BigQuery 客户端,让库从运行时上下文中获取它

client = bigquery.Client(project=project_id)

如果你想在本地测试你的容器,我写了一篇文章


编辑 1

我将尝试解释:

  1. 没有密钥文件?是的,这是原则!保守秘密最好的办法,就是不要有秘密!所以现在,元数据服务器为您提供所有必需的凭据信息,您无需担心 Cloud Run(或 Cloud Run,以及 Google Cloud 上的任何其他运行时)上的这些信息。

  2. 在您的工作站(或非 GCP 环境)上没有元数据服务器,因此您没有来自那里的凭据。

  • 如果您阅读了我的文章,您将了解如何在运行时在 docker 容器中加载凭据(使用您的用户凭据挂载卷,并设置环境变量以引用此挂载的卷)

  • 如果您在其他环境(非 GCP)上运行容器,则原则是相同的,但您不能使用您的用户凭据(这不是您的工作站,这不是您的责任)。因此,您需要一个放在运行时环境中的服务帐户密钥文件,并以相同的方式运行您的容器(使用服务帐户密钥文件挂载一个卷,并设置一个环境变量来引用这个挂载的卷)

原则还是一样的:不要把你的秘密放在容器里,它不安全,而且是不好的做法。

  1. 我不确定能不能抓住你。元数据服务器拥有服务帐户凭据(以及更多)所需的一切

编辑 2

我用烧瓶在我这边进行了测试,它起作用了。您的问题来自未强制执行的 Cloud Run 合同。

这是一个有效的最小代码

from flask import Flask
import os


app = Flask(__name__)

@app.route('/', methods=['GET'])
def pfy_algorithm_1_1():


    import pandas as pd
    import numpy as np
    import datetime
    import requests
    import json
    from pandas import json_normalize


    user_data=query_big_query('''select * from dlp_test.name limit 5''')

    destination_table1 = 'dlp_test.name3'
    if_exists='replace'

    user_data.to_gbq(destination_table = destination_table1,
                     project_id = "project_id",
                     chunksize=None,
                     reauth=False,
                     if_exists=if_exists,
                     auth_local_webserver=False,
                     table_schema=None)
    return "Message End of processing",200


def query_big_query(query):
    """ Query bigquery return result in the form of dataframe :param query: the query to be queried """

    from google.cloud import bigquery
    # Cant directly add hence add indirectly
    client = bigquery.Client(project="project_id")
    update_query = client.query(query)
    update_iter = update_query.result()
    update_table = update_iter.to_dataframe()
    return update_table

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 8080)))

只需在部署后访问 Cloud Run URL 即可运行脚本。

不要忘记在依赖项中添加烧瓶。

于 2021-04-26T14:06:30.590 回答