官方文檔地址爲:http://cloud.spring.io/spring-cloud-static/Dalston.SR2/#spring-cloud-feignhtml
文中例子我作了一些測試在:http://git.oschina.net/dreamingodd/spring-cloud-preparationjava
官方項目:https://github.com/spring-cloud-samples/config-repomysql
Dalston.SR2linux
Spring Cloud Config爲分佈式系統的外部配置提供客戶端的服務端的支持。使用了它,開發人員就能夠在一箇中心倉庫管理應用程序在全部環境中的外部配置。服務器和客戶端映射的概念都和Spring環境以及PropertySource的抽象徹底相同,所以和Spring應用程序結合的至關好,而且支持任何語言編寫的任何程序。當應用程序隨着部署流程在DEV,TEST和PROD環境間遷移時,開發人員能夠統一管理這些環境的配置,而且能確認應用程序擁有全部的運行所需的東西。服務器後端服務器默認使用git,所以,它能夠輕鬆支持標籤版本的配置環境,而且能夠被大多數內容管理工具訪問到。能夠輕鬆添加替代實現,並使用Spring配置實現插拔。git
啓動服務器:(可下載參考官方項目)github
$ cd spring-cloud-config-serverspring
$ ../mvnw spring-boot:runsql
此服務器是一個Spring Boot應用,因此若是願意開發人員也能夠在IDE中跑(main類爲ConfigServerApplication)。而後試一試客戶端:shell
$ curl localhost:8888/foo/developmentbootstrap
{"name":"development","label":"master","propertySources":[{"name":"https://github.com/scratches/config-repo/foo-development.properties","source":{"bar":"spam"}},{"name":"https://github.com/scratches/config-repo/foo.properties","source":{"foo":"bar"}}]}
定位屬性配置源的默認策略爲克隆一個git倉庫(使用spring.cloud.config.server.git.uri),而且使用它去初始化一個迷你SpringApplication。迷你SpringApplication用於枚舉屬性源並經過JSON節點發布。
HTTP服務支持如下屬性數據源。
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
「application」是以SpringApplication的spring.config.name注入的(即常規Spring Boot應用程序中一般爲「application」),「profile」爲生效的配置文件(或以逗號分隔的屬性列表), 而「label」是可選的git標籤(一般爲「master」)。
Spring Cloud Config服務器從git倉庫(必須提供)爲遠程客戶端拉取配置信息:
spring: cloud: config: server: git: uri: https://github.com/spring-cloud-samples/config-repo
要在應用程序中使用這些特性,只須要建立一個依賴於spring-cloud-config-client的Spring Boot的應用(例如:借鑑config-client的測試,或同一個app)。最便捷的方式時用過Spring Boot starter的org.springframework.cloud:spring-cloud-starter-config依賴。使用Maven的父pom(spring-cloud-starter-parent)或Gradle的Spring CLI,Spring IO version management properties file也能夠。Maven示例:
pom.xml
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.5.RELEASE</version> <relativePath/><!-- lookup parent from repository --> </parent> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Brixton.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build><!-- repositories also needed for snapshots and milestones -->
而後建立一個標準的Spring Boot應用,以下例,簡單HTTP服務器:
@SpringBootApplication @RestController public class Application { @RequestMapping("/") public String home() { return "Hello World!"; } public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
App啓動時,它會從默認的本地配置服務器的8888端口拉取外部配置,固然前提是服務器已在8888啓動。使用bootstrap.properties切換配置服務器的地址開發人員可以改變應用啓動的行爲(就像一個應用程序上下文在程序引導階段使用的application.properties),例如:
spring.cloud.config.uri: http://myconfigserver.com
bootstrap屬性將做爲高優先級屬性源顯示在/env的連接返回結果中,例如:
$ curl localhost:8080/env
{
"profiles":[],"configService:https://github.com/spring-cloud-samples/config-repo/bar.properties":{"foo":"bar"},
"servletContextInitParams":{}, "systemProperties":{...},
...
}
(a property source called "configService:<URL of remote repository>/<file name>" contains the property "foo" with value "bar" and is highest priority).
(一個叫作"configService:<URL of remote repository>/<file name>"的最高優先級屬性源包含一個值爲「bar」的「foo「屬性)
NOTE the URL in the property source name is the git repository not the config server URL.
注意 屬性源名稱中的URL是git倉庫地址而不是配置服務器的URL。
Spring Cloud Config服務器爲外部配置提供了一個HTTP,基於資源的API(名稱-值對,或等價的YAML)。使用@EnableConfigServer註解,服務器能輕易嵌入Spring Boot應用。故這個應用就是一個配置服務器:
ConfigServer.java
@SpringBootApplication@EnableConfigServerpublic class ConfigServer { public static void main(String[] args) { SpringApplication.run(ConfigServer.class, args); } }
與通用的Spring Boot應用同樣,服務器默認跑在8080端口上,開發人員可使用多種方式換成8888端口。最簡單的方式是,發佈爲spring.config.name=configserver(配置服務器jar包中有一個configserver.yml),同時將其設定爲一個配置倉庫。另外一種方式是使用自身的application.properties(application.yml),以下:
application.properties
server.port: 8888
spring.cloud.config.server.git.uri: file://${user.home}/config-repo
其中${user.home}/config-repo爲包含了YAML和屬性文件的git倉庫。
注意 在Windows系統中若是路徑是一個帶盤符的絕對路徑,那麼開發人員須要額外的「/」,以下: file:///${user.home}/config-repo.
提示 如下是建立上例中git倉庫的操做步驟:
$ 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"
警告 使用本地的git倉庫只能用作測試目的。在生產環境要使用配置服務器。
警告 若是開發人員只保留文本文件,那麼配置倉庫的初始克隆將快速而高效。若是開始使用二進制文件,尤爲是體積大的,開發人員極可能會碰到第一次請求的延時甚至是服務器內存溢出錯誤。
配置中心的配置信息存在哪裏呢?管理這個的策略是傳說中的EnvironmentRepository,提供Environment對象。這個Environment是一個Spring Environment的淺層次拷貝(主要包含屬性源)。Environment數據源由三個變量參數化:
{application}由客戶端的"spring.application.name"屬性指定
{profile}由客戶端的"spring.profiles.active"屬性指定
{label}爲服務器的標註「版本」配置集(git爲分支)
倉庫實現一般與Spring Boot應用同樣,從「spring.config.name」和「spring.profiles.active」(也就是{application}和{profiles})加載配置文件。Profiles的優先級規則也和普通的應用同樣:active的profile優先於默認配置,還有,若是有多個profiles,那麼應用最後一個(就像在Map中添加數據同樣)。
示例:一個客戶端應用程序和他的bootstrap配置:
bootstrap.yml
spring: application: name: foo profiles: active: dev,mysql
(固然和Spring Boot應用同樣,這些屬性也能夠在環境變量和命令行中定義)。
若是倉庫是基於文件的,那麼服務器會從application.yml(被全部客戶端共享)和foo.yml(優先級高)中建立環境。若是YAML文件中有文檔指向Spring profiles,則應用較高優先級(根據profiles列出的順序),若是指明profile的YAML文件,那麼這些文件的優先級也比默認的高。高優先級的配置將在環境中率先轉換爲PropertySource。
EnvironmentRepository的默認實現使用了Git,這種方式能夠便捷的管理升級和物理環境以及審覈修改。修改倉庫地址只須要在配置中心修改"spring.cloud.config.server.git.uri"(application.yml)。若是用文件設置:前綴設置它,它應該從本地存儲庫中運行,以便在沒有服務器的狀況下快速輕鬆地啓動,但在這種狀況下,服務器直接在本地存儲庫上操做,而不克隆它(它是否是裸機不重要,由於配置中心從不對「遠程」存儲庫進行更改。要擴展中心並使其高度可用,開發人員須要將服務器的全部實例指向同一個存儲庫,這樣共享文件系統才能正常工做。即便在這種狀況下,最好使用ssh:協議用於共享文件系統存儲庫,以便服務器能夠將其克隆,並將本地工做副本用做緩存。
這個倉庫實現將HTTP資源的{label}參數映射到git標籤(commit,branch或tag)。若是git branch或tag中有斜線(/),那麼HTTP URL的標籤須要用特定字符串"()"代替指定(避免URL歧義)。例如,若標籤爲foo/bar,則替換爲foo()bar。注意若使用命令行工具的話,URL中的()須要特殊處理(例如,在shell中使用"轉義)。
Spring Cloud Config Server支持git倉庫URL中的{application}和{profile}佔位符(若須要,也支持{label},但記住標籤應用爲git標籤)。所以,開發人員能夠輕鬆支持「一個應用一套配置」的策略。
spring: cloud: config: server: git: uri: https://github.com/myorg/{application}
或使用同樣的模式加上{profile}實現「一個profile一套配置」的策略。
還能夠經過application和profile的pattern匹配來支持更復雜的需求。pattern的格式是帶有通配符的{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}與任何pattern不匹配,它將使用「spring.cloud.config.server.git.uri」下定義的默認uri。 在上面的例子中,對於「simple」倉庫,pattern爲simple/*(即它只匹配一個在全部配置文件中名爲「simple」的應用程序)。 「local」倉庫將全部配置文件中以「local」開頭的全部應用程序名稱匹配(/*後綴自動添加到任何沒有不匹配profile的pattern)。
注意 上文simple的一行快捷設置只能在僅設定URI的場合使用。設置其餘任何值都不能再用這種方式。repo中的pattern屬性實際上是一個數組,所以開發人員也可使用YAML數組(或[0],[1]等後綴)綁定到多個patterns。這是爲了運行不一樣profile的多個程序。示例:
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會認爲不以結尾的配置文件的pattern意味着實際上要匹配一個以此pattern開頭的配置文件列表(/staging是["/staging", "/staging,*"]的快捷方式)。這很常見,例如開發人員須要在本地跑"development" profile,同時在遠程跑"cloud" profile。
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倉庫克隆了配置。其餘兩個要在請求以後。
注意 啓動時克隆能夠快速定位錯誤的配置源(如無效的倉庫URI)。若cloneOnStart爲false,那麼服務可能會在配置源錯誤的狀況下順利啓動,並在應用請求的時候才發現配置源錯誤了。
使用基本的HTTP安全認證只需分別加入用戶名和密碼,例如:
spring: cloud: config: server: git: uri: https://github.com/spring-cloud-samples/config-repo username: trolley password: strongpassword
若不使用HTTPS和用戶證書,那麼將密鑰存在默認文件夾(/.ssh)並用URI指向SSH地址,也能夠作到SSH的開箱即用,如"git@github.com:configuration/cloud-configuration"。重要的是,Git服務器的入口存在於/.ssh/known_hosts文件中,而且以ssh-rsa格式存在。 其餘格式(像ecdsa-sha2-nistp256)均不支持。爲了不意外,應確保Git服務器的known_hosts文件中只有一個入口,而且與您提供給配置服務器的URL相匹配。若是開發人員在URL中使用了主機名,那麼須要在known_hosts文件中有這個名稱,而不是IP。當使用JGit訪問存儲庫,任何文檔都適用。HTTPS代理選項能夠在~/.git/config中設置,或經過相似於JVM進程的系統變量(-Dhttps.proxyHost and -Dhttps.proxyPort)。
提示 若是找不到~/.git文件夾,使用git config --global設置(例如git config --global http.sslVerify false)。
AWS CodeCommit authentication can also be done. AWS CodeCommit uses an authentication helper when using Git from the command line. This helper is not used with the JGit library, so a JGit CredentialProvider for AWS CodeCommit will be created if the Git URI matches the AWS CodeCommit pattern. AWS CodeCommit URIs always look like https://git-codecommit.${AWS_REGION}.amazonaws.com/${repopath}.
If you provide a username and password with an AWS CodeCommit URI, then these must be the AWS accessKeyId and secretAccessKey to be used to access the repository. If you do not specify a username and password, then the accessKeyId and secretAccessKey will be retrieved using the AWS Default Credential Provider Chain.
If your Git URI matches the CodeCommit URI pattern (above) then you must provide valid AWS credentials in the username and password, or in one of the locations supported by the default credential provider chain. AWS EC2 instances may use IAM Roles for EC2 Instances.
Note: The aws-java-sdk-core jar is an optional dependency. If the aws-java-sdk-core jar is not on your classpath, then the AWS Code Commit credential provider will not be created regardless of the git server URI.
默認狀況下,當經過SSH URI鏈接Git倉庫的時候,Spring Cloud Config Server的JGit library使用SSH配置文件如~/.ssh/known_hosts和/etc/ssh/ssh_config。在相似Cloud Foundry的雲環境下,本地文件系統多是短暫的或難以訪問的。這些狀況下,可使用Java屬性去設置SSH配置。爲了激活基於屬性的SSH配置,須將屬性spring.cloud.config.server.git.ignoreLocalSshSettings設置爲true。例:
spring: cloud: config: server: git: uri: git@gitserver.com:team/repo1.git ignoreLocalSshSettings: true hostKey: someHostKey hostKeyAlgorithm: ssh-rsa privateKey: | -----BEGIN RSA PRIVATE KEY----- MIIEpgIBAAKCAQEAx4UbaDzY5xjW6hc9jwN0mX33XpTDVW9WqHp5AKaRbtAC3DqX IXFMPgw3K45jxRb93f8tv9vL3rD9CUG1Gv4FM+o7ds7FRES5RTjv2RT/JVNJCoqF ol8+ngLqRZCyBtQN7zYByWMRirPGoDUqdPYrj2yq+ObBBNhg5N+hOwKjjpzdj2Ud 1l7R+wxIqmJo1IYyy16xS8WsjyQuyC0lL456qkd5BDZ0Ag8j2X9H9D5220Ln7s9i oezTipXipS7p7Jekf3Ywx6abJwOmB0rX79dV4qiNcGgzATnG1PkXxqt76VhcGa0W DDVHEEYGbSQ6hIGSh0I7BQun0aLRZojfE3gqHQIDAQABAoIBAQCZmGrk8BK6tXCd fY6yTiKxFzwb38IQP0ojIUWNrq0+9Xt+NsypviLHkXfXXCKKU4zUHeIGVRq5MN9b BO56/RrcQHHOoJdUWuOV2qMqJvPUtC0CpGkD+valhfD75MxoXU7s3FK7yjxy3rsG EmfA6tHV8/4a5umo5TqSd2YTm5B19AhRqiuUVI1wTB41DjULUGiMYrnYrhzQlVvj 5MjnKTlYu3V8PoYDfv1GmxPPh6vlpafXEeEYN8VB97e5x3DGHjZ5UrurAmTLTdO8 +AahyoKsIY612TkkQthJlt7FJAwnCGMgY6podzzvzICLFmmTXYiZ/28I4BX/mOSe pZVnfRixAoGBAO6Uiwt40/PKs53mCEWngslSCsh9oGAaLTf/XdvMns5VmuyyAyKG ti8Ol5wqBMi4GIUzjbgUvSUt+IowIrG3f5tN85wpjQ1UGVcpTnl5Qo9xaS1PFScQ xrtWZ9eNj2TsIAMp/svJsyGG3OibxfnuAIpSXNQiJPwRlW3irzpGgVx/AoGBANYW dnhshUcEHMJi3aXwR12OTDnaLoanVGLwLnkqLSYUZA7ZegpKq90UAuBdcEfgdpyi PhKpeaeIiAaNnFo8m9aoTKr+7I6/uMTlwrVnfrsVTZv3orxjwQV20YIBCVRKD1uX VhE0ozPZxwwKSPAFocpyWpGHGreGF1AIYBE9UBtjAoGBAI8bfPgJpyFyMiGBjO6z FwlJc/xlFqDusrcHL7abW5qq0L4v3R+FrJw3ZYufzLTVcKfdj6GelwJJO+8wBm+R gTKYJItEhT48duLIfTDyIpHGVm9+I1MGhh5zKuCqIhxIYr9jHloBB7kRm0rPvYY4 VAykcNgyDvtAVODP+4m6JvhjAoGBALbtTqErKN47V0+JJpapLnF0KxGrqeGIjIRV cYA6V4WYGr7NeIfesecfOC356PyhgPfpcVyEztwlvwTKb3RzIT1TZN8fH4YBr6Ee KTbTjefRFhVUjQqnucAvfGi29f+9oE3Ei9f7wA+H35ocF6JvTYUsHNMIO/3gZ38N CPjyCMa9AoGBAMhsITNe3QcbsXAbdUR00dDsIFVROzyFJ2m40i4KCRM35bC/BIBs q0TY3we+ERB40U8Z2BvU61QuwaunJ2+uGadHo58VSVdggqAo0BSkH58innKKt96J 69pcVH/4rmLbXdcmNYGm6iu+MlPQk4BUZknHSmVHIFdJ0EPupVaQ8RHT -----END RSA PRIVATE KEY-----
表1-SSH 配置屬性
Property Name |
Remarks |
ignoreLocalSshSettings |
true:使用基於屬性的SSH代替基於文件的SSH。需經過spring.cloud.config.server.git.ignoreLo calSshSettings設置,而不能在一個倉庫中定義。 |
privateKey |
合法的SSH私有密鑰。若ignoreLocalSshSettings爲true且Git URI是SSH格式的,則必須設置。 |
hostKey |
合法的SSH主機主機密鑰。若設置了hostKeyAlgorithm,則必須設置 |
hostKeyAlgorithm |
ssh-dss, ssh-rsa, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384 ,ecdsa-sha2-nistp521之中一個,必須設置若hostKey設置了。 |
strictHostKeyChecking |
true或false. 若爲false,則忽略host key的錯誤。 |
Spring Cloud Config Server也支持搜索路徑的佔位符如{application}和{profile}(若須要{label}也支持)。例如:
Spring Cloud Config Server
spring: cloud: config: server: git: uri: https://github.com/spring-cloud-samples/config-repo searchPaths: '{application}'
在倉庫中搜索與目錄(以及頂級)相同名稱的文件。在佔位符中使用通配符也是有效的(搜索中包含任何匹配的目錄)。
如前所述,Spring Cloud Config Server克隆了遠程git倉庫,若是本地副本被污染了,則Spring Cloud Config Server沒法從遠程倉庫更新本地副本。
爲解決這個問題,當本地副本被污染,Spring Cloud Config Server提供了force-pull屬性來讓其強制從遠程服務器拉取配置。
spring: cloud: config: server: git: uri: https://github.com/spring-cloud-samples/config-repo force-pull: true
如有多個倉庫配置,那麼能夠爲每一個都配置上這個屬性。以下:
spring: cloud: config: server: git: uri: https://git/common/config-repo.git force-pull: true repos: team-a: pattern: team-a-* uri: http://git/team-a/config-repo.git force-pull: true team-b: pattern: team-b-* uri: http://git/team-b/config-repo.git force-pull: true team-c: pattern: team-c-* uri: http://git/team-a/config-repo.git
注意 Force-pull的默認值是false。
警告 當使用基於版本控制的後端(git,svn)時,文件被克隆到本地文件系統。它們會被默認放在系統的帶config-repo-前綴的臨時目錄下。例如在linux系統中,它是/tmp/config-repo-<randomid>。有些操做系統按期清理臨時文件。這會致使如丟失屬性這樣不可預知的錯誤。爲避免這種狀況出現,要經過設置spring.cloud.config.server.git.basedir或spring.cloud.config.server.svn.basedir到一個非臨時文件的文件結構中,讓配置中心使用這個值。
配置中心還有個不使用Git的「原生」配置,它從本地classpath或文件系統加載配置文件(使用spring.cloud.config.server.native.searchLocations指向任何的靜態URL)。啓動配置中心時加上spring.profiles.active=native參數就可使用這個原生配置。
注意 記住使用文件時:文件資源要加前綴(沒有前綴的一般是classpath裏的)。跟Spring Boot配置同樣,可使用${}風格的佔位符,但記住windows的絕對路徑須要一個額外的"/",例如:file:///${user.home}/config-repo
警告 默認searchLocations的值適合本地Spring Boot應用徹底相同的([classpath:/, classpath:/config, file:./, file:./config])。這不會把服務器的application.properties暴露給全部的客戶端,由於服務器全部存在的屬性源在發送到客戶端以前就已經被刪除了。
提示 本地文件系統適合初學者的測試。在生產環境使用的話,必須保證文件系統的可靠性,並在配置中心的全部實例間共享。
搜索字段能夠包括{application},{profile}和{label}。這樣開發人員能夠在路徑中隔離文件夾,並選擇一個適合的策略(例如每一個應用一個子文件夾,或每一個profile一個子文件夾)。
若是不使用佔位符,那麼倉庫將把HTTP資源的{label}參數加到搜索路徑上的後綴,因此屬性文件將從從每一個搜索位置和一個與標籤名稱相同的子目錄加載(標記屬性在Spring環境中優先)。所以,沒有佔位符的話,默認與添加以/{label}/結尾的搜索位置同樣。好比 file:/tmp/config 和 file:/tmp/config,file:/tmp/config/{label}同樣。禁用這個功能能夠經過設定spring.cloud.config.server.native.addLabelLocations=false。
Spring Cloud Config Server also supports Vault as a backend.
Spring Cloud Config Server也支持Vault做爲後端。
保險櫃是安全訪問保密信息(secret)的工具。Secret是任意須要開發人員嚴格控制訪問的信息,好比API key,密碼,證書等等。Vault爲任意的secret提供統一的訪問接口,同時提供嚴格的訪問控制和記錄詳細的審覈信息。
更多信息請參考Vault quickstart guide。
配置中心啓用Vault後端,開發人員必須使用Vault profile去跑配置中心。例如在配置中心的application.properties中能夠加入spring.profiles.active=vault。
配置中心通常默認Vault服務器跑在http://127.0.0.1:8200上。同時也默認後端名稱是secret以及應用是key。下面的列表是可配置的Vault屬性。全部的屬性都以spring.cloud.config.server.vault爲前綴。
Name |
Default Value |
host |
127.0.0.1 |
port |
8200 |
scheme |
http |
backend |
secret |
defaultKey |
application |
profileSeparator |
, |
org.springframework.cloud.config.server.environment.VaultEnvironmentRepository中能夠找到全部的可配置屬性。
運行配置中心服務器,開發人員能夠向服務器發送HTTP請求來從Vault獲取信息。這樣作的話Vault服務器須要一個token。
首先在Vault中加入一些數據。好比:
$ vault write secret/application foo=bar baz=bam $ vault write secret/myapp foo=myappsbar
如今向配置中心服務器發送HTTP請求來獲取信息。
$ curl -X "GET" "http://localhost:8888/myapp/default" -H "X-Config-Token: yourtoken"
接下來經過上面的請求應該能夠得到一個相似於下面的響應。
{ "name":"myapp", "profiles":[ "default" ], "label":null, "version":null, "state":null, "propertySources":[ { "name":"vault:myapp", "source":{ "foo":"myappsbar" } }, { "name":"vault:application", "source":{ "baz":"bam", "foo":"bar" } } ]}
使用Vault時,開發人員還能夠給應用程序提供多屬性源。例如,假設開發人員在Vault中寫入如下數據。
secret/myApp,dev
secret/myApp
secret/application,dev
secret/application
使用配置中心能夠將secret/應用寫入屬性的方式應用在全部應用程序中。名稱爲myApp的應用將具備寫入secret/myApp和secret/應用程序的任何屬性。當myApp啓用開發配置時,寫入上述全部路徑的屬性就可用,在列表中的第一個路徑中的屬性優先於其餘全部的路徑。
使用基於文件的(即git,svn和native)倉庫,應用程序中的文件名資源在全部的客戶端應用間共享(application.properties, application.yml, application-*.properties etc)。開發人員可使用這些文件名資源來配置全局默認值,並按需覆蓋指定應用中的文件。
#_property_overrides[屬性覆蓋]功能也能夠用於設定全局默認值,而且使用佔位符應用程序能夠本地覆蓋默認值。
提示 使用"native" profile(本地文件系統後端),建議開發人員使用顯示不屬於服務器自帶配置的搜索位置。不然因爲默認搜索位置的應用資源是服務器的一部分,它們將被刪除。
當使用Vault做爲後端的時候,開發人員能夠經過將配置放入secret/應用的方式在應用間共享配置。例如運行如下的Vault命令
$ vault write secret/application foo=bar baz=bam
使用配置中心,全部的應用都將有可用的foo和baz屬性(不知道有啥用)。
一些情景中開發人員可能但願從多個環境的倉庫拉取配置數據。開發人員須要在配置中心的application.properties或application.yml啓用多profiles。若是,例如,若是還須要從Git倉庫或SVN倉庫拉取配置數據,則須要在配置服務器中設定下列屬性:
spring: profiles: active: git, svn cloud: config: server: svn: uri: file:///path/to/svn/repo order: 2 git: uri: file:///path/to/git/repo order: 1
除每一個倉庫制定一個URI以外,還能夠制定一個order屬性。order屬性幫助開發人員指定全部倉庫的優先順序。order屬性的數值越低,倉庫的優先級越高。倉庫的優先級能解決倉庫間包含統一屬性時的潛在衝突問題。
注意 從環境倉庫取值過程當中的全部類型的故障都將致使整個組合環境的故障。
注意 當使用組合環境時,全部倉庫都有相同的標籤很重要。好比有一個相似於上述的環境,若向SVN倉庫請求master標籤下的配置數據可是倉庫裏卻沒有master分支,那麼整個請求將失敗。
除了使用Spring Cloud中的一個環境倉庫以外,還能夠提供本身的環境倉庫bean做爲複合環境的一部分。爲此,須要實現EnvironmentRepository接口。若是開發人員但願在組合環境中控制自定義EnvironmentRepository的優先級,那麼就實現Ordered接口並覆蓋getOrdered方法。若是不這麼作,則自定義的EnvironmentRepository會擁有最低的優先級。
配置中心有一個「overrides」功能,它容許操做符給全部應用提供配置屬性,這些屬性不會被普通的Spring Boot hooks意外更改。聲明覆蓋只要加一個name-value鍵值對map到spring.cloud.config.server.overrides。例如:
spring: cloud: config: server: overrides: foo: bar
這會致使全部客戶端應用讀取到foo: bar配置,獨立於它們自身的配置以外。(固然一個應用能夠任意使用配置中心的數據,故並不須要強制覆蓋,可是隻要它們是Spring Cloud Config客戶端,它們就會提供可用的默認行爲)
提示 正常狀況下,Spring環境的佔位符使用反斜槓("")來轉義"${}",例如${app.foo:bar}解析爲"bar",除非應用提供了"app.foo"。當開發人員在服務器覆蓋配置是,注意在YAML格式中,不須要轉義反斜槓自己,而在屬性文件中須要。開發人員能夠在客戶端修改全部覆蓋的優先級爲相似默認值那樣,這使應用經過在遠程倉庫設定spring.cloud.config.overrideNone=true(默認爲false),來爲環境變量和系統屬性提供本身的值。
配置中心附帶一個Health Indicator,用於檢查配置的EnvironmentRepository是否工做。默認它向EnvironmentRepository詢問一個名爲app的應用,由EnvironmentRepository實現提供的默認profile和默認label。
開發人員能夠配置Health Indicator來檢查更多的應用連同自定義的profiles和labels。例如:
spring: cloud: config: server: health: repositories: myservice: label: mylabel myservice-dev: name: myservice profiles: development
You can disable the Health Indicator by setting spring.cloud.config.server.health.enabled=false.
開發人員能夠自由應用任何有意義的方式(從物理網絡安全到OAuth2承載令牌)來增強配置中心的安全,並且使用Spring Security和Spring Boot幾乎能夠輕鬆作任何事情。
要使用Spring Boot默認的HTTP Basic安全,只須要在classpath中接入Spring Security(例如經過spring-boot-starter-security)。默認是"user"的用戶名和隨機生成的密碼,實踐中不這樣用,所以推薦開發人員配置密碼(經過security.user.password)並進行加密(參考下面的說明來作)。
重要 先決條件:要使用加密和解密功能,開發人員須要在JVM中安裝完整的JCE(默認狀況下沒有)。開發人員能夠從Oracle下載「Java加密擴展(JCE)無限強度管理策略文件」,並按照安裝說明(實際上將JRE lib/security目錄中的2個策略文件替換爲下載的文件)。若是遠程屬性源包含加密內容(以{cipher}開頭的值),則它們將在經過HTTP發送給客戶端以前被解密。這種設置的主要優勢是,當「靜止」(例如,在git倉庫中)時,屬性值沒必要是純文本。若是值沒法解密,則從屬性源中刪除該值,並添加一個附加屬性,並使用相同的鍵,但以「invalid」爲前綴。和「不適用」(一般爲「<n/a>」)的值。這主要是爲了防止密文被用做密碼並意外泄漏。
若是開發人員正在爲配置客戶端應用程序設置遠程配置存儲庫,可能會包含一個這樣的application.yml:
application.yml
spring: datasource: username: dbuser password: '{cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ'
.properties文件中的加密值不能用引號括起來,不然將不會被解密:
application.properties
spring.datasource.username: dbuser
spring.datasource.password: {cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ
You can safely push this plain text to a shared git repository and the secret password is protected.
服務器還暴露 /encrypt和/decrypt路徑(假設這些會被保護且只能由受權代理訪問)。若開發人員在編輯一個遠程配置文件,可使用配置中心經過POST到/encrypt來加密值,例如:
$ curl localhost:8888/encrypt -d mysecret682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
注意 若開發人員要加密帶有須要進行URL編碼的字符的值,則應使用--data-urlencode選項來curl以確保它們已正確編碼。
提示 確保不要在加密值中包含任何curl命令統計信息。 將值輸出到文件能夠幫助避免此問題。逆操做也能夠經過/decrypt實現(假設服務器配置了對稱密鑰或全密鑰對):
$ curl localhost:8888/decrypt -d 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
mysecret
提示 若是開發人員使用curl進行測試,則使用--data-urlencode(而不是-d)或設置顯式的Content-Type:text/plain,以確保在有特殊字符('+')時,curl對數據進行正確編碼('+'號特別棘手)。在將加密值添加到YAML或屬性文件並在提交併將其推送到遠程的,潛在風險的存儲以前,須要先爲加密值添加{cipher}前綴。
/encrypt和/decrypt也都接受形式爲/*/{name}/{profiles}的路徑,當客戶端調用到主環境資源時,可使用每一個應用程序(name)和配置文件控制加密方式。
注意 爲了以這種細微的方式控制加密方式,開發人員還必須提供一種類型爲TextEncryptorLocator的@Bean來爲每一個不一樣的應用和配置文件建立不一樣的加密器。默認不提供(全部加密使用相同的密鑰)。 spring命令行客戶端(安裝了Spring Cloud CLI擴展)也能夠用於加密和解密,例如:
$ spring encrypt mysecret --key foo 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda $ spring decrypt --key foo 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda mysecret
要使用文件中的密鑰(例如,用於加密的RSA公鑰),預先使用「@」來填充密鑰值並提供文件路徑,例如:
$ spring encrypt mysecret --key @${HOME}/.ssh/id_rsa.pubAQAjPgt3eFZQXwt8tsHAVv/QHiY5sI2dRcR+...
key參數是強制性的(儘管有一個--前綴)。
配置中心可使用對稱的(共享的)密鑰或非對稱的(RSA密鑰對)。在安全方面考量,非對稱更優,不過對稱的每每是更便捷的,由於它只須要配置一個屬性值。
配置對稱密鑰,開發人員須要將encrypt.key設置爲保密字符串(或使用環境變量ENCRYPT_KEY將其保持在純文本配置文件以外)。
配置非對稱密鑰,開發人員能夠將密鑰設置爲PEM加密的文本值(encrypt.key),或者經過密鑰庫(好比JDK附帶的keytool工具)。密鑰庫相關屬性爲encrypt.keyStore.*,具體是:
如下命令用於建立密鑰庫
$ 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文件加入classpath,並加入配置中心的application.yml中:
encrypt: keyStore: location: classpath:/server.jks password: letmein alias: mytestkey secret: changeme
除了在加密屬性值的{cipher}前綴以外,配置中心在(Base64 encoded)密文開始以前查找{name:value}前綴(零或多個)。密鑰被傳遞給TextEncryptorLocator-能夠爲定位一個密碼的TextEncryptor執行任意邏輯。若是開發人員配置了一個密鑰庫(encrypt.keystore.location),則默認定位器將使用「密鑰」提供的別名來查找存儲庫中的密鑰,也就是用如下密碼:
foo: bar: `{cipher}{key:testkey}...`
定位器會查找一個名爲「testkey」的密鑰。前綴{secret:…}值也能夠提供secret,但若非默認狀況下使用的是密鑰庫密碼(這是當開發人員創建一個密鑰庫且不指定secret時獲得的)。若是肯定要提供secret,那麼建議開發人員也用一個自定義的SecretLocator來加密secrets。
若是密鑰僅僅用來加密幾個字節的配置數據(即只在一個地方使用),那麼使用密鑰轉置的理由並不充分,但有時仍是須要改變密鑰,好比當有安全漏洞的時候。這種狀況下全部的客戶端都須要更改其源配置文件(好比git)並使用新的{key:...}前綴,固然也要預先檢查密鑰別名在配置中心的可用性。
提示 若是想要讓配置中心處理全部的加密解密,那麼也能夠將{name:value}前綴明文發佈到/encrypt連接。
有時須要客戶端在本地而非服務器解密配置信息。這種狀況下,開發人員仍然可使用/encrypt和/decrypt連接(只要提供了encrypt.*的配置去定位密鑰),但須要使用spring.cloud.config.server.encrypt.enabled=false來顯式關閉轉出屬性的解密。若是不關心連接,那麼只要不配置密鑰且不啓用開關,就能夠正常工做。
dreamingodd原創文章,如轉載請註明出處。