如何分析Spring Cloud Config 配置

86次阅读
没有评论

共计 9360 个字符,预计需要花费 24 分钟才能阅读完成。

今天给大家介绍一下如何分析 Spring Cloud Config 配置。文章的内容丸趣 TV 小编觉得不错,现在给大家分享一下,觉得有需要的朋友可以了解一下,希望对大家有所帮助,下面跟着丸趣 TV 小编的思路一起来阅读吧。

 Spring Cloud Config Server 配置服务

Spring 为扩展配置服务,提供了一个基于 HTTP 的资源绑定的 api。(键值对,或者 YAML 内容)此服务可以通过 @EnableConfigServer 非常容易的整合进 Spring Boot 应用中。

例如:ConfigServer.java

@SpringBootApplication
@EnableConfigServer
public class ConfigServer { public static void main(String[] args) { SpringApplication.run(ConfigServer.class, args);
 }
}

默认情况下,和 Spring Boot 应用一样运行在 8080 端口,当然也有很多种方法修改此端口。最简单的方法,设置默认的配置资源库。通过在 jar 中 configserver.yml 文件中配置 spring.config.name=configserver;或者通过指定自己的 configserver.yml。

例如:application.properties

server.port: 8888
spring.cloud.config.server.git.uri: file://${user.home}/config-repo

${user.home}/config-repo, 是一个 git 资源。内容为 YAML 或者 properties 文件内容。

例如:

$ cd $HOME
$ mkdir config-repo
$ cd config-repo
$ git init .
$ echo info.foo: bar   application.properties
$ git add -A .
$ git commit -m  Add application.properties

注意:以上使用本地文件只是为了测试。生产中应该使用远程服务提供的配置资源。

1 Environment Repository 环境资源

在 Config Server 中,对于配置数据你想要怎么样存储呢?存储策略由 Environment 中的 EnvironmentRepository 来决定。同时多个 Environment 之间也允许复制配置项,甚至配置源 propertySources。

Environment 资源主要来自这三个参数:

{application}对应着客户端的 spring.application.name 配置;

{profile}对应着客户端 spring.profiles.active 配置;

{label}这是一个服务端功能,标记着配置文件的版本。

资源实例通常表现和 Srping Boot 应用加载配置文件类似:spring.config.name 类似于 {application} 参数;spring.profiles.active 类似于 {profiles} 参数。对于特定配置文件的优先级也是类似 Spring Boot 的规则:特定的配置会覆盖默认配置,并且如果指定了多个,那最后一个优先级最高。

例如:一个客户端应用可以配置一下引导配置:

bootstrap.yml

spring:
 application:
 name: foo
 profiles:
 active: dev,mysql

普通 Spring Boot 应用也可以通过环境变量或者命令行方式配置以上信息

如果资源是基于文件方式的,那系统会从 application.yml 创建一个 Environment 共享给所有客户端,并且加载 foo.yml 进行覆盖。如果 YAML 文件中有指定特定配置的话,那么这些特定配置比默认配置拥有着更高的优先级。这些拥有更高优先级的配置文件在 Environment 之前,就逐个生成 PropertySource 并被加载。

1.1 Git Backend 基于 GIT

默认情况下 EnvironmentRepository 是基于 GIT 的,这样非常方便管理更新、物理环境也方便对修改历史进行审计。可以通过 spring.cloud.config.server.git.uri 配置属性修改 Config Server 的本地资源库(例如:在 application.yml 中修改)。如果设置成 file:前缀,那会从本地资源进行加载,这样方便你快速简易的启动服务。但是这样就是直接在本地资源库上进行操作,没有备份。(不过如果远程服务资源是不变得情况下,这种方式也无所谓。)

如果需要扩展 Config Server 使其具备高可用性,那你需要将所有的服务实例指向同一个资源,这样就工作在一个共享文件的环境下。在这个情况下最好使用 ssh: 协议去访问共享文件资源,这样可以备份资源同时可以使用本地缓存提高效率。

资源实例会把 HTTP 资源中的 {label} 映射成 git 标签(commit id, branch name 或者 tag) 如果 git 分支或者标签名上有斜杠 / 那映射成 HTTP URL 时会自动替换成 _。使用括号、空格时需要小心。(例如使用 cmd 时需要加上双引号)

