Spring Cloud Config 服务器
Spring Cloud Config Server 为外部配置(名称-值对或等效的 YAML 内容)提供了一个基于 HTTP 资源的 API。
服务器可以嵌入到 Spring Boot 应用程序中,方法是使用@EnableConfigServer
注解。
因此,以下应用程序是配置服务器:
@SpringBootApplication
@EnableConfigServer
public class ConfigServer {
public static void main(String[] args) {
SpringApplication.run(ConfigServer.class, args);
}
}
与所有 Spring Boot 应用程序一样,它默认在端口 8080 上运行,但您可以通过多种方式将其切换到更传统的端口 8888。
最简单的方法(也设置了默认配置存储库)是使用spring.config.name=configserver
(有一个configserver.yml
在 Config Server jar 中)。
另一种是使用自己的application.properties
,如以下示例所示:
server.port: 8888
spring.cloud.config.server.git.uri: file://${user.home}/config-repo
哪里${user.home}/config-repo
是一个包含 YAML 和属性文件的 git 存储库。
在 Windows 上,如果文件 URL 是带有驱动器前缀的绝对值(例如,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
(包括propertySources
作为主要特征)。
这Environment
资源由三个变量参数化:
-
{application}
,映射到spring.application.name
在客户端。 -
{profile}
,映射到spring.profiles.active
在客户端上(逗号分隔列表)。 -
{label}
,这是一个服务器端功能,标记了一组“版本化”配置文件。
存储库实现通常表现得像 Spring Boot 应用程序,从spring.config.name
等于{application}
参数,以及spring.profiles.active
等于{profiles}
参数。
配置文件的优先级规则也与常规 Spring Boot 应用程序中的相同:活动配置文件优先于默认值,如果有多个配置文件,则最后一个优先(类似于将条目添加到Map
).
以下示例客户端应用程序具有此引导配置:
spring:
application:
name: foo
profiles:
active: dev,mysql
(与 Spring Boot 应用程序一样,这些属性也可以由环境变量或命令行参数设置)。
如果存储库是基于文件的,则服务器会创建一个Environment
从application.yml
(在所有客户端之间共享)和foo.yml
(与foo.yml
优先)。
如果 YAML 文件中包含指向 Spring 配置文件的文档,则这些文档将以更高的优先级应用(按列出的配置文件的顺序)。
如果存在特定于配置文件的 YAML(或属性)文件,则这些文件的应用优先级也高于默认值。
更高的优先级转换为PropertySource
在前面的Environment
.
(这些相同的规则适用于独立的 Spring Boot 应用程序。
您可以将spring.cloud.config.server.accept-empty设置为false,以便在找不到应用程序时Server将返回HTTP 404状态。默认情况下,此标志设置为 true。
Git 后端
默认实现EnvironmentRepository
使用 Git 后端,这对于管理升级和物理环境以及审计更改非常方便。
要更改存储库的位置,您可以将spring.cloud.config.server.git.uri
配置服务器中的配置属性(例如,在application.yml
).
如果将其设置为file:
前缀,它应该从本地存储库工作,这样您就可以在没有服务器的情况下快速轻松地开始使用。但是,在这种情况下,服务器直接在本地存储库上运行,而无需克隆它(如果它不是裸露的也没关系,因为配置服务器永远不会对“远程”存储库进行更改)。
要纵向扩展配置服务器并使其高可用性,您需要让服务器的所有实例都指向同一个存储库,因此只有共享文件系统才能工作。
即使在这种情况下,最好使用ssh:
协议,以便服务器可以克隆它并使用本地工作副本作为缓存。
此存储库实现映射{label}
参数添加到 git 标签(提交 ID、分支名称或标签)。
如果 git 分支或标签名称包含斜杠 (),则应使用特殊字符串指定 HTTP URL 中的标签(以避免与其他 URL 路径产生歧义)。
例如,如果标签是/
(_)
foo/bar
,替换斜杠将导致以下标签:foo(_)bar
.
特殊字符串的包含也可以应用于(_)
{application}
参数。
如果您使用 curl 等命令行客户端,请小心 URL 中的括号 - 您应该用单引号 ('') 将它们从 shell 中转义。
跳过 SSL 证书验证
可以通过设置git.skipSslValidation
属性设置为true
(默认值为false
).
spring:
cloud:
config:
server:
git:
uri: https://example.com/my/repo
skipSslValidation: true
设置 HTTP 连接超时
您可以配置配置服务器等待获取 HTTP 连接的时间(以秒为单位)。使用git.timeout
财产。
spring:
cloud:
config:
server:
git:
uri: https://example.com/my/repo
timeout: 4
Git URI 中的占位符
Spring Cloud Config Server 支持带有{application}
和{profile}
(和{label}
如果需要,但请记住,无论如何,标签都是作为 Git 标签应用的)。
因此,可以使用类似于以下内容的结构来支持“每个应用程序一个存储库”策略:
spring:
cloud:
config:
server:
git:
uri: https://github.com/myorg/{application}
您还可以使用类似的模式来支持“每个配置文件一个存储库”策略,但使用{profile}
.
此外,在{application}
参数可以启用对多个
组织,如以下示例所示:
spring:
cloud:
config:
server:
git:
uri: https://github.com/{application}
哪里{application}
在请求时以以下格式提供:organization(_)application
.
模式匹配和多个存储库
Spring Cloud Config 还包括对更复杂的要求的支持,其中包含 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}
不匹配任何模式,它使用在spring.cloud.config.server.git.uri
.
在上面的示例中,对于“简单”存储库,模式为simple/*
(它仅匹配一个名为simple
在所有配置文件中)。“本地”存储库匹配以local
在所有配置文件中(后缀会自动添加到任何没有配置文件匹配器的模式)。/*
“简单”示例中使用的“单行”快捷方式仅当要设置的唯一属性是 URI 时才能使用。 如果您需要设置任何其他内容(凭据、模式等),则需要使用完整表单。 |
这pattern
属性实际上是一个数组,因此您可以使用 YAML 数组(或[0]
,[1]
等属性文件中的后缀)绑定到多个模式。如果您要运行具有多个配置文件的应用程序,则可能需要这样做,如以下示例所示:
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,*"] ,依此类推)。例如,您需要在本地运行“开发”配置文件中的应用程序,但也需要远程运行“云”配置文件中的应用程序,这很常见。 |
每个存储库还可以选择将配置文件存储在子目录中,并且搜索这些目录的模式可以指定为search-paths
. 以下示例显示了顶层的配置文件:
spring:
cloud:
config:
server:
git:
uri: https://github.com/spring-cloud-samples/config-repo
search-paths:
- 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: https://git/team-a/config-repo.git
team-b:
pattern: team-b-*
cloneOnStart: false
uri: https://git/team-b/config-repo.git
team-c:
pattern: team-c-*
uri: https://git/team-a/config-repo.git
在前面的示例中,服务器在启动时克隆 team-a 的 config-repo,在它之前 接受任何请求。 在请求存储库的配置之前,不会克隆所有其他存储库。
将存储库设置为在配置服务器启动时克隆,有助于在配置服务器启动时快速识别配置错误的配置源(例如无效的存储库 URI)。
跟cloneOnStart 未为配置源启用,则配置服务器可能会在配置错误或无效的配置源的情况下成功启动,并且在应用程序从该配置源请求配置之前不会检测到错误。 |
认证
要在远程存储库上使用 HTTP 基本身份验证,请将username
和password
属性(不在 URL 中),如以下示例所示:
spring:
cloud:
config:
server:
git:
uri: https://github.com/spring-cloud-samples/config-repo
username: trolley
password: strongpassword
如果您不使用 HTTPS 和用户凭据,当您将密钥存储在默认目录 (~/.ssh
),URI 指向 SSH 位置,例如[email protected]:configuration/cloud-configuration
.
Git 服务器的条目必须存在于~/.ssh/known_hosts
文件,并且它位于ssh-rsa
格式。
其他格式(例如ecdsa-sha2-nistp256
) 不支持。
为避免意外,应确保known_hosts
文件,并且它与您提供给配置服务器的 URL 匹配。
如果您在 URL 中使用主机名,则希望在known_hosts
文件。
该存储库是使用 JGit 访问的,因此您在其中找到的任何文档都应该适用。
HTTPS 代理设置可以在~/.git/config
或者(与任何其他 JVM 进程相同)与
系统属性 (-Dhttps.proxyHost
和-Dhttps.proxyPort
).
如果您不知道您的~/.git 目录是,使用git config --global 以作设置(例如,git config --global http.sslVerify false ). |
JGit 需要 PEM 格式的 RSA 密钥。下面是一个示例 ssh-keygen(来自 openssh)命令,它将生成 corect 格式的密钥:
ssh-keygen -m PEM -t rsa -b 4096 -f ~/config_server_deploy_key.rsa
警告:使用 SSH 密钥时,预期的 ssh 私钥必须以
.如果键以-----BEGIN RSA PRIVATE KEY-----
则 RSA 密钥将不会在启动 spring-cloud-config 服务器时加载。错误如下所示:-----BEGIN OPENSSH PRIVATE KEY-----
- Error in object 'spring.cloud.config.server.git': codes [PrivateKeyIsValid.spring.cloud.config.server.git,PrivateKeyIsValid]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [spring.cloud.config.server.git.,]; arguments []; default message []]; default message [Property 'spring.cloud.config.server.git.privateKey' is not a valid private key]
要纠正上述错误,必须将 RSA 密钥转换为 PEM 格式。上面提供了一个使用 openssh 以适当格式生成新密钥的示例。
使用 AWS CodeCommit 进行身份验证
Spring Cloud Config Server 还支持 AWS CodeCommit 身份验证。 AWS CodeCommit 在从命令行使用 Git 时使用身份验证帮助程序。 此帮助程序不与 JGit 库一起使用,因此如果 Git URI 与 AWS CodeCommit 模式匹配,则会为 AWS CodeCommit 创建 JGit CredentialProvider。 AWS CodeCommit URI 遵循以下模式:
https//git-codecommit.${AWS_REGION}.amazonaws.com/v1/repos/${repo}.
如果您使用 AWS CodeCommit URI 提供用户名和密码,则它们必须是提供对存储库的访问权限的 AWS accessKeyId 和 secretAccessKey。 如果您未指定用户名和密码,则使用 AWS 默认凭证提供程序链检索 accessKeyId 和 secretAccessKey。
如果您的 Git URI 与 CodeCommit URI 模式匹配(如上所示),则必须在用户名和密码中或在默认凭证提供程序链支持的位置之一提供有效的 AWS 凭证。AWS EC2 实例可以对 EC2 实例使用 IAM 角色。
这aws-java-sdk-core jar 是一个可选的依赖项。如果aws-java-sdk-core jar 不在您的类路径上,则不会创建 AWS Code Commit 凭证提供程序,无论 git 服务器 URI 如何。 |
使用 Google Cloud Source 进行身份验证
Spring Cloud Config Server 还支持针对 Google Cloud Source 存储库进行身份验证。
如果您的 Git URI 使用http
或https
协议,域名为source.developers.google.com
,则将使用 Google Cloud Source 凭据提供程序。Google Cloud Source 代码库 URI 的格式为https://source.developers.google.com/p/${GCP_PROJECT}/r/${REPO}
.要获取代码库的 URI,请点击 Google Cloud 源代码界面中的“克隆”,然后选择“手动生成的凭据”。不要生成任何凭据,只需复制显示的 URI。
Google Cloud Source 凭据提供程序将使用 Google Cloud Platform 应用程序默认凭据。请参阅 Google Cloud SDK 文档,了解如何为系统创建应用默认凭据。此方法适用于开发环境中的用户帐户和生产环境中的服务帐户。
com.google.auth:google-auth-library-oauth2-http 是可选的依赖项。
如果google-auth-library-oauth2-http jar 不在您的类路径上,则不会创建 Google Cloud Source 凭据提供程序,无论 git 服务器 URI 如何。 |
使用属性的 Git SSH 配置
默认情况下,Spring Cloud Config Server 使用的 JGit 库使用 SSH 配置文件,例如~/.ssh/known_hosts
和/etc/ssh/ssh_config
使用 SSH URI 连接到 Git 存储库时。
在 Cloud Foundry 等云环境中,本地文件系统可能是短暂的或不易访问的。
对于这些情况,可以使用 Java 属性设置 SSH 配置。
为了激活基于属性的 SSH 配置,请spring.cloud.config.server.git.ignoreLocalSshSettings
属性必须设置为true
,如以下示例所示:
spring:
cloud:
config:
server:
git:
uri: [email protected]: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-----
下表介绍了 SSH 配置属性。
属性名称 | 言论 |
---|---|
忽略 LocalSshSettings |
如果 |
私钥 |
有效的 SSH 私钥。如果出现以下情况,则必须设置 |
主机密钥 |
有效的 SSH 主机密钥。如果出现以下情况,则必须设置 |
hostKey算法 |
其中之一 |
strictHostKey检查 |
|
已知主机文件 |
自定义位置 |
preferredAuthentications |
覆盖服务器身份验证方法顺序。如果服务器在 |
Git 搜索路径中的占位符
Spring Cloud Config Server 还支持带有占位符的搜索路径{application}
和{profile}
(和{label}
如果
你需要它),如以下示例所示:
spring:
cloud:
config:
server:
git:
uri: https://github.com/spring-cloud-samples/config-repo
search-paths: '{application}'
前面的列表会导致在存储库中搜索与目录(以及顶级)同名的文件。 通配符在带有占位符的搜索路径中也有效(任何匹配的目录都包含在搜索中)。
在 Git 存储库中强制拉取
如前所述,Spring Cloud Config Server 会克隆远程 git 存储库,以防本地副本变脏(例如, 文件夹内容由作系统进程更改),因此 Spring Cloud Config Server 无法从远程存储库更新本地副本。
为了解决这个问题,有一个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: https://git/team-a/config-repo.git
force-pull: true
team-b:
pattern: team-b-*
uri: https://git/team-b/config-repo.git
force-pull: true
team-c:
pattern: team-c-*
uri: https://git/team-a/config-repo.git
的默认值force-pull 属性是false . |
删除 Git 存储库中未跟踪的分支
由于 Spring Cloud Config Server 具有远程 git 存储库的克隆
将分支签出到本地存储库后(例如,按标签获取属性),它将保留此分支
永远或直到下一次服务器重新启动(这将创建新的本地存储库)。
因此,可能会出现远程分支被删除但仍然可以获取它的本地副本的情况。
如果 Spring Cloud Config Server 客户端服务以--spring.cloud.config.label=deletedRemoteBranch,master
它将从deletedRemoteBranch
local 分支,但不是来自master
.
为了保持本地存储库分支干净并达到远程状态 -deleteUntrackedBranches
属性可以设置。
它将使 Spring Cloud Config Server 从本地存储库中强制删除未跟踪的分支。
例:
spring:
cloud:
config:
server:
git:
uri: https://github.com/spring-cloud-samples/config-repo
deleteUntrackedBranches: true
的默认值deleteUntrackedBranches 属性是false . |
Git 刷新率
您可以控制配置服务器获取更新配置数据的频率
使用spring.cloud.config.server.git.refreshRate
.这
此属性的值以秒为单位指定。默认情况下,该值为 0,这意味着
配置服务器每次都会从 Git 存储库中获取更新的配置
被要求。
版本控制后端文件系统使用
使用基于 VCS 的后端(git、svn),文件被检出或克隆到本地文件系统。
默认情况下,它们被放置在系统临时目录中,前缀为config-repo- .
例如,在 Linux 上,它可能是/tmp/config-repo-<randomid> .
某些作系统会定期清理临时目录。
这可能会导致意外行为,例如缺少属性。
要避免此问题,请通过将spring.cloud.config.server.git.basedir 或spring.cloud.config.server.svn.basedir 到不驻留在系统临时结构中的目录。 |
文件系统后端
配置服务器中还有一个“本机”配置文件,它不使用 Git,但从本地类路径或文件系统(您想要指向的任何静态 URLspring.cloud.config.server.native.searchLocations
). 要使用本机配置文件,请使用spring.profiles.active=native
.
请记住使用file: 文件资源的前缀(没有前缀的默认值通常是类路径)。与任何 Spring Boot 配置一样,您可以嵌入 -style 环境占位符,但请记住,Windows 中的绝对路径需要额外的(例如${} / file:///${user.home}/config-repo ). |
默认值searchLocations 与本地 Spring Boot 应用程序相同(即,[classpath:/, classpath:/config,
file:./, file:./config] ).
这不会公开application.properties 从服务器到所有客户端,因为服务器中存在的任何属性源在发送到客户端之前都会被删除。 |
文件系统后端非常适合快速入门和测试。 要在生产环境中使用它,您需要确保文件系统可靠并在 Config Server 的所有实例之间共享。 |
搜索位置可以包含{application}
,{profile}
和{label}
.
通过这种方式,您可以隔离路径中的目录,并选择对您有意义的策略(例如每个应用程序的子目录或每个配置文件的子目录)。
如果未在搜索位置中使用占位符,则此存储库还会将{label}
参数添加到搜索路径上的后缀,因此从每个搜索位置和与标签同名的子目录加载属性文件(标记的属性在 Spring 环境中优先)。
因此,没有占位符的默认行为与添加以/{label}/
.
例如file:/tmp/config
与file:/tmp/config,file:/tmp/config/{label}
.
可以通过将spring.cloud.config.server.native.addLabelLocations=false
.
Vault 后端
Spring Cloud Config Server 还支持 Vault 作为后端。
有关 Vault 的更多信息,请参阅 Vault 快速入门指南。
要使配置服务器能够使用 Vault 后端,您可以使用vault
轮廓。
例如,在配置服务器的application.properties
,您可以添加spring.profiles.active=vault
.
默认情况下,配置服务器假定您的 Vault 服务器运行在http://127.0.0.1:8200
.
它还假设后端的名称是secret
关键是application
.
所有这些默认值都可以在配置服务器的application.properties
.
下表描述了可配置的 Vault 属性:
名称 | 默认值 |
---|---|
主机 |
127.0.0.1 |
端口 |
8200 |
方案 |
http |
后端 |
秘密 |
defaultKey |
应用 |
轮廓分离器 |
, |
kv版本 |
1 |
skipSsl验证 |
false |
超时 |
5 |
Namespace |
零 |
上表中的所有属性都必须以spring.cloud.config.server.vault 或放置在复合配置的正确 Vault 部分中。 |
所有可配置的属性都可以在org.springframework.cloud.config.server.environment.VaultEnvironmentProperties
.
Vault 0.10.0 引入了版本化的键值后端(k/v 后端版本 2),它公开了与早期版本不同的 API,它现在需要data/ 在挂载路径和实际上下文路径之间,并将密钥包装在data 对象。设置spring.cloud.config.server.vault.kv-version=2 将考虑到这一点。 |
(可选)支持 Vault EnterpriseX-Vault-Namespace
页眉。要将其发送到 Vault,请将namespace
财产。
在配置服务器运行的情况下,您可以向服务器发出 HTTP 请求以检索 Vault 后端的值。 为此,您需要一个保管库服务器的Tokens。
首先,将一些数据放入 Vault 中,如以下示例所示:
$ vault kv put secret/application foo=bar baz=bam
$ vault kv put 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"
}
}
]
}
客户端提供必要的身份验证以让 Config Server 与 Vault 通信的默认方法是设置 X-Config-Token 标头。
但是,您可以通过设置与 Spring Cloud Vault 相同的配置属性来省略标头并在服务器中配置身份验证。
要设置的属性是spring.cloud.config.server.vault.authentication
.
它应设置为受支持的身份验证方法之一。
您可能还需要使用与spring.cloud.vault
而是使用spring.cloud.config.server.vault
前缀。
有关更多详细信息,请参阅 Spring Cloud Vault 参考指南。
如果省略 X-Config-Token 标头并使用服务器属性来设置身份验证,则 Config Server 应用程序需要对 Spring Vault 的额外依赖才能启用其他身份验证选项。 有关如何添加该依赖项,请参阅 Spring Vault 参考指南。 |
多个属性源
使用 Vault 时,您可以为应用程序提供多个属性源。 例如,假设您已将数据写入 Vault 中的以下路径:
secret/myApp,dev
secret/myApp
secret/application,dev
secret/application
写入的属性secret/application
适用于所有使用 Config Server 的应用程序。
名称为myApp
,将有任何属性写入secret/myApp
和secret/application
可供它使用。
什么时候myApp
具有dev
启用配置文件后,写入上述所有路径的属性将可供其使用,列表中第一个路径中的属性优先于其他路径。
通过代理访问后端
配置服务器可以通过 HTTP 或 HTTPS 代理访问 Git 或 Vault 后端。Git 或 Vault 的此行为由proxy.http
和proxy.https
.这些设置是按存储库设置的,因此,如果您使用的是复合环境存储库,则必须单独为复合中的每个后端配置代理设置。如果使用需要单独代理服务器的 HTTP 和 HTTPS URL 的网络,则可以为单个后端配置 HTTP 和 HTTPS 代理设置。
下表描述了 HTTP 和 HTTPS 代理的代理配置属性。所有这些属性都必须以proxy.http
或proxy.https
.
属性名称 | 言论 |
---|---|
主机 |
代理的主机。 |
端口 |
用于访问代理的端口。 |
非代理主机 |
配置服务器应在代理外部访问的任何主机。如果为两者提供值 |
用户名 |
用于向代理进行身份验证的用户名。如果为两者提供值 |
密码 |
用于向代理进行身份验证的密码。如果为两者提供值 |
以下配置使用 HTTPS 代理访问 Git 存储库。
spring:
profiles:
active: git
cloud:
config:
server:
git:
uri: https://github.com/spring-cloud-samples/config-repo
proxy:
https:
host: my-proxy.host.io
password: myproxypassword
port: '3128'
username: myproxyusername
nonProxyHosts: example.com
与所有应用程序共享配置
所有应用程序之间的共享配置因您采用的方法而异,如以下主题中所述:
基于文件的存储库
使用基于文件(git、svn 和本机)的存储库,文件名在application*
(application.properties
,application.yml
,application-*.properties
,依此类推)在所有客户端应用程序之间共享。
您可以使用具有这些文件名的资源来配置全局默认值,并根据需要由特定于应用程序的文件覆盖它们。
属性覆盖功能还可用于设置全局默认值,以及占位符应用程序 允许在本地覆盖它们。
对于“本机”配置文件(本地文件系统后端),您应该使用不属于服务器自身配置的显式搜索位置。
否则,application* 默认搜索位置中的资源将被删除,因为它们是服务器的一部分。 |
Vault 服务器
使用 Vault 作为后端时,您可以通过将配置放在secret/application
.
例如,如果运行以下 Vault 命令,则使用配置服务器的所有应用程序都将具有foo
和baz
可供他们使用:
$ vault write secret/application foo=bar baz=bam
CredHub 服务器
将 CredHub 用作后端时,您可以通过将配置放在/application/
或者将其放在default
应用程序的配置文件。
例如,如果您运行以下 CredHub 命令,则使用配置服务器的所有应用程序都将具有shared.color1
和shared.color2
可供他们使用:
credhub set --name "/application/profile/master/shared" --type=json
value: {"shared.color1": "blue", "shared.color": "red"}
credhub set --name "/my-app/default/master/more-shared" --type=json
value: {"shared.word1": "hello", "shared.word2": "world"}
JDBC 后端
Spring Cloud Config Server 支持 JDBC(关系数据库)作为配置属性的后端。
您可以通过添加spring-jdbc
添加到类路径,并使用jdbc
profile 或通过添加类型为JdbcEnvironmentRepository
.
如果您在类路径上包含正确的依赖项(有关更多详细信息,请参阅用户指南),Spring Boot 将配置一个数据源。
您可以禁用JdbcEnvironmentRepository
通过将spring.cloud.config.server.jdbc.enabled
属性设置为false
.
数据库需要有一个名为PROPERTIES
列名为APPLICATION
,PROFILE
和LABEL
(与通常的Environment
意思),加上KEY
和VALUE
对于Properties
风格。
所有字段在 Java 中都是 String 类型,因此您可以将它们VARCHAR
无论您需要什么长度。
属性值的行为方式与它们来自名为{application}-{profile}.properties
,包括所有加密和解密,这些加密和解密将作为后处理步骤应用(即,不直接在存储库实现中)。
Redis 后端
Spring Cloud Config Server 支持 Redis 作为配置属性的后端。 您可以通过向 Spring Data Redis 添加依赖项来启用此功能。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
以下配置使用 Spring DataRedisTemplate
访问 Redis。我们可以使用spring.redis.*
属性以覆盖默认连接设置。
spring:
profiles:
active: redis
redis:
host: redis
port: 16379
属性应存储为哈希中的字段。哈希的名称应与spring.application.name
属性或连词spring.application.name
和spring.profiles.active[n]
.
HMSET sample-app server.port "8100" sample.topic.name "test" test.property1 "property1"
运行上面可见的命令后,哈希值应包含以下带有值的键:
HGETALL sample-app { "server.port": "8100", "sample.topic.name": "test", "test.property1": "property1" }
未指定配置文件时default 将被使用。 |
AWS S3 后端
Spring Cloud Config Server 支持 AWS S3 作为配置属性的后端。 您可以通过向适用于 Amazon S3 的 AWS Java 开发工具包添加依赖项来启用此功能。
<dependencies>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
</dependency>
</dependencies>
以下配置使用 AWS S3 客户端访问配置文件。我们可以使用spring.awss3.*
属性以选择存储配置的存储桶。
spring:
profiles:
active: awss3
cloud:
config:
server:
awss3:
region: us-east-1
bucket: bucket1
还可以指定 AWS URL 以覆盖 S3 服务的标准终端节点spring.awss3.endpoint
.这允许支持 S3 的测试版区域和其他 S3 兼容的存储 API。
使用默认 AWS 凭证提供程序链查找凭证。支持版本化和加密存储桶,无需进一步配置。
配置文件存储在您的存储桶中作为{application}-{profile}.properties
,{application}-{profile}.yml
或{application}-{profile}.json
.可以提供可选标签来指定文件的目录路径。
未指定配置文件时default 将被使用。 |
CredHub 后端
Spring Cloud Config Server 支持 CredHub 作为配置属性的后端。 您可以通过向 Spring CredHub 添加依赖项来启用此功能。
<dependencies>
<dependency>
<groupId>org.springframework.credhub</groupId>
<artifactId>spring-credhub-starter</artifactId>
</dependency>
</dependencies>
以下配置使用双向 TLS 访问 CredHub:
spring:
profiles:
active: credhub
cloud:
config:
server:
credhub:
url: https://credhub:8844
属性应存储为 JSON,例如:
credhub set --name "/demo-app/default/master/toggles" --type=json
value: {"toggle.button": "blue", "toggle.link": "red"}
credhub set --name "/demo-app/default/master/abs" --type=json
value: {"marketing.enabled": true, "external.enabled": false}
名称为spring.cloud.config.name=demo-app
将具有以下属性可供他们使用:
{ toggle.button: "blue", toggle.link: "red", marketing.enabled: true, external.enabled: false }
未指定配置文件时default 将使用,并且未指定标签master 将用作默认值。
注意:添加到application 将由所有应用程序共享。 |
OAuth 2.0
<dependencies>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
</dependency>
</dependencies>
以下配置使用 OAuth 2.0 和 UAA 访问 CredHub:
spring:
profiles:
active: credhub
cloud:
config:
server:
credhub:
url: https://credhub:8844
oauth2:
registration-id: credhub-client
security:
oauth2:
client:
registration:
credhub-client:
provider: uaa
client-id: credhub_config_server
client-secret: asecret
authorization-grant-type: client_credentials
provider:
uaa:
token-uri: https://uaa:8443/oauth/token
使用的 UAA 客户端 ID 应具有credhub.read 作为范围。 |
复合环境存储库
在某些情况下,您可能希望从多个环境存储库中提取配置数据。
为此,您可以启用composite
配置文件。
例如,如果要从一个 Subversion 存储库和两个 Git 存储库中提取配置数据,则可以为配置服务器设置以下属性:
spring:
profiles:
active: composite
cloud:
config:
server:
composite:
-
type: svn
uri: file:///path/to/svn/repo
-
type: git
uri: file:///path/to/rex/git/repo
-
type: git
uri: file:///path/to/walter/git/repo
使用此配置,优先级由存储库在composite
钥匙。
在上面的示例中,首先列出了 Subversion 存储库,因此在 Subversion 存储库中找到的值将覆盖在其中一个 Git 存储库中找到的同一属性的值。
在rex
Git 存储库将在walter
Git 存储库。
如果只想从每种类型不同的存储库中提取配置数据,则可以启用相应的配置文件,而不是composite
配置文件,位于配置服务器的应用程序属性或 YAML 文件中。
例如,如果要从单个 Git 存储库和单个 HashiCorp Vault 服务器中提取配置数据,则可以为配置服务器设置以下属性:
spring:
profiles:
active: git, vault
cloud:
config:
server:
git:
uri: file:///path/to/git/repo
order: 2
vault:
host: 127.0.0.1
port: 8200
order: 1
使用此配置,优先级可以通过order
财产。
您可以使用order
属性来指定所有存储库的优先级顺序。
的数值越低order
属性,其优先级越高。
存储库的优先级顺序有助于解决包含相同属性值的存储库之间的任何潜在冲突。
如果组合环境包含 Vault 服务器,如上例所示,则必须在向配置服务器发出的每个请求中包含 Vault Tokens。请参阅 Vault 后端。 |
从环境存储库检索值时,任何类型的故障都会导致整个复合环境失败。
如果您希望复合在存储库发生故障时继续,您可以将spring.cloud.config.server.failOnCompositeError 自false . |
使用复合环境时,所有存储库都包含相同的标签非常重要。
如果您的环境与前面示例中的环境类似,并且您使用master 标签,但 Subversion 存储库不包含名为master ,则整个请求失败。 |
自定义复合环境存储库
除了使用 Spring Cloud 中的环境存储库之一外,您还可以提供自己的EnvironmentRepository
bean 作为复合环境的一部分包含在内。
为此,您的 Bean 必须实现EnvironmentRepository
接口。
如果您想控制自定义的优先级EnvironmentRepository
在复合环境中,还应实现Ordered
接口并覆盖getOrdered
方法。
如果您不实现Ordered
界面,您的EnvironmentRepository
被赋予最低优先级。
属性覆盖
配置服务器具有“覆盖”功能,允许操作员向所有应用程序提供配置属性。
使用普通 Spring Boot 钩子的应用程序不会意外更改覆盖的属性。
要声明覆盖,请将名称-值对的映射添加到spring.cloud.config.server.overrides
,如以下示例所示:
spring:
cloud:
config:
server:
overrides:
foo: bar
上述示例导致作为配置客户端的所有应用程序读取foo=bar
,独立于自己的配置。
配置系统不能强制应用程序以任何特定方式使用配置数据。 因此,覆盖是不可执行的。 但是,它们确实为 Spring Cloud Config 客户端提供了有用的默认行为。 |
通常,可以通过使用反斜杠 () 转义 或 .
例如${} \ $ { \${app.foo:bar} 解析为bar ,除非应用程序提供自己的app.foo . |
在 YAML 中,您不需要转义反斜杠本身。 但是,在属性文件中,当您在服务器上配置覆盖时,您确实需要转义反斜杠。 |
您可以将客户端中所有覆盖的优先级更改为更像默认值,让应用程序在环境变量或系统属性中提供自己的值,方法是将spring.cloud.config.overrideNone=true
标志(默认值为 false)。
健康指标
Config Server 附带一个运行状况指示器,用于检查配置的EnvironmentRepository
正在发挥作用。
默认情况下,它会询问EnvironmentRepository
对于名为app
这default
profile,以及EnvironmentRepository
实现。
您可以配置运行状况指示器以检查更多应用程序以及自定义配置文件和自定义标签,如以下示例所示:
spring:
cloud:
config:
server:
health:
repositories:
myservice:
label: mylabel
myservice-dev:
name: myservice
profiles: development
您可以通过设置management.health.config.enabled=false
.
安全
您可以通过任何对您有意义的方式(从物理网络安全到 OAuth2 持有者Tokens)来保护您的 Config Server,因为 Spring Security 和 Spring Boot 提供了对许多安全安排的支持。
要使用默认的 Spring Boot 配置的 HTTP Basic 安全性,请在类路径上包含 Spring Security(例如,通过spring-boot-starter-security
).
默认值是用户名user
以及随机生成的密码。随机密码在实践中没有用处,因此我们建议您配置密码(通过将spring.security.user.password
) 并对其进行加密(有关如何执行此作的说明,请参阅下文)。
执行器和安全
某些平台配置运行状况检查或类似内容并指向/actuator/health 或其他执行器端点。如果执行器不是配置服务器的依赖项,则请求/actuator/ 将与配置服务器 API 匹配/{application}/{label} 可能泄露安全信息。记得添加spring-boot-starter-actuator 依赖项,并配置用户,以便调用/actuator/ 无权访问位于/{application}/{label} . |
加密和解密
要使用加密和解密功能,您需要在 JVM 中安装全强度 JCE(默认情况下不包括在内)。 您可以从 Oracle 下载“Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files”,然后按照安装说明进行作(本质上,您需要将 JRE lib/security 目录中的两个策略文件替换为下载的文件)。 |
如果远程属性源包含加密内容(以{cipher}
),它们在通过 HTTP 发送到客户端之前被解密。此设置的主要优点是,当属性值处于“静态”状态时(例如,在 git 存储库中),它们不需要是纯文本的。如果无法解密某个值,则会从属性源中删除该值,并添加具有相同键但前缀为invalid
以及表示“不适用”的值(通常<n/a>
). 这主要是为了防止密文被用作密码并意外泄露。
如果您为配置客户端应用程序设置远程配置存储库,它可能包含一个application.yml
类似于以下内容:
spring:
datasource:
username: dbuser
password: '{cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ'
中的加密值application.properties
文件不得用引号括起来。否则,不会解密该值。以下示例显示了有效的值:
spring.datasource.username: dbuser spring.datasource.password: {cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ
您可以安全地将此纯文本推送到共享的 git 存储库,并且秘密密码仍然受到保护。
服务器还公开/encrypt
和/decrypt
端点(假设这些是安全的并且只能由授权代理访问)。如果您编辑远程配置文件,则可以使用配置服务器通过将 POST 到/encrypt
端点,如以下示例所示:
$ curl localhost:8888/encrypt -s -d mysecret 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
如果你使用 curl 进行测试,则使用--data-urlencode (而不是-d )并以要加密的值为前缀(curl 需要这个)或设置一个显式的= Content-Type: text/plain 以确保 curl 在存在特殊字符时正确编码数据(“+”特别棘手)。 |
确保不要在加密值中包含任何 curl 命令统计信息,这就是示例使用-s 选项将它们静音。将值输出到文件有助于避免此问题。 |
逆运算也可以通过以下方式进行/decrypt
(前提是服务器是配置了对称密钥或完整密钥对),如以下示例所示:
$ curl localhost:8888/decrypt -s -d 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda mysecret
获取加密值并添加{cipher}
前缀,然后再将其放入 YAML 或属性文件中,以及提交并将其推送到远程(可能不安全的)存储之前。
这/encrypt
和/decrypt
端点也都接受以下形式的路径/*/{application}/{profiles}
,当客户端调用主环境资源时,可用于在每个应用程序(名称)和每个配置文件的基础上控制加密。
若要以这种精细方式控制加密,还必须提供@Bean 类型TextEncryptorLocator 为名称和配置文件创建不同的加密器。默认情况下提供的加密器不会这样做(所有加密都使用相同的密钥)。 |
这spring
命令行客户端(带有 Spring Cloud CLI 扩展installed)也可用于加密和解密,如以下示例所示:
$ spring encrypt mysecret --key foo 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda $ spring decrypt --key foo 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda mysecret
要使用文件中的密钥(例如用于加密的 RSA 公钥),请在键值前面加上“@”,并提供文件路径,如以下示例所示:
$ spring encrypt mysecret --key @${HOME}/.ssh/id_rsa.pub AQAjPgt3eFZQXwt8tsHAVv/QHiY5sI2dRcR+...
这--key 参数是强制性的(尽管有前缀)。-- |
密钥管理
配置服务器可以使用对称(共享)密钥或非对称密钥(RSA 密钥对)。非对称选项在安全性方面更胜一筹,但使用对称密钥通常更方便,因为它是在bootstrap.properties
.
要配置对称键,您需要将encrypt.key
添加到 secret String(或使用ENCRYPT_KEY
环境变量,使其远离纯文本配置文件)。
您无法使用encrypt.key . |
要配置非对称密钥,请使用密钥库(例如
由keytool
JDK 附带的实用程序)。这
keystore 属性是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
使用 JDK 11 或更高版本时,使用上述命令时可能会收到以下警告。在这种情况下,您可能需要确保keypass 和storepass 值匹配。 |
Warning: Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified -keypass value.
将server.jks
文件(例如),然后在 你bootstrap.yml
,对于 Config Server,创建以下设置:
encrypt:
keyStore:
location: classpath:/server.jks
password: letmein
alias: mytestkey
secret: changeme
使用多个关键帧和关键帧旋转
除了{cipher}
前缀,则配置服务器会查找零个或多个{name:value}
前缀。密钥被传递给TextEncryptorLocator
,它可以执行任何需要的逻辑来定位TextEncryptor
。如果您配置了密钥库 (encrypt.keystore.location
),默认定位器查找具有key
前缀,其密文如下所示:
foo:
bar: `{cipher}{key:testkey}...`
定位器查找名为“testkey”的密钥。还可以使用{secret:…}
值。但是,如果未提供密钥库密码,则默认值是使用密钥库密码(这是构建密钥库时获得的密码,但未指定密钥)。如果确实提供了密钥,则还应使用自定义SecretLocator
.
当密钥仅用于加密几个字节的配置数据(即,它们不在其他地方使用)时,出于加密原因,密钥轮换几乎不需要。
但是,有时可能需要更改密钥(例如,在发生安全漏洞时)。
在这种情况下,所有客户端都需要更改其源配置文件(例如,在 git 中)并使用新的{key:…}
前缀。
请注意,客户端需要首先检查密钥别名在 Config Server 密钥库中是否可用。
如果您想让 Config Server 处理所有加密和解密,请{name:value} 前缀也可以添加为发布到/encrypt 端点。 |
提供加密属性
有时您希望客户端在本地解密配置,而不是在服务器中解密。
在这种情况下,如果您提供encrypt.*
配置来查找密钥,您仍然可以拥有/encrypt
和/decrypt
endpoints,但您需要通过将spring.cloud.config.server.encrypt.enabled=false
在bootstrap.[yml|properties]
.
如果您不关心端点,则如果不配置密钥或启用标志,它应该可以工作。