docker - 使用带有官方 google/cloud-sdk 映像的 IAM 服务帐户
问题描述
语境
我有一个使用gcloud
命令行工具执行维护操作的 bash 脚本。
这个脚本工作正常。
该脚本基于 docker 镜像google/cloud-sdk
,直接通过容器入口点自动执行。
目标是通过Kubernetes CronJob定期执行它。这也有效。
我目前没有设置任何有关身份验证的内容,因此我的脚本使用Compute Engine 默认服务帐户。
到目前为止一切顺利,但是,我需要停止使用此默认服务帐户,并切换到具有 API 密钥文件的单独服务帐户。这就是问题开始的地方。
问题
我的计划是通过 Kubernetes Secret 将我的 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
更改我的图像的入口点脚本,以读取环境变量,并使用命令执行环境准备:这是最简单的解决方案,并且可以让我的 Kubernetes 配置保持最干净(每个环境仅在某些环境变量上有所不同)。但是,它需要维护我自己正在使用的图像的副本,如果可能的话,我想避免这种情况。
使用作为文件安装的 Kubernetes configMap 覆盖我的图像的入口点:
这个选项可能是最方便的:为每个环境执行一个单独的 configmap,我可以在其中进行任何我想要的环境设置(例如
gcloud auth activate-service-account --key-file /credentials/credentials.json
)。尽管如此,它还是感觉很老套,与 env 变量相比几乎不可读。手动为
gcloud
(in/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
使用以下 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
推荐阅读
- html - 为什么我的 .png 网站徽标文件不会显示在我的网站上?
- php - 如何在字符串中添加新行?
- spring - Spring Security:会话有效时禁用登录页面
- linux - 为什么子进程会调用 getppid()?Parent 的 PID 可以用来做什么?
- javascript - 如何从 HTML 字符串生成动态 HTML?
- java - 如何在 jtextfield 上迭代和打印矩阵?
- flutter-layout - 如何对齐行首的第一项和行尾的第二项?
- java - 类型不匹配:无法使用 java 在 selenium webdriver 中从 ChromeDriver 转换为 WebDriver
- python - 递归地尝试找到最大的 w/o 循环
- jquery-steps - 重定向到特定的向导步骤