将IAM服务帐户与Google / cloud-sdk官方图片一起使用

时间:2019-02-05 18:33:39

标签: docker kubernetes google-compute-engine google-cloud-sdk

上下文

我有一个bash脚本,它使用gcloud命令行工具来执行维护操作。

此脚本可以正常工作。

此脚本位于基于google/cloud-sdk的docker映像中,直接通过容器入口点自动执行。

目标是使其通过Kubernetes CronJob定期执行。这也可以。

我目前尚未设置任何有关身份验证的内容,因此我的脚本使用了Compute Engine default service account

但是,到目前为止,我需要停止使用此默认服务帐户,并使用API​​密钥文件切换到单独的服务帐户。问题就从这里开始。

问题

我的计划是通过Kubernetes Secret将我的API密钥安装在容器中,然后使用GOOGLE_APPLICATION_CREDENTIALS(文档为here)通过以下(简化)配置自动加载它:

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: some-name
spec:
  schedule: "0 1 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: some-name
              image: some-image-path
              imagePullPolicy: Always
              env:
                - name: GOOGLE_APPLICATION_CREDENTIALS
                  value: "/credentials/credentials.json"
              volumeMounts:
                - name: credentials
                  mountPath: /credentials
          volumes:
            - name: credentials
              secret:
                secretName: some-secret-name

但是很明显,gcloud工具的行为与编程语言SDK有所不同,并且完全忽略了该env变量。

image documentation也无济于事,因为它只为您提供一种更改gcloud配置位置的方法。

此外,我很确定我需要一种方法来为gcloud的将来(项目,区域等)提供一些额外的配置,所以我想我的解决方案应该给我选择的方法所以从一开始。

可能的解决方案

我找到了解决此问题的几种方法:

  • 更改图像的入口点脚本,以读取环境变量,并使用gcloud命令执行环境准备:

    这是最简单的解决方案,并且可以使我保持Kubernetes配置最干净的解决方案(每个环境仅因某些环境变量而异)。但是,这需要维护我自己使用的图像的副本,如果可能的话,我希望避免这种情况。

  • 使用安装为文件的Kubernetes configMap覆盖图像的入口点:

    该选项可能是最方便的:为每个环境执行一个单独的configmap,我可以在其中进行所需的任何环境设置(例如gcloud auth activate-service-account --key-file /credentials/credentials.json)。尽管如此,它还是很笨拙,与env变量相比几乎不可读。

  • gcloud(在/root/.config/gcloud中)手动提供配置文件:

    我想这将是最干净的解决方案,但是,配置语法似乎并不十分清楚,而且我不确定通过configMap提供此配置有多么容易。

如您所见,我找到了解决问题的方法,但是没有一个方法可以完全满足我的要求。我错过了什么吗?

1 个答案:

答案 0 :(得分:1)

作为记录,这是我最终使用的解决方案,尽管我认为这仍然是一种解决方法:

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: some-name
spec:
  schedule: "0 1 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: some-name
              image: some-image-path
              imagePullPolicy: Always
              command: ["/bin/bash", "/k8s-entrypoint/entrypoint.sh"]
              volumeMounts:
                - name: credentials
                  mountPath: /credentials
                - name: entrypoint
                  mountPath: /k8s-entrypoint
          volumes:
            - name: credentials
              secret:
                secretName: some-secret-name
            - name: entrypoint
              configMap:
                name: entrypoint

使用以下ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: entrypoint
data:
  entrypoint.sh: |
    #!/bin/bash

    gcloud auth activate-service-account --key-file /credentials/credentials.json

    # Chainload the original entrypoint
    exec sh -c /path/to/original/entrypoint.sh