【问题标题】:What is the preferred way to configure GCP credentials in Spring boot application在 Spring Boot 应用程序中配置 GCP 凭据的首选方法是什么
【发布时间】:2021-10-19 07:14:00
【问题描述】:

我正在编写一个基于 Spring Boot 的微服务,该微服务将部署在 GKE 上。要配置服务帐户凭据,我确实看到有多个选项可用。什么是最优选和可能更安全的选择。我尝试了以下方法,请提出其他方法

  1. 与 spring.cloud.gcp.credentials.location 的 CredentialsProvider 接口
  2. spring.cloud.gcp.credentials.encoded-key
  3. GCP 秘密管理器

【问题讨论】:

  • 只是一个旁注:“首选方式”几乎总是基于意见。

标签: java spring-boot google-cloud-platform microservices google-kubernetes-engine


【解决方案1】:

在云环境中,通常管理开销最少的最安全和最佳选择是使用来自云提供商的相应服务 - 在您的情况下,它将是 Secret Manager。当然,如果您不打算将您的应用程序与特定的云提供商绑定或迎合本地环境,那么您可以使用第三方机密管理提供商,例如 HashiCorp Vault

但是,即使使用 Secret Manager,如果您直接与 API 交互,您也必须提供密钥才能在某处调用 API,这会产生另一个问题。一般推荐的解决方案是使用应用程序身份验证作为服务帐户并直接与秘密管理器交互,如here 所述。或者,如here 所述,还有其他方法可以使用 CSI 驱动程序将 Secret Manager 中的 Secret 挂载到 GKE 卷上。

运行安全的集群和容器应用程序是一项关键要求,here 是 GKE 安全强化的进一步建议,其中还包括机密管理。更具体地说,您可以查看“CIS GKE Benchmark Recommendation:6.3.1”部分中的建议

【讨论】:

    【解决方案2】:

    虽然@Shailendra 为您提供了一个很好的解决方案,但在您使用GKE 时,您可以将敏感信息存储为Kubernetes secrets

    KubernetesGKE 文档都提供了几个创建机密的示例。

    您稍后可以使用multiple ways 中配置的秘密,在简单的用例中,作为可以在应用程序中使用的environment variables。请同时查看this article

    Spring Cloud Kubernetes 项目支持以 property sources 的身份使用此机密。

    此方法允许您使用minikubekind 在本地测试您的应用程序部署,然后将相同的工件部署到云提供商。此外,它与云提供商不可知,因为您使用的是开箱即​​用的 Kubernetes 工件。


    恐怕我们太专注于为您提供更多替代方案,以至于最终我们实际上并没有回答您的问题。

    之前,我会给你使用 Kubernetes Secrets 的建议,它仍然很好,但是请允许我稍后再回来。

    根据您尝试设置的different properties,您正在尝试代表您的应用程序配置凭据,以便与部署在 GCP 中的其他服务进行交互。

    为此,您首先需要的是service account

    简而言之,服务帐户是一种软件工件,它结合了多个权限。

    此服务帐户稍后可以分配给某个 GCP 资源、某个 GCP 服务,并且它将允许该资源继承代表与其他 GCP 资源和服务交互时配置的权限。

    每个服务帐户都会有一组关联的密钥,用于识别服务帐户 - 您要努力保护的信息。

    有不同类型的服务帐户,主要是默认服务帐户,由 GCP 在您启用或使用某些 Google Cloud 服务(一种用于 Compute Engine,另一种用于 App Engine)时创建 - 用户定义的

    您可以修改与这些服务帐户关联的权限:要记住的重要一点是始终关注principle of least privilege,仅授予服务帐户执行其任务所需的权限,仅此而已。

    默认情况下,您的 GKE 集群将使用 default Compute Engine service accountscopes for it defined。在联系其他服务时,这些权限将由您的 pod 继承。

    因此,一种可能的选择是为 GKE 配置适当的服务帐号并在您的代码中使用这些权限。

    您可以使用默认的 Compute Engine 服务帐号,但是,正如 GCP docs 在描述如何加强集群安全性时所指出的:

    每个 GKE 节点都有一个与之关联的身份和访问管理 (IAM) 服务帐号。默认情况下,节点会获得 Compute Engine 默认服务帐号,您可以通过导航到 Cloud Console 的 IAM 部分找到该帐号。默认情况下,此帐户具有广泛的访问权限,使其适用于各种应用程序,但它拥有的权限超出了运行 Kubernetes Engine 集群所需的权限。 您应该创建并使用最低权限的服务帐号来运行您的 GKE 集群,而不是使用 Compute Engine 默认服务帐号。

    因此,您可能需要创建一个具有最低权限的服务帐户来运行您的集群(和)应用程序。前面提到的link 提供了所有必要的信息。

    作为替代方案,您可以为您的应用程序配置不同的服务帐户,作为替代方案,您可以在此处使用 Kubernetes Secrets。

    请:

    • 不要直接提供您自己的CredentialsProvider 实现,我认为与其他解决方案相比,它不会为您提供任何额外的好处。

    • 如果您想使用spring.cloud.gcp.credentials.location 配置属性,请创建一个 Kubernetes 机密和expose it as a file,并将该属性的值设置为该文件位置。

    • 以非常相似的方式,使用 Kubernetes Secrets,例如 this article,您可以在环境变量 GOOGLE_APPLICATION_CREDENTIALS 下公开服务帐户凭据,Spring GCP 和不同的 GCP client libraries 看起来为此变量获取所需的凭据。

    • 我不会使用配置属性spring.cloud.gcp.credentials.encoded-key,我认为这种方法使密钥更适合威胁 - 可能您必须处理 VCS 问题等。

    • 秘密经理...正如我所说,@Shailendra 在他的回答中指出,这是一个合适的解决方案。

    • Guillaume 提供的选项也非常好。

    【讨论】:

      【解决方案3】:

      首选方式很难回答。看你的意愿了...

      就我个人而言,我更喜欢保持高水平的安全性,这与服务帐户身份验证有关,一旦发生违规行为可能会造成灾难。

      因此,我也保守秘密,我宁愿没有秘密。无论是在 K8S 中还是在秘密管理器中!问题解决了!!

      您可以通过ADC (application default credential) 实现这一目标。但就像那样,ADC 开箱即用地使用节点身份。这里的问题是,如果您在同一个节点上运行多个 pod,它们都将具有相同的身份,因此具有相同的权限。

      一个很酷的功能是使用Workload Identity。它允许您将服务帐户与您的 K8S 部署绑定。 ADC原理是一样的,只是绑定在pod级别而不是节点级别(创建了一个代理来拦截ADC请求)

      【讨论】:

        【解决方案4】:

        如果您的应用在 GCP 上运行,首选方式是使用 Google GCP 客户端提供的默认凭据。使用默认凭据提供程序时,客户端将使用与您的应用程序关联的服务帐户。

        【讨论】:

          猜你喜欢
          • 2022-06-11
          • 2011-01-15
          • 2011-05-21
          • 2015-11-02
          • 1970-01-01
          • 2019-08-06
          • 1970-01-01
          • 2020-02-01
          • 1970-01-01
          相关资源
          最近更新 更多