如何在 Spring Cloud Data Flow 任务中外部化应用程序属性

Posted

技术标签:

【中文标题】如何在 Spring Cloud Data Flow 任务中外部化应用程序属性【英文标题】:How to externalize application properties in Spring Cloud Data Flow taks 【发布时间】:2018-09-09 02:46:07 【问题描述】:

我目前有一个常规 SpringBoot 应用程序,我将其拆分为 2 个应用程序,以便从 Spring Cloud Dataflow 和 Spring Batch 中获得一些好处:

    一个 SpringBoot 应用,负责通过 Spring Cloud Dataflow REST API 检测特定事件并启动新的 Batch 任务 一个 SpringBoot + Spring Batch 任务将从我们 Nexus 上的 jar 注册到 SCDF,并轮询调用新事件。

我已经让这两个应用程序都可以运行,并且我正在开始移动。现在我担心的是,这个批处理应用程序有一个application.yml 文件,其中包含可以(不应该,但可以)经常更新的数据源和其他重要属性。

在我目前的方法中,我的应用程序被打包在一个 Docker 容器中,我启动我的应用程序时说出最终的 application.yml 文件在哪里。这允许我在每个环境中拥有一个特定的.yml 文件,因为这里不允许我使用 Spring Profiles 来组织每个环境的变量。开发人员不应该知道 Prod vars。

这是我的 Dockerfile 的入口点:

ENTRYPOINT ["java","-Dspring.profiles.active=docker","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar", "--spring.config.location=classpath:/application.yml,file:/tmp/config/application.yml"]

使用这种 SCDF 任务的新方法来保持我的属性文件外部化的最佳方法是什么?我应该去 Spring Cloud Config 吗?将--spring.config.location 作为工作参数传递真的有效吗?

记住我上面提到的限制,Spring Cloud 是否仍然可以作为一种可能的解决方案来解决?

提前感谢您的帮助!

最好的问候,

恩里科

【问题讨论】:

【参考方案1】:

您可以为您的 spring 云任务和 spring 批处理使用 kubernetes configmap。如果你在 Kubernetes 上部署 Spring Cloud 数据流。您可以将以下依赖项添加到您的云任务和春季批处理中。

<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-kubernetes-config</artifactId>
</dependency>

现在您需要将以下引导 yaml 属性添加到您的应用程序中。

spring:
  cloud:
    kubernetes:
      enabled: true
      config:
        enabled: true
        namespace: <namespace>
        name: <config map 1>
        namespace: <kubernetes namespace>
        sources:
        - name: <config map 1>
        - name: <config map 2>
      reload:
        enabled: true
        strategy: refresh

您需要提及命名空间值。如果您基于环境隔离属性,请提及您正在使用的命名空间。您还可以指定配置映射名称。

在此处阅读有关它的更多信息。 https://docs.spring.io/spring-cloud-kubernetes/docs/current/reference/html/index.html#kubernetes-propertysource-implementations

【讨论】:

【参考方案2】:

Spring Cloud Config Server 绝对是一个不错的选择,特别是考虑到您提到的数据源包含密码和其他可能需要保护的密钥/秘密。 使用配置服务器,您不仅可以外部化配置,还可以安全地存储它们,因为它允许您使用对称和非对称算法加密属性,请参见此处:

spring cloud config encryption and decryption

另一方面,拥有这些属性 application.yml 意味着这些密码/密钥/秘密最终将在您的控制版本系统中(希望无法从您组织的网络外部访问)。

另一种选择是将配置保存在配置文件中,并仅将敏感信息外部化。在我的组织中,我们将 HashiCorp Vault 与 Spring Cloud Config 结合使用。

Vault

如果您的组织中没有部署现有的 Vault,并且您发现维护附加服务的工作量对您或您的团队来说太高,那么 Spring Cloud Config 服务器应该足够好。

关于:I'm not allowed here to use Spring Profiles to organize variables per env. Devs shouldn't be able to know Prod vars。 我认为这是在代码中拥有属性的直接后果,通常有一些(如果不是大多数)配置在不同的应用程序之间共享,最终导致配置地狱,特别是如果您必须轮换密码或密钥。 外部化将允许 Devs 访问非 prod 环境配置,Ops 处理 prod 环境配置,因此每个人都很高兴。即使使用 Vault 开发人员也可以“知道” prod env Vault 路径,但无法访问它。

【讨论】:

以上是关于如何在 Spring Cloud Data Flow 任务中外部化应用程序属性的主要内容,如果未能解决你的问题,请参考以下文章