今天给大家介绍一下如何分析Spring Cloud Config 配置。文章的内容小编觉得不错,现在给大家分享一下,觉得有需要的朋友可以了解一下,希望对大家有所帮助,下面跟着小编的思路一起来阅读吧。
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"
注意: 以上使用本地文件只是为了测试。生产中应该使用远程服务提供的配置资源。
在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
并被加载。
默认情况下
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时需要加上双引号)
当需要时,Spring Cloud Config Server 支持在GIT URI中使用
{application}
、{profile}
、{label}
三个占位符,但是要记住{label}
总是会映射成git的标签。
spring: cloud: config: server: git: uri: https://github.com/myorg/{application}
在应用配置文件与特定配置文件中可以同过正则表达式来支持更为复杂的情况。可以在
{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
Spring Cloud 的 Config Server 也支持在搜索路径中使用
{application}
、{profile}
、{label}
占位符配置。例如:
spring: cloud: config: server: git: uri: https://github.com/spring-cloud-samples/config-repo searchPaths: '{application}'
也有不使用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}
通过基于文件(svn,本地)资源,文件名为
application*
的资源将在所有的应用客户端中共享。(application.properties
,application.yml
,application-*.properties
) 可以通过这种方式来定义一个全局的默认配置,如有必要应用可以使用应用指定配置对其进行覆盖。
Config Server 有一个属性覆盖的特性,允许操作者通过提供一个配置属性去覆盖所有应用中的配置。通过普通的Spring Boot钩子方式来实现,因此应用不需要什么改变。
声明覆盖仅仅需要在
spring.cloud.config.server.overrides
中配置一个键值对。例如:
spring: cloud: config: server: overrides: foo: bar
这样会引起所有的应用客户端去读取
foo=bar
去覆盖自己的配置。(当然应用拿到新的数据后自己决定如何使用,因此,覆盖并不是强制的,客户端可以自定义拿到新数据后的行为)
提示: 使用文件方式时,Spring环境中的占位符
${}
可以用""对"$"转义,例如:\${app.foo:bar}
。当使用YAML时,YAML本身会处理,因此不需要转义。
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
去关闭此功能。
你可以按你自己的情况用任何方法对Config Server进行安全处理。(从物理网络安全到OAuth3授权token),不过通过Spring Security 结合Spring Boot能提供一种更好的方式。
使用Spring Boot默认的基于HTTP安全方式,仅仅需要引入Spring Security依赖。(如:可以通过
spring-boot-starter-security
)
默认情况使用一个用户名和一个随机产生的密码,这种方式并不是很靠谱,因此,建议通过
spring-boot-starter-security
配置密码,并对其进行加密处理。
重要:要使用此特性,需要完全的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+...
Config Server 可以使用对称/非对称加解密算法。使用非对称算法拥有更好的安全性,但是对称算法更方便。
配置对称算法的key,只需要设置
encrypt.key
就行了。(或者使用环境变量ENCRYPT_KEY
)
配置非对称算法key,你可以选择在
encrypt.key
中配置一个PEM编码的文本,也可以通过encrypt.keyStore.*
配置使用一个密钥库。
encrypt.keyStore.*
包括如下配置:
location 一个资源路径
password 密钥库密码
alias 被使用的密钥标识
通过公钥加密,私钥解密。因此,原则上可以在服务端只配置公钥。但是实践中可能很少这样做,密钥管理在全部客户端处理过程都会被包含,而不仅仅是服务端。不过从另一方面说,如果服务端 真的不安全,而且只有少数几个客户端需要加密处理,那这样配置也有一定的合理性。
可以通过如下配置来创建一个用于测试的密钥库:
$ 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
通过添加
{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
数据请求时使用。
有的时候需要客户端对配置数进行解密,而不是在服务端解密。这种情况下,仍然可以通过
/encrypt
和/decrypt
端点访问。那就需要明确指定配置数据在服务端发出时不解密:spring.cloud.config.server.encrypt.enabled=false
。如果不关系端点访问,那就既不要配置密钥也不要开启此配置。
以上就是如何分析Spring Cloud Config 配置的全部内容了,更多与如何分析Spring Cloud Config 配置相关的内容可以搜索亿速云之前的文章或者浏览下面的文章进行学习哈!相信小编会给大家增添更多知识,希望大家能够支持一下亿速云!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。