上下文
我有一个bash脚本,它使用gcloud
命令行工具来执行维护操作。
这个剧本很好用。
该脚本位于基于google/cloud-sdk
的docker映像中,直接通过容器入口点自动执行。
目标是通过Kubernetes CronJob定期执行它。这也有效。
我目前还没有设置任何有关身份验证的内容,所以我的脚本使用计算引擎默认服务帐户。
然而,到目前为止还不错,我需要停止使用这个默认服务帐户,并切换到一个单独的服务帐户,使用API密钥文件。这就是问题的根源。
问题
我的计划是通过一个KubernetesSecret将我的API密钥挂载到容器中,然后使用GOOGLE_APPLICATION_CREDENTIALS
(这里介绍)自动加载它,配置如下(简化):
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变量。
图像文档也没有多大帮助,因为它只提供了一种更改gcloud配置位置的方法。
此外,我很确定我需要一种方法来为gcloud提供一些额外的配置(项目、区域等),所以我想我的解决方案应该让我从一开始就可以选择这样做。
可能的解决方案
我找到了一些解决这个问题的方法:
更改映像的入口点脚本,读取环境变量,并使用
gcloud
命令执行env准备:这是最简单的解决方案,也是让我保持Kubernetes配置最干净的解决方案(每个环境只因一些环境变量而不同)。然而,这需要维护我自己使用的图像副本,如果可能的话,我希望避免。
使用安装为文件的Kubernetes configMap覆盖我的映像的入口点:
这个选项可能是最方便的:为每个环境执行一个单独的配置映射,在那里我可以执行我想要的任何环境设置(例如
gcloud auth activate-service-account --key-file /credentials/credentials.json
)。尽管如此,它还是让人感觉很粗糙,与env变量相比几乎不可读。手动提供
gcloud
(在/root/.config/gcloud
中)的配置文件:我想这将是最干净的解决方案,然而,配置语法似乎并不清楚,我不确定通过configMap提供这种配置有多容易。
正如你所看到的,我找到了解决问题的方法,但没有一种能让我完全满意。我错过什么了吗?
这里是我最终使用的解决方案,尽管在我看来这仍然是一个变通方法:
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
使用以下配置映射:
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