1.1.1 Placeholders in Git URI:git uri 中的占位符

当需要时,Spring Cloud Config Server 支持在 GIT URI 中使用 {application}、{profile}、{label} 三个占位符,但是要记住 {label} 总是会映射成 git 的标签。

spring:
 cloud:
 config:
 server:
 git:
 uri: https://github.com/myorg/{application}

1.1.2 Pattern Matching and Multiple Repositories 正则与多资源库

在应用配置文件与特定配置文件中可以同过正则表达式来支持更为复杂的情况。可以在 {application}/{profile} 中可以使用通配符进行匹配,如果有多个值可以使用逗号分隔。

spring:
 cloud:
 config:
 server:
 git:
 uri: https://github.com/spring-cloud-samples/config-repo
 repos:
 simple: https://github.com/simple/config-repo
 special:
 pattern: special*/dev*,*special*/dev*
 uri: https://github.com/special/config-repo
 local:
 pattern: local*
 uri: file:/home/configsvc/config-repo

如果 {application}/{profile} 没有匹配到任何资源,则使用 spring.cloud.config.server.git.uri 配置的默认 URI。

上面例子中 pattern 属性是一个 YAML 数组,也可以使用 YAML 数组格式来定义。这样可以设置成多个配个配置文件。

spring:
 cloud:
 config:
 server:
 git:
 uri: https://github.com/spring-cloud-samples/config-repo
 repos:
 development:
 pattern:
 - */development
 - */staging
 uri: https://github.com/development/config-repo
 staging:
 pattern:
 - */qa
 - */production
 uri: https://github.com/staging/config-repo

每个资源库有一个可选的配置,用来指定扫描路径。

spring:
 cloud:
 config:
 server:
 git:
 uri: https://github.com/spring-cloud-samples/config-repo
 searchPaths: foo,bar*

这样系统就会自动搜索 foo 的子目录,以及以 bar 开头的文件夹中的子目录。

默认情况下,当第一次请求配置时,系统复制远程资源库。系统也可以配置成一启动就复制远程资源库。

spring:
 cloud:
 config:
 server:
 git:
 uri: https://git/common/config-repo.git
 repos:
 team-a:
 pattern: team-a-*
 cloneOnStart: true
 uri: http://git/team-a/config-repo.git
 team-b:
 pattern: team-b-*
 cloneOnStart: false
 uri: http://git/team-b/config-repo.git
 team-c:
 pattern: team-c-*
 uri: http://git/team-a/config-repo.git

上面的例子中 team- a 的资源库会在启动时就从远程资源库进行复制,其他的则等到第一次请求时才从远程资源库复制。

如果远程资源库设置了权限认证,则可以如下配置:

spring:
 cloud:
 config:
 server:
 git:
 uri: https://github.com/spring-cloud-samples/config-repo
 username: trolley
 password: strongpassword

如果你不是用 HTTPS 和用户认证,可以使用 SSH uri 的格式。例如:git@github.com:configuration/cloud-configuration 这样你就需要先有 SSH 的 key。这种方式系统会使用 JGit 库进行访问,可以去查看相关文档。可以在~/.git/config 中设置 HTTPS 代理配置,或者也可以通过 JVM 参数 -Dhttps.proxyHost、-Dhttps.proxyPort 来配置代理。

提示:当你不知道你的~/.git 目录时,可以使用 git config –global 来指定。例如:git config –global http.sslVerify false

3.2.1.1.3 Placeholders in Git Search Paths : GIT 路径搜索中的占位符

Spring Cloud 的 Config Server 也支持在搜索路径中使用 {application}、{profile}、{label} 占位符配置。例如:

spring:
 cloud:
 config:
 server:
 git:
 uri: https://github.com/spring-cloud-samples/config-repo
 searchPaths:  {application}

1.2 File System Backend 基于文件系统

也有不使用 git 资源库的方式,那就是从本地 classpath 或者文件系统加载配置文件。这种方式可以通过 spring.profiles.active=native 开启。

使用 file: 前缀加载文件系统,否则从 classpath 中加载,也可以使用 ${}样式的环境占位符。例如:file:///${user.home}/config-repo

searchLocations 默认值与本地 Spring Boot 应用的扫描路径一样,都是:[classpath:/, classpath:/config, file:./, file:./config] 这样并不用担心 application.properties 文件暴露给所有客户端,因为在发送给客户端之前就会被清理掉。

