如何在 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 任务中外部化应用程序属性的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Cloud Data Flow 任务中外部化应用程序属性
如何在与 Spring Cloud Data Local 服务器不同的服务器上运行任务
Spring Cloud Data Flow整合UAA之使用LDAP进行账号管理