【问题标题】:How to set GOOGLE_APPLICATION_CREDENTIALS on GKE running through Kubernetes如何在通过 Kubernetes 运行的 GKE 上设置 GOOGLE_APPLICATION_CREDENTIALS
【发布时间】:2017-10-30 17:57:51
【问题描述】:

在 kubernetes 的帮助下,我在 GKE 上运行日常作业,基于 kubernetes 中配置的 cron 每天都会启动一个新容器并尝试将一些数据插入 BigQuery。

我们的设置是我们在一个项目中的 GCP 中有 2 个不同的项目我们在另一个项目中维护 BigQuery 中的数据我们让所有 GKE 运行,所以当 GKE 必须与不同的项目资源交互时,我猜我必须设置一个名为 GOOGLE_APPLICATION_CREDENTIALS 的环境变量,它指向一个服务帐户 json 文件,但由于 kubernetes 每天都在启动一个新容器,我不知道应该如何以及在哪里设置这个变量。

提前致谢!

注意:这个文件被drone-gke插件解析为golang模板。

---
apiVersion: v1
kind: Secret
metadata:
  name: my-data-service-account-credentials
type: Opaque
data:
  sa_json: "bas64JsonServiceAccount"
---
apiVersion: v1
kind: Pod
metadata:
  name: adtech-ads-apidata-el-adunit-pod
spec:
  containers:
  - name: adtech-ads-apidata-el-adunit-container
    volumeMounts:
    - name: service-account-credentials-volume
     mountPath: "/etc/gcp"
     readOnly: true
  volumes:
  - name: service-account-credentials-volume
    secret:
      secretName: my-data-service-account-credentials
      items:
      - key: sa_json
        path: sa_credentials.json

这是我们用于加载 AdUnit 数据的 cron 作业

apiVersion: batch/v2alpha1
kind: CronJob
metadata:
  name: adtech-ads-apidata-el-adunit
spec:
  schedule: "*/5 * * * *"
  suspend: false
  concurrencyPolicy: Replace
  successfulJobsHistoryLimit: 10
  failedJobsHistoryLimit: 10
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: adtech-ads-apidata-el-adunit-container
            image: {{.image}}
            args:
            - -cp
            - opt/nyt/DFPDataIngestion-1.0-jar-with-dependencies.jar
            - com.nyt.cron.AdUnitJob
            env:
              - name: ENV_APP_NAME
                value: "{{.env_app_name}}"
              - name: ENV_APP_CONTEXT_NAME
                value: "{{.env_app_context_name}}"
              - name: ENV_GOOGLE_PROJECTID
                value: "{{.env_google_projectId}}"
              - name: ENV_GOOGLE_DATASETID
                value: "{{.env_google_datasetId}}"
              - name: ENV_REPORTING_DATASETID
                value: "{{.env_reporting_datasetId}}"
              - name: ENV_ADBRIDGE_DATASETID
                value: "{{.env_adbridge_datasetId}}"
              - name: ENV_SALESFORCE_DATASETID
                value: "{{.env_salesforce_datasetId}}"
              - name: ENV_CLOUD_PLATFORM_URL
                value: "{{.env_cloud_platform_url}}"
              - name: ENV_SMTP_HOST
                value: "{{.env_smtp_host}}"
              - name: ENV_TO_EMAIL
                value: "{{.env_to_email}}"
              - name: ENV_FROM_EMAIL
                value: "{{.env_from_email}}"
              - name: ENV_AWS_USERNAME
                value: "{{.env_aws_username}}"
              - name: ENV_CLIENT_ID
                value: "{{.env_client_id}}"
              - name: ENV_REFRESH_TOKEN
                value: "{{.env_refresh_token}}"
              - name: ENV_NETWORK_CODE
                value: "{{.env_network_code}}"
              - name: ENV_APPLICATION_NAME
                value: "{{.env_application_name}}"
              - name: ENV_SALESFORCE_USERNAME
                value: "{{.env_salesforce_username}}"
              - name: ENV_SALESFORCE_URL
                value: "{{.env_salesforce_url}}"
              - name: GOOGLE_APPLICATION_CREDENTIALS
                value: "/etc/gcp/sa_credentials.json"
              - name: ENV_CLOUD_SQL_URL
                valueFrom:
                  secretKeyRef:
                    name: secrets
                    key: cloud_sql_url
              - name: ENV_AWS_PASSWORD
                valueFrom:
                  secretKeyRef:
                    name: secrets
                    key: aws_password
              - name: ENV_CLIENT_SECRET
                valueFrom:
                  secretKeyRef:
                    name: secrets
                    key: dfp_client_secret
              - name: ENV_SALESFORCE_PASSWORD
                valueFrom:
                  secretKeyRef:
                    name: secrets
                    key: salesforce_password


          restartPolicy: OnFailure

【问题讨论】:

    标签: kubernetes google-kubernetes-engine


    【解决方案1】:

    因此,如果您的 GKE 项目是项目 my-gke,并且包含您的 GKE 容器需要访问的服务/事物的项目是项目 my-data,则一种方法是:

    • my-data 项目中创建一个服务帐户。给它所需的任何 GCP 角色/权限(例如,roles/bigquery. dataViewer,如果您有一些您的 my-gke GKE 容器需要读取的 BigQuery 表)。
    • 为这些服务帐户凭据创建一个 Kubernetes 机密资源。它可能看起来像这样:

      apiVersion: v1
      kind: Secret
      metadata:
        name: my-data-service-account-credentials
      type: Opaque
      data:
        sa_json: <contents of running 'base64 the-downloaded-SA-credentials.json'>
      
    • 在需要访问的容器中挂载凭据:

      [...]
      spec:
        containers:
        - name: my-container
          volumeMounts:
          - name: service-account-credentials-volume
            mountPath: /etc/gcp
            readOnly: true
      [...]
        volumes:
        - name: service-account-credentials-volume
          secret:
            secretName: my-data-service-account-credentials
            items:
            - key: sa_json
              path: sa_credentials.json
      
    • 在容器中设置GOOGLE_APPLICATION_CREDENTIALS环境变量指向挂载凭证的路径:

      [...]
      spec:
        containers:
        - name: my-container
          env:
          - name: GOOGLE_APPLICATION_CREDENTIALS
            value: /etc/gcp/sa_credentials.json
      

    这样,任何官方 GCP 客户端(例如 GCP Python 客户端、GCP Java 客户端、gcloud CLI 等)都应该尊重 GOOGLE_APPLICATION_CREDENTIALS env var,并且在发出 API 请求时,自动使用 @987654333 的凭据@您为其创建和安装凭据.json 文件的服务帐户。

    【讨论】:

    • 如果GOOGLE_APPLICATION_CREDENTIALS 只是作为环境变量提供,它是否也可以工作,还是必须始终指向已安装的文件?
    • 我相信 GOOGLE_APPLICATION_CREDENTIALS env var 的值始终必须是凭据文件的路径才能正常工作。例如,将 base64 编码或凭据的其他表示直接作为 GOOGLE_APPLICATION_CREDENTIALS env var 的值将不起作用。
    猜你喜欢
    • 2020-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-15
    • 2021-02-10
    • 2020-07-24
    • 2018-09-18
    • 1970-01-01
    相关资源
    最近更新 更多