基于文件系统的配置服务对于测试和快速练手来说是比较好的,如果用于生产环境,那就需要确保文件系统的可靠性,并允许共享访问。

路径搜索时能够包含{application}、{profile}、{label},这样方便你按照目录来管理你的配置文件。

如果在路径搜索时不使用占位符,那也会尝试自动的在 HTTP 资源中加上 {label} 后缀,那这样就会从不同的路径加载到。因此,在默认情况下不使用占位符等价于在每一个路径后添加了 /{label}/。例如:file:/tmp/config 就等价于 file:/tmp/config,file:/tmp/config/{label}

1.3 Sharing Configuration With All Applications 应用共享配置

通过基于文件(svn,本地)资源,文件名为 application* 的资源将在所有的应用客户端中共享。(application.properties,application.yml,application-*.properties)可以通过这种方式来定义一个全局的默认配置,如有必要应用可以使用应用指定配置对其进行覆盖。

1.4 Property Overrides 属性覆盖

Config Server 有一个属性覆盖的特性,允许操作者通过提供一个配置属性去覆盖所有应用中的配置。通过普通的 Spring Boot 钩子方式来实现,因此应用不需要什么改变。

声明覆盖仅仅需要在 spring.cloud.config.server.overrides 中配置一个键值对。例如:

spring:
 cloud:
 config:
 server:
 overrides:
 foo: bar

这样会引起所有的应用客户端去读取 foo=bar 去覆盖自己的配置。(当然应用拿到新的数据后自己决定如何使用,因此,覆盖并不是强制的,客户端可以自定义拿到新数据后的行为)

提示:使用文件方式时,Spring 环境中的占位符 ${}可以用 对 $ 转义, 例如:\${app.foo:bar}。当使用 YAML 时,YAML 本身会处理,因此不需要转义。

2.2 Health Indicator 健康指示器

Config Server 通过一个健康指示器来检测配置的 EnvironmentRepository 是否正常工作。默认情况下会向 EnvironmentRepository 询问一个名字为 app 的应用配置,EnvironmentRepository 实例回应 default 配置。

可以通过配置让健康指示器一起去检查多个应用的多个配置。例如:

spring:
 cloud:
 config:
 server:
 health:
 repositories:
 myservice:
 label: mylabel
 myservice-dev:
 name: myservice
 profiles: development

也可以通过配置 spring.cloud.config.server.health.enabled=false 去关闭此功能。

2.2 Security 安全

你可以按你自己的情况用任何方法对 Config Server 进行安全处理。(从物理网络安全到 OAuth3 授权 token),不过通过 Spring Security 结合 Spring Boot 能提供一种更好的方式。

使用 Spring Boot 默认的基于 HTTP 安全方式,仅仅需要引入 Spring Security 依赖。(如:可以通过 spring-boot-starter-security)

默认情况使用一个用户名和一个随机产生的密码,这种方式并不是很靠谱,因此,建议通过 spring-boot-starter-security 配置密码,并对其进行加密处理。

2.3 Encryption and Decryption 加解密

重要:要使用此特性,需要完全的 JCE 授权,方法参见前文

如果远程资源是一个经过加密的内容(以 {cipher} 开头),在发送给客户端之前会被解密。这样,配置内容就不用明文存放了。当直接去替换一个没有解密的值时,会被标记为 invalid (无效的)。这基本上可以大部分的杜绝密钥泄露的发生。例如:

application.yml

