服務(wù)器為外部配置(名稱值對或等效的YAML內(nèi)容)提供了基于資源的HTTP。服務(wù)器可以使用@EnableConfigServer注釋輕松嵌入到Spring Boot應(yīng)用程序中。所以這個應(yīng)用程序是一個配置服務(wù)器:
ConfigServer.java
@SpringBootApplication
@EnableConfigServer
public class ConfigServer {
? public static void main(String[] args) {
? ? SpringApplication.run(ConfigServer.class, args);
? }
}
像所有的默認端口8080上運行的所有Spring Boot應(yīng)用程序一樣,但您可以通過各種方式將其切換到常規(guī)端口8888。最簡單的也是設(shè)置一個默認配置庫,它是通過啟動它的spring.config.name=configserver(在Config Server jar中有一個configserver.yml)。另一個是使用你自己的application.properties,例如
application.properties
server.port: 8888
spring.cloud.config.server.git.uri: file://${user.home}/config-repo
其中${user.home}/config-repo是包含YAML和屬性文件的git倉庫。
注意在Windows中,如果文件URL為絕對驅(qū)動器前綴,例如file:///${user.home}/config-repo,則需要額外的“/”。
提示以下是上面示例中創(chuàng)建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"
警告使用本地文件系統(tǒng)進行g(shù)it存儲庫僅用于測試。使用服務(wù)器在生產(chǎn)環(huán)境中托管配置庫。
警告如果您只保留文本文件,則配置庫的初始克隆將會快速有效。如果您開始存儲二進制文件,尤其是較大的文件,則可能會遇到服務(wù)器中第一個配置請求和/或內(nèi)存不足錯誤的延遲。
環(huán)境庫
您要在哪里存儲配置服務(wù)器的配置數(shù)據(jù)?管理此行為的策略是EnvironmentRepository,服務(wù)于Environment對象。此Environment是SpringEnvironment(包括propertySources作為主要功能)的域的淺層副本。Environment資源由三個變量參數(shù)化:
{application}映射到客戶端的“spring.application.name”;
{profile}映射到客戶端上的“spring.profiles.active”(逗號分隔列表);和
{label}這是一個服務(wù)器端功能,標(biāo)記“版本”的配置文件集。
存儲庫實現(xiàn)通常表現(xiàn)得像一個Spring Boot應(yīng)用程序從“spring.config.name”等于{application}參數(shù)加載配置文件,“spring.profiles.active”等于{profiles}參數(shù)。配置文件的優(yōu)先級規(guī)則也與常規(guī)啟動應(yīng)用程序相同:活動配置文件優(yōu)先于默認配置,如果有多個配置文件,則最后一個獲勝(例如向Map添加條目)。
示例:客戶端應(yīng)用程序具有此引導(dǎo)配置:
bootstrap.yml
spring:
? application:
? ? name: foo
? profiles:
? ? active: dev,mysql
(通常使用Spring Boot應(yīng)用程序,這些屬性也可以設(shè)置為環(huán)境變量或命令行參數(shù))。
如果存儲庫是基于文件的,則服務(wù)器將從application.yml創(chuàng)建Environment(在所有客戶端之間共享),foo.yml(以foo.yml優(yōu)先))。如果YAML文件中有文件指向Spring配置文件,那么應(yīng)用的優(yōu)先級更高(按照列出的配置文件的順序),并且如果存在特定于配置文件的YAML(或?qū)傩裕┪募敲催@些文件也應(yīng)用于優(yōu)先級高于默認值。較高優(yōu)先級轉(zhuǎn)換為Environment之前列出的PropertySource。(這些規(guī)則與獨立的Spring Boot應(yīng)用程序相同。)
Git后端
EnvironmentRepository的默認實現(xiàn)使用Git后端,這對于管理升級和物理環(huán)境以及審核更改非常方便。要更改存儲庫的位置,可以在Config Server中設(shè)置“spring.cloud.config.server.git.uri”配置屬性(例如application.yml)。如果您使用file:前綴進行設(shè)置,則應(yīng)從本地存儲庫中工作,以便在沒有服務(wù)器的情況下快速方便地啟動,但在這種情況下,服務(wù)器將直接在本地存儲庫上進行操作,而不會克隆如果它不是裸機,因為配置服務(wù)器永遠不會更改“遠程”資源庫)。要擴展Config Server并使其高度可用,您需要將服務(wù)器的所有實例指向同一個存儲庫,因此只有共享文件系統(tǒng)才能正常工作。即使在這種情況下,最好使用共享文件系統(tǒng)存儲庫的ssh:協(xié)議,以便服務(wù)器可以將其克隆并使用本地工作副本作為緩存。
該存儲庫實現(xiàn)將HTTP資源的{label}參數(shù)映射到git標(biāo)簽(提交ID,分支名稱或標(biāo)簽)。如果git分支或標(biāo)簽名稱包含斜杠(“/”),則應(yīng)使用特殊字符串“(_)”指定HTTP URL中的標(biāo)簽,以避免與其他URL路徑模糊。例如,如果標(biāo)簽為foo/bar,則替換斜杠將導(dǎo)致標(biāo)簽看起來像foo(_)bar。如果您使用像curl這樣的命令行客戶端(例如使用引號將其從shell中轉(zhuǎn)出來),請小心URL中的方括號。
Git URI中的占位符
Spring Cloud Config服務(wù)器支持一個Git倉庫URL,其中包含{application}和{profile}(以及{label})的占位符,如果需要,請記住標(biāo)簽應(yīng)用為git標(biāo)簽)。因此,您可以使用(例如)輕松支持“每個應(yīng)用程序的一個repo”策略:
spring:
? cloud:
? ? config:
? ? ? server:
? ? ? ? git:
? ? ? ? ? uri: https://github.com/myorg/{application}
或使用類似模式但使用{profile}的“每個配置文件一個”策略。
模式匹配和多個存儲庫
還可以通過應(yīng)用程序和配置文件名稱的模式匹配來支持更復(fù)雜的需求。模式格式是帶有通配符的{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。在上面的例子中,對于“簡單”存儲庫,模式是simple/*(即所有配置文件中只匹配一個名為“簡單”的應(yīng)用程序)?!氨镜亍贝鎯炫c所有配置文件中以“l(fā)ocal”開頭的所有應(yīng)用程序名稱匹配(將/*后綴自動添加到任何沒有配置文件匹配器的模式)。
注意在上述“簡單”示例中使用的“單行”快捷方式只能在唯一要設(shè)置的屬性為URI的情況下使用。如果您需要設(shè)置其他任何內(nèi)容(憑據(jù),模式等),則需要使用完整的表單。
repo中的pattern屬性實際上是一個數(shù)組,因此您可以使用屬性文件中的YAML數(shù)組(或[0],[1]等后綴)綁定到多個模式。如果要運行具有多個配置文件的應(yīng)用程序,則可能需要執(zhí)行此操作。例:
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將猜測包含不在*中的配置文件的模式意味著您實際上要匹配從此模式開始的配置文件列表(因此*/staging是["*/staging", "*/staging,*"])。這是常見的,您需要在本地的“開發(fā)”配置文件中運行應(yīng)用程序,但也可以遠程運行“云”配置文件。
每個存儲庫還可以選擇將配置文件存儲在子目錄中,搜索這些目錄的模式可以指定為searchPaths。例如在頂層:
spring:
? cloud:
? ? config:
? ? ? server:
? ? ? ? git:
? ? ? ? ? uri: https://github.com/spring-cloud-samples/config-repo
? ? ? ? ? searchPaths: foo,bar*
在此示例中,服務(wù)器搜索頂級和“foo /”子目錄以及名稱以“bar”開頭的任何子目錄中的配置文件。
默認情況下,首次請求配置時,服務(wù)器克隆遠程存儲庫。服務(wù)器可以配置為在啟動時克隆存儲庫。例如在頂層:
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
在此示例中,服務(wù)器在啟動之前克隆了team-a的config-repo,然后它接受任何請求。所有其他存儲庫將不被克隆,直到請求從存儲庫配置。
注意在配置服務(wù)器啟動時設(shè)置要克隆的存儲庫可以幫助在配置服務(wù)器啟動時快速識別錯誤配置的源(例如,無效的存儲庫URI)。配置源不啟用cloneOnStart時,配置服務(wù)器可能會成功啟動配置錯誤或無效的配置源,而不會檢測到錯誤,直到應(yīng)用程序從該配置源請求配置為止。
認證
要在遠程存儲庫上使用HTTP基本身份驗證,請分別添加“username”和“password”屬性(不在URL中),例如
spring:
? cloud:
? ? config:
? ? ? server:
? ? ? ? git:
? ? ? ? ? uri: https://github.com/spring-cloud-samples/config-repo
? ? ? ? ? username: trolley
? ? ? ? ? password: strongpassword
如果您不使用HTTPS和用戶憑據(jù),當(dāng)您將密鑰存儲在默認目錄(~/.ssh)中,并且uri指向SSH位置時,SSH也應(yīng)該開箱即用,例如“git@github.com:配置/云配置”。必須在~/.ssh/known_hosts文件中存在Git服務(wù)器的條目,并且它是ssh-rsa格式。其他格式(如ecdsa-sha2-nistp256)不受支持。為了避免意外,您應(yīng)該確保Git服務(wù)器的known_hosts文件中只有一個條目,并且與您提供給配置服務(wù)器的URL匹配。如果您在URL中使用了主機名,那么您希望在known_hosts文件中具有這一點,而不是IP。使用JGit訪問存儲庫,因此您發(fā)現(xiàn)的任何文檔都應(yīng)適用。HTTPS代理設(shè)置可以~/.git/config設(shè)置,也可以通過系統(tǒng)屬性(-Dhttps.proxyHost和-Dhttps.proxyPort)與任何其他JVM進程相同。
提示如果您不知道~/.git目錄使用git config
--global來處理設(shè)置的位置(例如git config --global
http.sslVerify false)。
使用AWS CodeCommit進行認證
AWS CodeCommit認證也可以完成。當(dāng)從命令行使用Git時,AWS CodeCommit使用身份驗證助手。該幫助器不與JGit庫一起使用,因此如果Git URI與AWS CodeCommit模式匹配,則將創(chuàng)建用于AWS CodeCommit的JGit CredentialProvider。AWS CodeCommit URI始終看起來像
https://git-codecommit.$ {AWS_REGION} .amazonaws.com / $ {repopath}。
如果您使用AWS CodeCommit URI提供用戶名和密碼,那么這些URI必須是用于訪問存儲庫的AWS accessKeyId和 secretAccessKey。如果不指定用戶名和密碼,則將使用AWS默認憑據(jù)提供程序鏈檢索accessKeyId和secretAccessKey
。
如果您的Git URI與CodeCommit URI模式(上述)匹配,則必須在用戶名和密碼或默認憑據(jù)提供程序鏈支持的某個位置中提供有效的AWS憑據(jù)。AWS EC2實例可以使用EC2實例的
注意:aws-java-sdk-core jar是一個可選的依賴關(guān)系。如果aws-java-sdk-core jar不在您的類路徑上,則無論git服務(wù)器URI如何,都將不會創(chuàng)建AWS代碼提交憑據(jù)提供程序。
Git搜索路徑中的占位符
Spring Cloud Config服務(wù)器還支持具有{application}和{profile}(以及{label}(如果需要))占位符的搜索路徑。例:
spring:
? cloud:
? ? config:
? ? ? server:
? ? ? ? git:
? ? ? ? ? uri: https://github.com/spring-cloud-samples/config-repo
? ? ? ? ? searchPaths: '{application}'
在資源庫中搜索與目錄(以及頂級)相同名稱的文件。通配符在具有占位符的搜索路徑中也是有效的(搜索中包含任何匹配的目錄)。
力拉入Git存儲庫
如前所述Spring Cloud Config服務(wù)器克隆遠程git存儲庫,如果某種方式本地副本變臟(例如,通過操作系統(tǒng)進程更改文件夾內(nèi)容),則Spring Cloud Config服務(wù)器無法從遠程存儲庫更新本地副本。
要解決這個問題,有一個force-pull屬性,如果本地副本是臟的,將使Spring Cloud Config Server強制從遠程存儲庫拉。例:
spring:
? cloud:
? ? config:
? ? ? server:
? ? ? ? git:
? ? ? ? ? uri: https://github.com/spring-cloud-samples/config-repo
? ? ? ? ? force-pull: true
如果您有多個存儲庫配置,則可以為每個存儲庫配置force-pull屬性。例:
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。
版本控制后端文件系統(tǒng)使用
警告使用基于VCS的后端(git,svn)文件被檢出或克隆到本地文件系統(tǒng)。默認情況下,它們放在系統(tǒng)臨時目錄中,前綴為config-repo-。在linux上,例如可以是/tmp/config-repo-<randomid>。一些操作系統(tǒng)會定期清除臨時目錄。這可能會導(dǎo)致意外的行為,例如缺少屬性。為避免此問題,請通過將spring.cloud.config.server.git.basedir或spring.cloud.config.server.svn.basedir設(shè)置為不駐留在系統(tǒng)臨時結(jié)構(gòu)中的目錄來更改Config Server使用的目錄。
文件系統(tǒng)后端
配置服務(wù)器中還有一個不使用Git的“本機”配置文件,只是從本地類路徑或文件系統(tǒng)加載配置文件(您想要指向的任何靜態(tài)URL“spring.cloud.config.server .native.searchLocations“)。要使用本機配置文件,只需使用“spring.profiles.active = native”啟動Config Server。
注意請記住使用file:前綴的文件資源(缺省沒有前綴通常是classpath)。與任何Spring Boot配置一樣,您可以嵌入${}樣式的環(huán)境占位符,但請記住,Windows中的絕對路徑需要額外的“/”,例如file:///${user.home}/config-repo
警告searchLocations的默認值與本地Spring Boot應(yīng)用程序(所以[classpath:/, classpath:/config,
file:./, file:./config])相同。這不會將application.properties從服務(wù)器暴露給所有客戶端,因為在發(fā)送到客戶端之前,服務(wù)器中存在的任何屬性源都將被刪除。
提示文件系統(tǒng)后端對于快速入門和測試是非常好的。要在生產(chǎn)中使用它,您需要確保文件系統(tǒng)是可靠的,并在配置服務(wù)器的所有實例中共享。
搜索位置可以包含{application},{profile}和{label}的占位符。以這種方式,您可以隔離路徑中的目錄,并選擇一個有用的策略(例如每個應(yīng)用程序的子目錄或每個配置文件的子目錄)。
如果您不在搜索位置使用占位符,則該存儲庫還將HTTP資源的{label}參數(shù)附加到搜索路徑上的后綴,因此屬性文件將從每個搜索位置加載并具有相同名稱的子目錄作為標(biāo)簽(標(biāo)記的屬性在Spring環(huán)境中優(yōu)先)。因此,沒有占位符的默認行為與添加以/{label}/. For example `file:/tmp/config結(jié)尾的搜索位置與file:/tmp/config,file:/tmp/config/{label}相同
Vault后端
Spring Cloud Config服務(wù)器還支持Vault作為后端。
Vault是安全訪問秘密的工具。一個秘密是你想要嚴(yán)格控制訪問的任何東西,如API密鑰,密碼,證書等等。Vault為任何秘密提供統(tǒng)一的界面,同時提供嚴(yán)格的訪問控制和記錄詳細的審核日志。
有關(guān)Vault的更多信息,請參閱Vault快速入門指南。
要使配置服務(wù)器使用Vault后端,您必須使用vault配置文件運行配置服務(wù)器。例如在配置服務(wù)器的application.properties中,您可以添加spring.profiles.active=vault。
默認情況下,配置服務(wù)器將假定您的Vault服務(wù)器正在運行于http://127.0.0.1:8200。它還將假定后端名稱為secret,密鑰為application。所有這些默認值都可以在配置服務(wù)器的application.properties中配置。以下是可配置Vault屬性的表。所有屬性前綴為spring.cloud.config.server.vault。
名稱默認值
host127.0.0.1
port8200
schemeHTTP
backend秘密
defaultKey應(yīng)用
profileSeparator,
所有可配置的屬性可以在org.springframework.cloud.config.server.environment.VaultEnvironmentRepository找到。
運行配置服務(wù)器后,可以向服務(wù)器發(fā)出HTTP請求,以從Vault后端檢索值。為此,您需要為Vault服務(wù)器創(chuàng)建一個令牌。
首先放置一些數(shù)據(jù)給你Vault。例如
$ vault write secret/application foo=bar baz=bam
$ vault write secret/myapp foo=myappsbar
現(xiàn)在,將HTTP請求發(fā)送給您的配置服務(wù)器以檢索值。
$ curl -X "GET" "http://localhost:8888/myapp/default" -H "X-Config-Token: yourtoken"
在提出上述要求后,您應(yīng)該會看到類似的回復(fù)。
{
? "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"
? ? ? ? }
? ? ? }
? ]
}
多個Properties來源
使用Vault時,您可以為應(yīng)用程序提供多個屬性源。例如,假設(shè)您已將數(shù)據(jù)寫入Vault中的以下路徑。
secret/myApp,dev
secret/myApp
secret/application,dev
secret/application
寫入secret/application的Properties可用于使用配置服務(wù)器的所有應(yīng)用程序。名稱為myApp的應(yīng)用程序?qū)⒕哂袑懭雜ecret/myApp和secret/application的任何屬性。當(dāng)myApp啟用dev配置文件時,寫入所有上述路徑的屬性將可用,列表中第一個路徑中的屬性優(yōu)先于其他路徑。
與所有應(yīng)用共享配置
基于文件的存儲庫
使用基于文件(即git,svn和native)的存儲庫,文件名為application*的資源在所有客戶端應(yīng)用程序(所以application.properties,application.yml,application-*.properties等)之間共享)。您可以使用這些文件名的資源來配置全局默認值,并根據(jù)需要將其覆蓋應(yīng)用程序特定的文件。
#_property_overrides [屬性覆蓋]功能也可用于設(shè)置全局默認值,并且允許占位符應(yīng)用程序在本地覆蓋它們。
提示使用“本機”配置文件(本地文件系統(tǒng)后端),建議您使用不屬于服務(wù)器自身配置的顯式搜索位置。否則,默認搜索位置中的application*資源將被刪除,因為它們是服務(wù)器的一部分。
Vault服務(wù)器
當(dāng)使用Vault作為后端時,可以通過將配置放在secret/application中與所有應(yīng)用程序共享配置。例如,如果您運行此Vault命令
$ vault write secret/application foo=bar baz=bam
使用配置服務(wù)器的所有應(yīng)用程序都可以使用屬性foo和baz。
復(fù)合環(huán)境庫
在某些情況下,您可能希望從多個環(huán)境存儲庫中提取配置數(shù)據(jù)。為此,只需在配置服務(wù)器的應(yīng)用程序?qū)傩曰験AML文件中啟用多個配置文件即可。例如,如果您要從Git存儲庫以及SVN存儲庫中提取配置數(shù)據(jù),那么您將為配置服務(wù)器設(shè)置以下屬性。
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的每個repo之外,還可以指定order屬性。order屬性允許您指定所有存儲庫的優(yōu)先級順序。order屬性的數(shù)值越低,優(yōu)先級越高。存儲庫的優(yōu)先順序?qū)⒂兄诮鉀Q包含相同屬性的值的存儲庫之間的任何潛在沖突。
注意從環(huán)境倉庫檢索值時的任何類型的故障將導(dǎo)致整個復(fù)合環(huán)境的故障。
注意當(dāng)使用復(fù)合環(huán)境時,重要的是所有repos都包含相同的標(biāo)簽。如果您有類似于上述的環(huán)境,并且使用標(biāo)簽master請求配置數(shù)據(jù),但是SVN repo不包含稱為master的分支,則整個請求將失敗。
自定義復(fù)合環(huán)境庫
除了使用來自Spring Cloud的環(huán)境存儲庫之外,還可以提供自己的EnvironmentRepositorybean作為復(fù)合環(huán)境的一部分。要做到這一點,你的bean必須實現(xiàn)EnvironmentRepository接口。如果要在復(fù)合環(huán)境中控制自定義EnvironmentRepository的優(yōu)先級,您還應(yīng)該實現(xiàn)Ordered接口并覆蓋getOrdered方法。如果您不實現(xiàn)Ordered接口,那么您的EnvironmentRepository將被賦予最低優(yōu)先級。
屬性覆蓋
配置服務(wù)器具有“覆蓋”功能,允許操作員為應(yīng)用程序使用普通的Spring Boot鉤子不會意外更改的所有應(yīng)用程序提供配置屬性。要聲明覆蓋,只需將名稱/值對的地圖添加到spring.cloud.config.server.overrides。例如
spring:
? cloud:
? ? config:
? ? ? server:
? ? ? ? overrides:
? ? ? ? ? foo: bar
將導(dǎo)致配置客戶端的所有應(yīng)用程序獨立于自己的配置讀取foo=bar。(當(dāng)然,應(yīng)用程序可以以任何方式使用Config Server中的數(shù)據(jù),因此覆蓋不可強制執(zhí)行,但如果它們是Spring Cloud Config客戶端,則它們確實提供有用的默認行為。)
提示通過使用反斜杠(“\”)來轉(zhuǎn)義“$”或“{”,例如\${app.foo:bar}解析,可以轉(zhuǎn)義正常的Spring具有“$ {}”的環(huán)境占位符到“bar”,除非應(yīng)用程序提供自己的“app.foo”。請注意,在YAML中,您不需要轉(zhuǎn)義反斜杠本身,而是在您執(zhí)行的屬性文件中配置服務(wù)器上的覆蓋。
您可以通過在遠程存儲庫中設(shè)置標(biāo)志spring.cloud.config.overrideNone=true(默認為false),將客戶端中所有覆蓋的優(yōu)先級更改為更為默認值,允許應(yīng)用程序在環(huán)境變量或系統(tǒng)屬性中提供自己的值。
健康指標(biāo)
配置服務(wù)器附帶運行狀況指示器,檢查配置的EnvironmentRepository是否正常工作。默認情況下,它要求EnvironmentRepository應(yīng)用程序名稱為app,default配置文件和EnvironmentRepository實現(xiàn)提供的默認標(biāo)簽。
您可以配置運行狀況指示器以檢查更多應(yīng)用程序以及自定義配置文件和自定義標(biāo)簽,例如
spring:
? cloud:
? ? config:
? ? ? server:
? ? ? ? health:
? ? ? ? ? repositories:
? ? ? ? ? ? myservice:
? ? ? ? ? ? ? label: mylabel
? ? ? ? ? ? myservice-dev:
? ? ? ? ? ? ? name: myservice
? ? ? ? ? ? ? profiles: development
您可以通過設(shè)置spring.cloud.config.server.health.enabled=false來禁用運行狀況指示器。
安全
您可以以任何對您有意義的方式(從物理網(wǎng)絡(luò)安全性到OAuth2承載令牌)保護您的Config Server,并且Spring Security和Spring Boot可以輕松做任何事情。
要使用默認的Spring Boot配置的HTTP Basic安全性,只需在類路徑中包含Spring Security(例如通過spring-boot-starter-security)。默認值為“user”的用戶名和隨機生成的密碼,這在實踐中不會非常有用,因此建議您配置密碼(通過security.user.password)并對其進行加密(請參閱下文的說明怎么做)。
加密和解密
重要先決條件:要使用加密和解密功能,您需要在JVM中安裝全面的JCE(默認情況下不存在)。您可以從Oracle下載“Java加密擴展(JCE)無限強度管理策略文件”,并按照安裝說明(實際上將JRE lib / security目錄中的2個策略文件替換為您下載的文件)。
如果遠程屬性源包含加密內(nèi)容(以{cipher}開頭的值),則在通過HTTP發(fā)送到客戶端之前,它們將被解密。這種設(shè)置的主要優(yōu)點是,當(dāng)它們“靜止”時,屬性值不必是純文本(例如在git倉庫中)。如果值無法解密,則從屬性源中刪除該值,并添加具有相同鍵的附加屬性,但以“無效”作為前綴。和“不適用”的值(通常為“<n / a>”)。這主要是為了防止密碼被用作密碼并意外泄漏。
如果要為config客戶端應(yīng)用程序設(shè)置遠程配置存儲庫,可能會包含一個application.yml,例如:
application.yml
spring:
? datasource:
? ? username: dbuser
? ? password: '{cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ'
.properties文件中的加密值不能用引號括起來,否則不會解密該值:
application.properties
spring.datasource.username: dbuser
spring.datasource.password: {cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ
您可以安全地將此純文本推送到共享git存儲庫,并且保密密碼。
服務(wù)器還暴露了/encrypt和/decrypt端點(假設(shè)這些端點將被保護,并且只能由授權(quán)代理訪問)。如果您正在編輯遠程配置文件,可以使用Config Server通過POST到/encrypt端點來加密值,例如
$ curl localhost:8888/encrypt -d mysecret
682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
注意如果要加密的值具有需要進行URL編碼的字符,則應(yīng)使用--data-urlencode選項curl來確保它們已正確編碼。
逆向操作也可通過/decrypt獲得(如果服務(wù)器配置了對稱密鑰或全密鑰對):
$ curl localhost:8888/decrypt -d 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
mysecret
提示如果您使用curl進行測試,則使用--data-urlencode(而不是-d)或設(shè)置顯式Content-Type:
text/plain,以確保在有特殊字符時正確地對數(shù)據(jù)進行編碼('+'特別是棘手)。
將加密的值添加到{cipher}前綴,然后再將其放入YAML或?qū)傩晕募?,然后再提交并將其推送到遠程可能不安全的存儲區(qū)。
/encrypt和/decrypt端點也都接受/*/{name}/{profiles}形式的路徑,當(dāng)客戶端調(diào)用到主環(huán)境資源時,可以用于每個應(yīng)用程序(名稱)和配置文件控制密碼。
注意為了以這種細微的方式控制密碼,您還必須提供一種TextEncryptorLocator類型的@Bean,可以為每個名稱和配置文件創(chuàng)建不同的加密器。默認提供的不會這樣做(所有加密使用相同的密鑰)。
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.pub
AQAjPgt3eFZQXwt8tsHAVv/QHiY5sI2dRcR+...
關(guān)鍵參數(shù)是強制性的(盡管有一個--前綴)。
密鑰管理
Config Server可以使用對稱(共享)密鑰或非對稱密鑰(RSA密鑰對)。非對稱選擇在安全性方面是優(yōu)越的,但是使用對稱密鑰往往更方便,因為它只是配置的一個屬性值。
要配置對稱密鑰,您只需要將encrypt.key設(shè)置為一個秘密字符串(或使用環(huán)境變量ENCRYPT_KEY將其從純文本配置文件中刪除)。
要配置非對稱密鑰,您可以將密鑰設(shè)置為PEM編碼的文本值(encrypt.key),也可以通過密鑰庫設(shè)置密鑰(例如由JDK附帶的keytool實用程序創(chuàng)建)。密鑰庫屬性為encrypt.keyStore.*,*等于
location(aResource位置),
password(解鎖密鑰庫)和
alias(以識別商店中使用的密鑰)。
使用公鑰進行加密,需要私鑰進行解密。因此,原則上您只能在服務(wù)器中配置公鑰,如果您只想進行加密(并準(zhǔn)備使用私鑰本地解密值)。實際上,您可能不想這樣做,因為它圍繞所有客戶端傳播密鑰管理流程,而不是將其集中在服務(wù)器中。另一方面,如果您的配置服務(wù)器真的相對不安全,并且只有少數(shù)客戶端需要加密的屬性,這是一個有用的選項。
創(chuàng)建用于測試的密鑰庫
要創(chuàng)建一個密鑰庫進行測試,您可以執(zhí)行以下操作:
$ 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文件放在類路徑(例如)中,然后在您的application.yml中配置服務(wù)器:
encrypt:
? keyStore:
? ? location: classpath:/server.jks
? ? password: letmein
? ? alias: mytestkey
? ? secret: changeme
使用多個鍵和鍵旋轉(zhuǎn)
除了加密屬性值中的{cipher}前綴之外,配置服務(wù)器在(Base64編碼)密文開始前查找{name:value}前綴(零或多個)。密鑰被傳遞給TextEncryptorLocator,它可以執(zhí)行找到密碼的TextEncryptor所需的任何邏輯。如果配置了密鑰庫(encrypt.keystore.location),默認定位器將使用“key”前綴提供的別名,即使用如下密碼查找存儲中的密鑰:
foo:
? bar: `{cipher}{key:testkey}...`
定位器將尋找一個名為“testkey”的鍵。也可以通過前綴中的{secret:…?}值提供一個秘密,但是如果不是默認值,則使用密鑰庫密碼(這是您在構(gòu)建密鑰庫時獲得的,并且不指定密碼)。如果你這樣做提供一個秘密建議你也加密使用自定義SecretLocator的秘密。
如果密鑰只用于加密幾個字節(jié)的配置數(shù)據(jù)(即它們沒有在其他地方使用),則密碼轉(zhuǎn)換幾乎不是必需的,但是如果存在安全漏洞,有時您可能需要更改密鑰實例。在這種情況下,所有客戶端都需要更改其源配置文件(例如,以git格式),并在所有密碼中使用新的{key:…?}前綴,當(dāng)然事先檢查密鑰別名在配置服務(wù)器密鑰庫中是否可用。
提示如果要讓Config Server處理所有加密以及解密,也可以將{name:value}前綴添加到發(fā)布到/encrypt端點的明文中。
服務(wù)加密Properties
有時您希望客戶端在本地解密配置,而不是在服務(wù)器中進行配置。在這種情況下,您仍然可以擁有/加密和解密端點(如果您提供encrypt.*配置來定位密鑰),但是您需要使用spring.cloud.config.server.encrypt.enabled=false明確地關(guān)閉傳出屬性的解密。如果您不關(guān)心端點,那么如果您既不配置密鑰也不配置使能的標(biāo)志,則應(yīng)該起作用。