如何在 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 编辑现有流

Spring Cloud Data Flow整合UAA之使用LDAP进行账号管理

Spring Cloud Data Flow 的自定义任务中缺少参数

Spring Cloud Data Flow整合Cloudfoundry UAA服务做权限控制