spring:
 datasource:
 username: dbuser
 password:  {cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ

如果使用配置文件则加密数据不要加上双引号。例如:

application.properties

spring.datasource.username: dbuser
spring.datasource.password: {cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ

这样就可以安全共享此文件,同时可以保护密钥。

这个服务通过 /encrypt 和 /decrypt 端点向外暴露。这样就可以用过 POST 方式向 /encrypt 提交加密后的数据。例如:

$ curl localhost:8888/encrypt -d mysecret
682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda

反过来也行,通过 /decrypt 安全提交数据。(前提是已经在服务端配置了相应的解密 KEY)

$ curl localhost:8888/decrypt -d 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
mysecret

在提交之前,存放这些加密数据存在着潜在的不安全性。

/encrypt 和 /decrypt 都接受一个路径 /*/{name}/{profiles}用于分开控制每一个应用的密码。

注意:如果需要为每一个应用使用不同的密码,则需要一个 @Bean 产生一个 TextEncryptorLocator 对象来创建不同的密钥对,并给它们赋予一个名字。当然这是可选的,默认不需要这样(所有应用使用相同的密钥)

Spring 命令行客户端(Spring Cloud CLI)也可以使用加解密特性。例如:

$ spring encrypt mysecret --key foo
682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
$ spring decrypt --key foo 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
mysecret

可以使用 @来指定一个路径,包含一个存放加解密 key 的文件。例如:

$ spring encrypt mysecret --key @${HOME}/.ssh/id_rsa.pub
AQAjPgt3eFZQXwt8tsHAVv/QHiY5sI2dRcR+...

2.4 Key Management 密钥管理

Config Server 可以使用对称 / 非对称加解密算法。使用非对称算法拥有更好的安全性,但是对称算法更方便。

配置对称算法的 key,只需要设置 encrypt.key 就行了。(或者使用环境变量 ENCRYPT_KEY)

配置非对称算法 key,你可以选择在 encrypt.key 中配置一个 PEM 编码的文本,也可以通过 encrypt.keyStore.* 配置使用一个密钥库。

encrypt.keyStore.* 包括如下配置:

location 一个资源路径

password 密钥库密码

alias 被使用的密钥标识

通过公钥加密,私钥解密。因此,原则上可以在服务端只配置公钥。但是实践中可能很少这样做,密钥管理在全部客户端处理过程都会被包含,而不仅仅是服务端。不过从另一方面说,如果服务端 真的不安全,而且只有少数几个客户端需要加密处理,那这样配置也有一定的合理性。

 2.5 Creating a Key Store for Testing 创建一个密钥库用于测试

可以通过如下配置来创建一个用于测试的密钥库:

$ keytool -genkeypair -alias mytestkey -keyalg RSA \
 -dname  CN=Web Server,OU=Unit,O=Organization,L=City,S=State,C=US  \
 -keypass changeme -keystore server.jks -storepass letmein

把 server.jks 文件放入 classspath,然后在 application.yml 中进行以下配置:

encrypt:
 keyStore:
 location: classpath:/server.jks
 password: letmein
 alias: mytestkey
 secret: changeme

2.6 Using Multiple Keys and Key Rotation 使用多重密钥以及密钥轮换

通过添加 {cipher} 前缀来表明使用加密数据,系统会在对密文进行 Base64 解码之前寻找 {name:value} 前缀信息。密钥通过 TextEncryptorLocator(无论哪种)实例,最终使用 TextEncryptor 来完成加解密。如果配置了密钥库(encrypt.keystore.location), 那默认的执行器(locator)就会按照配置的 alias 去密钥库中查找相应的密钥。例如:

foo:
 bar: `{cipher}{key:testkey}...`

上例中执行器(locator)将会去查找一个叫做“testkey”的密钥。密钥库的密码可以通过 {secret:…} 来指定,但是如非必要一般不指定。如果想使用密钥库密码,那建议使用定制 SecretLocator 对其加密处理。

如果只是对很少的配置数据进行加密的话,密钥轮换基本上没有必要。但是,偶还还是会有需求去修改密钥的场景。在这种情况下,所有的客户端都需要改变源配置文件(如:git)来使用新的{key:…}, 最好还要事先检查密钥库中的密钥。

提示:{name:value}也可以在 /encrypt 数据请求时使用。

2.7 Serving Encrypted Properties 提供加密属性

有的时候需要客户端对配置数进行解密,而不是在服务端解密。这种情况下,仍然可以通过 /encrypt 和 /decrypt 端点访问。那就需要明确指定配置数据在服务端发出时不解密:spring.cloud.config.server.encrypt.enabled=false。如果不关系端点访问,那就既不要配置密钥也不要开启此配置。

以上就是如何分析 Spring Cloud Config 配置的全部内容了,更多与如何分析 Spring Cloud Config 配置相关的内容可以搜索丸趣 TV 之前的文章或者浏览下面的文章进行学习哈!相信丸趣 TV 小编会给大家增添更多知识, 希望大家能够支持一下丸趣 TV!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-04发表,共计9360字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)