如何解决如何在已部署的 Cloud Run 服务托管中使用 Google Secret?
我有一个正在运行的云运行服务 user-service
。出于测试目的,我通过环境变量作为纯文本传递了客户端机密。现在由于一切正常,我想改用秘密。
在“编辑修订版”选项的“变量”选项卡中,我可以声明环境变量,但我不知道如何传递秘密?我是否只需要在变量的值字段中传递像 ${my-secret-id}
这样的秘密名称?在此选项卡中没有关于如何使用机密的文档,只有顶部的提示:
Store and consume secrets using Secret Manager
在这种情况下这不是很有帮助。
解决方法
Google 有您可以在 API 中使用的 Secret 管理器客户端库的文档。
这应该可以帮助你做你想做的事 https://cloud.google.com/secret-manager/docs/reference/libraries
由于您尚未指定语言,因此我有一个 nodejs 示例,说明如何使用您的项目 ID 和机密名称访问最新版本的机密。我添加这个的原因是因为文档没有明确您需要提供的字符串作为名称。
const [version] = await this.secretClient.accessSecretVersion({
name: `projects/${process.env.project_id}/secrets/${secretName}/versions/latest`,});
return version.payload.data.toString()
请务必在您的 IAM 设置中为您的 api 在 GCP 中使用的服务帐户允许秘密管理员访问。
,问题现已得到解答,但是我在使用 Cloud Run with Java & Quarkus 以及使用 GraalVM 创建的本机映像时遇到了类似的问题。
虽然在撰写本文时 Cloud Run 是一项非常有趣的技术,但它缺乏通过 Cloud Run 配置加载机密的能力。在进行本地开发时,这无疑增加了我的应用的复杂性。
另外,Google 的文档真的很差。快速入门缺乏一个清晰的 Java 示例来获取秘密 [1] 而没有在相同的方法中设置它 - 我希望这是最常见的用例!
javadoc 本身似乎在很大程度上是使用 protobuf 语言自动生成的。有各种类似命名的方法,如 getSecret
、getSecretVersion
和 accessSecretVersion
我真的很想看到 Google 在这方面做出一些改进。我认为对于专门的团队来说,用适当的文档为通用语言制作库并没有太多要求。
这是我用来加载此信息的片段。它需要 GCP Secret 库和 GCP Cloud Core 库来加载项目 ID。
public String getSecret(final String secretName) {
LOGGER.info("Going to load secret {}",secretName);
// SecretManagerServiceClient should be closed after request
try (SecretManagerServiceClient client = buildClient()) {
// Latest is an alias to the latest version of a secret
final SecretVersionName name = SecretVersionName.of(getProjectId(),secretName,"latest");
return client.accessSecretVersion(name).getPayload().getData().toStringUtf8();
}
}
private String getProjectId() {
if (projectId == null) {
projectId = ServiceOptions.getDefaultProjectId();
}
return projectId;
}
private SecretManagerServiceClient buildClient() {
try {
return SecretManagerServiceClient.create();
} catch(final IOException e) {
throw new RuntimeException(e);
}
}
[1] - https://cloud.google.com/secret-manager/docs/reference/libraries
,您现在可以从 Secret Manager 中读取机密作为 Cloud Run 中的环境变量。这意味着您可以审核您的机密、设置每个机密的权限、版本机密等,而您的代码无需更改。
您可以通过 Cloud Console GUI (console.cloud.google.com) 指向机密,或者在从命令行部署 Cloud Run 服务时进行配置:
gcloud beta run deploy SERVICE --image IMAGE_URL --update-secrets=ENV_VAR_NAME=SECRET_NAME:VERSION
六分钟视频概览:https://youtu.be/JIE89dneaGo
详细文档:https://cloud.google.com/run/docs/configuring/secrets
,我找到了一种使用机密作为环境变量的方法。
以下文档 (https://cloud.google.com/sdk/gcloud/reference/run/deploy) 指出:
指定要挂载或作为环境变量提供的机密。钥匙 以正斜杠“/”开头的是挂载路径。所有其他键 对应环境变量。与每个相关的值 其中应采用 SECRET_NAME:KEY_IN_SECRET 格式;你可以省略 密钥中的密钥,用于指定密钥中所有密钥的数量 秘密。例如: '--update-secrets=/my/path=mysecret,ENV=othersecret:key.json' 将 创建一个带有秘密“mysecret”的卷并将该卷挂载在 '/我自己的路'。因为没有指定密钥,所有的密钥都在 'mysecret' 将被包括在内。一个名为 ENV 的环境变量将 也被创建,其值为 'key.json' 中的值 '其他秘密'。最多可以指定其中之一
,这是一段 Java 代码,用于获取您的 Cloud Run 项目的所有秘密。它需要 com.google.cloud/google-cloud-secretmanager 工件。
Map<String,String> secrets = new HashMap<>();
String projectId;
String url = "http://metadata.google.internal/computeMetadata/v1/project/project-id";
HttpURLConnection conn = (HttpURLConnection)(new URL(url).openConnection());
conn.setRequestProperty("Metadata-Flavor","Google");
try {
InputStream in = conn.getInputStream();
projectId = new String(in.readAllBytes(),StandardCharsets.UTF_8);
} finally {
conn.disconnect();
}
Set<String> names = new HashSet<>();
try (SecretManagerServiceClient client = SecretManagerServiceClient.create()) {
ProjectName projectName = ProjectName.of(projectId);
ListSecretsPagedResponse pagedResponse = client.listSecrets(projectName);
pagedResponse
.iterateAll()
.forEach(secret -> { names.add(secret.getName()); });
for (String secretName : names) {
String name = secretName.substring(secretName.lastIndexOf("/") + 1);
SecretVersionName nameParam = SecretVersionName.of(projectId,name,"latest");
String secretValue = client.accessSecretVersion(nameParam).getPayload().getData().toStringUtf8();
secrets.put(secretName,secretValue);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。