|
对于最新的稳定版本,请使用 Spring Cloud Kubernetes 3.3.0! |
使用ConfigMap PropertySource
Kubernetes 提供了一个名为ConfigMap将
以键值对或嵌入式的形式传递给应用程序的参数application.properties或application.yaml文件。
Spring Cloud Kubernetes Config 项目使 KubernetesConfigMap可用实例
在应用程序启动期间,并在检测到更改时触发 bean 或 Spring 上下文的热重载
观察ConfigMap实例。
接下来的所有内容主要参考使用 ConfigMaps 的示例进行解释,但同样代表 密钥,即:两者都支持每个功能。
默认行为是创建Fabric8ConfigMapPropertySource(或KubernetesClientConfigMapPropertySource) 基于 KubernetesConfigMap那有metadata.name其中之一:
-
值
spring.cloud.kubernetes.config.name -
Spring 应用程序的值(由
spring.application.name属性) -
字符串文字
"application"
但是,可以在可以使用多个ConfigMap实例。
这spring.cloud.kubernetes.config.sources列表使这成为可能。
例如,您可以定义以下内容ConfigMap实例:
spring:
application:
name: cloud-k8s-app
cloud:
kubernetes:
config:
name: default-name
namespace: default-namespace
sources:
# Spring Cloud Kubernetes looks up a ConfigMap named c1 in namespace default-namespace
- name: c1
# Spring Cloud Kubernetes looks up a ConfigMap named default-name in whatever namespace n2
- namespace: n2
# Spring Cloud Kubernetes looks up a ConfigMap named c3 in namespace n3
- namespace: n3
name: c3
在前面的示例中,如果spring.cloud.kubernetes.config.namespace没有设定,
这ConfigMap叫c1将在应用程序运行的命名空间中查找。
请参阅命名空间解析,以更好地了解命名空间如何
的申请已解决。
任何匹配ConfigMap找到的处理方式如下:
-
应用单个配置属性。
-
申请为
yaml(或properties) 由spring.application.name(如果不存在,则通过application.yaml/properties) -
将上述名称的内容 + 每个活动配置文件作为属性文件应用。
一个例子应该更有意义。让我们假设spring.application.name=my-app并且
我们有一个名为k8s.对于以下配置:
kind: ConfigMap
apiVersion: v1
metadata:
name: my-app
data:
my-app.yaml: |-
...
my-app-k8s.yaml: |-
..
my-app-dev.yaml: |-
..
not-my-app.yaml: |-
..
someProp: someValue
这是我们最终将加载的内容:
-
my-app.yaml被视为文件 -
my-app-k8s.yaml被视为文件 -
my-app-dev.yaml忽略,因为dev不是活动配置文件 -
not-my-app.yaml忽略,因为它不匹配spring.application.name -
someProp: someValue普通属性
加载属性的顺序如下:
-
首先加载所有属性
my-app.yaml -
然后全部来自基于配置文件的来源:
my-app-k8s.yaml -
然后所有普通属性
someProp: someValue
这意味着基于配置文件的源优先于非基于配置文件的源(就像在普通 Spring 应用程序中一样);和 plain 属性优先于基于配置文件和非配置文件的源。这是一个例子:
kind: ConfigMap
apiVersion: v1
metadata:
name: my-app
data:
my-app-k8s.yaml: |-
key1=valueA
key2=valueB
my-app.yaml: |-
key1=valueC
key2=valueA
key1: valueD
处理这样的 ConfigMap 后,您将在属性中得到以下内容:key1=valueD,key2=valueB.
上述流的唯一例外是当ConfigMap包含一个指示
该文件是 YAML 或属性文件。在这种情况下,密钥的名称不必是application.yaml或application.properties(它可以是任何东西),并且属性的值被正确处理。
此功能有助于在以下用例中ConfigMap是通过使用如下内容创建的:
kubectl create configmap game-config --from-file=/path/to/app-config.yaml
假设我们有一个名为demo使用以下属性读取其线程池
配置。
-
pool.size.core -
pool.size.maximum
这可以外部化为 config map 中的yaml格式如下:
kind: ConfigMap
apiVersion: v1
metadata:
name: demo
data:
pool.size.core: 1
pool.size.max: 16
在大多数情况下,单个属性工作正常。然而,有时,嵌入yaml更方便。在这种情况下,我们
使用名为application.yaml嵌入我们的yaml如下:
kind: ConfigMap
apiVersion: v1
metadata:
name: demo
data:
application.yaml: |-
pool:
size:
core: 1
max:16
以下示例也有效:
kind: ConfigMap
apiVersion: v1
metadata:
name: demo
data:
custom-name.yaml: |-
pool:
size:
core: 1
max:16
您还可以根据标签定义要进行的搜索,例如:
spring:
application:
name: labeled-configmap-with-prefix
cloud:
kubernetes:
config:
enableApi: true
useNameAsPrefix: true
namespace: spring-k8s
sources:
- labels:
letter: a
这将搜索命名空间中的每个配置映射spring-k8s有标签的{letter : a}.重要的
这里需要注意的是,与按名称读取 configmap 不同,这可能会导致读取多个配置映射。
与往常一样,机密支持相同的功能。
您还可以根据合并在一起的活动配置文件以不同的方式配置 Spring Boot 应用程序当ConfigMap读取。您可以使用application.properties或application.yaml属性,指定特定于配置文件的值,每个值都在自己的文档中(由序列指示),如下所示:---
kind: ConfigMap
apiVersion: v1
metadata:
name: demo
data:
application.yml: |-
greeting:
message: Say Hello to the World
farewell:
message: Say Goodbye
---
spring:
profiles: development
greeting:
message: Say Hello to the Developers
farewell:
message: Say Goodbye to the Developers
---
spring:
profiles: production
greeting:
message: Say Hello to the Ops
在前面的情况下,使用development简介如下:
greeting:
message: Say Hello to the Developers
farewell:
message: Say Goodbye to the Developers
但是,如果productionprofile 处于活动状态时,配置变为:
greeting:
message: Say Hello to the Ops
farewell:
message: Say Goodbye
如果两个配置文件都处于活动状态,则最后显示的属性在ConfigMap覆盖任何前面的值。
另一种选择是为每个配置文件创建不同的配置映射,spring boot 将根据 在活动配置文件上
kind: ConfigMap
apiVersion: v1
metadata:
name: demo
data:
application.yml: |-
greeting:
message: Say Hello to the World
farewell:
message: Say Goodbye
kind: ConfigMap
apiVersion: v1
metadata:
name: demo-development
data:
application.yml: |-
spring:
profiles: development
greeting:
message: Say Hello to the Developers
farewell:
message: Say Goodbye to the Developers
kind: ConfigMap
apiVersion: v1
metadata:
name: demo-production
data:
application.yml: |-
spring:
profiles: production
greeting:
message: Say Hello to the Ops
farewell:
message: Say Goodbye
告诉 Spring Boot 哪个profile应启用,请参阅 Spring Boot 文档。
在部署到 Kubernetes 时激活特定配置文件的一个选项是使用环境变量启动 Spring Boot 应用程序,您可以在容器规范的 PodSpec 中定义该环境变量。
部署资源文件,如下所示:
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-name
labels:
app: deployment-name
spec:
replicas: 1
selector:
matchLabels:
app: deployment-name
template:
metadata:
labels:
app: deployment-name
spec:
containers:
- name: container-name
image: your-image
env:
- name: SPRING_PROFILES_ACTIVE
value: "development"
您可能会遇到以下情况:有多个配置映射具有相同的属性名称。 例如:
kind: ConfigMap
apiVersion: v1
metadata:
name: config-map-one
data:
application.yml: |-
greeting:
message: Say Hello from one
和
kind: ConfigMap
apiVersion: v1
metadata:
name: config-map-two
data:
application.yml: |-
greeting:
message: Say Hello from two
取决于您放置这些内容的顺序bootstrap.yaml|properties,您最终可能会得到一个意外的结果(最后一个配置映射获胜)。 例如:
spring:
application:
name: cloud-k8s-app
cloud:
kubernetes:
config:
namespace: default-namespace
sources:
- name: config-map-two
- name: config-map-one
将导致属性greetings.message存在Say Hello from one.
有一种方法可以通过指定useNameAsPrefix.例如:
spring:
application:
name: with-prefix
cloud:
kubernetes:
config:
useNameAsPrefix: true
namespace: default-namespace
sources:
- name: config-map-one
useNameAsPrefix: false
- name: config-map-two
这样的配置将导致生成两个属性:
-
greetings.message等于Say Hello from one. -
config-map-two.greetings.message等于Say Hello from two
请注意spring.cloud.kubernetes.config.useNameAsPrefix优先级低于spring.cloud.kubernetes.config.sources.useNameAsPrefix. 这允许您为所有源设置“默认”策略,同时只允许覆盖少数源。
如果无法使用配置映射名称,则可以指定不同的策略,称为:explicitPrefix.由于这是一个显式前缀,因此
选择,则只能提供给sources水平。同时,它的优先级高于useNameAsPrefix.假设我们有第三个配置映射,其中包含这些条目:
kind: ConfigMap
apiVersion: v1
metadata:
name: config-map-three
data:
application.yml: |-
greeting:
message: Say Hello from three
如下所示的配置:
spring:
application:
name: with-prefix
cloud:
kubernetes:
config:
useNameAsPrefix: true
namespace: default-namespace
sources:
- name: config-map-one
useNameAsPrefix: false
- name: config-map-two
explicitPrefix: two
- name: config-map-three
将导致生成三个属性:
-
greetings.message等于Say Hello from one. -
two.greetings.message等于Say Hello from two. -
config-map-three.greetings.message等于Say Hello from three.
与为 configmap 配置前缀的方式相同,您也可以为机密配置前缀;两者都适用于基于名称的机密 以及基于标签的。例如:
spring:
application:
name: prefix-based-secrets
cloud:
kubernetes:
secrets:
enableApi: true
useNameAsPrefix: true
namespace: spring-k8s
sources:
- labels:
letter: a
useNameAsPrefix: false
- labels:
letter: b
explicitPrefix: two
- labels:
letter: c
- labels:
letter: d
useNameAsPrefix: true
- name: my-secret
生成属性源时适用与配置映射相同的处理规则。唯一的区别是
潜在地,按标签查找机密可能意味着我们找到了多个来源。在这种情况下,前缀(如果通过useNameAsPrefix)
将是为这些特定标签找到的密钥的名称。
还有一件事要记住,我们支持prefix每个秘密。解释这一点的最简单方法是通过一个例子:
spring:
application:
name: prefix-based-secrets
cloud:
kubernetes:
secrets:
enableApi: true
useNameAsPrefix: true
namespace: spring-k8s
sources:
- labels:
color: blue
useNameAsPrefix: true
假设与此类标签匹配的查询将返回两个机密:secretA和secretB.
这两个密钥具有相同的属性名称:color=sea-blue和color=ocean-blue.因为useNamesAsPrefix=true,将加载两个属性源:
-
secretA.color=sea-blue -
secretB.color=ocean-blue
默认情况下,除了读取sources配置,Spring 也会尝试读取
所有属性都来自“配置文件感知”源。解释这一点的最简单方法是通过一个例子。假设您的应用程序
启用名为“dev”的配置文件,您将拥有如下配置:
spring:
application:
name: spring-k8s
cloud:
kubernetes:
config:
namespace: default-namespace
sources:
- name: config-map-one
除了阅读config-map-one,Spring 也会尝试阅读config-map-one-dev;按这个特定的顺序。每个活动配置文件
生成这样的配置文件感知配置映射。
尽管您的应用程序不应受到此类配置映射的影响,但可以根据需要禁用它:
spring:
application:
name: spring-k8s
cloud:
kubernetes:
config:
includeProfileSpecificSources: false
namespace: default-namespace
sources:
- name: config-map-one
includeProfileSpecificSources: false
请注意,就像以前一样,您可以在两个级别指定此属性:对于所有配置映射或 对于个人;后者具有更高的优先级。
| 您应该检查安全配置部分。要从 Pod 内部访问配置映射,您需要拥有正确的 Kubernetes 服务帐户、角色和角色绑定。 |
使用另一种选择ConfigMap实例是通过运行 Spring Cloud Kubernetes 应用程序将它们挂载到 Pod 中
并让 Spring Cloud Kubernetes 从文件系统中读取它们。
此功能已弃用,并将在将来的版本中删除(使用spring.config.import相反)。
此行为由spring.cloud.kubernetes.config.paths财产。您可以在以下领域使用它
添加到或代替前面描述的机制。spring.cloud.kubernetes.config.paths需要每个属性文件的完整路径列表,因为目录不会递归解析。例如: |
spring:
cloud:
kubernetes:
config:
paths:
- /tmp/application.properties
- /var/application.yaml
如果您使用spring.cloud.kubernetes.config.paths或spring.cloud.kubernetes.secrets.path自动重新加载
功能将不起作用。您需要制作一个POST请求/actuator/refreshendpoint 或
重新启动/重新部署应用程序。 |
在某些情况下,您的应用程序可能无法加载您的某些ConfigMaps使用 Kubernetes API。
如果希望应用程序在这种情况下启动过程失败,可以将spring.cloud.kubernetes.config.fail-fast=true使应用程序启动失败并出现异常。
您还可以让应用程序重试加载ConfigMap属性源。首先,您需要
设置spring.cloud.kubernetes.config.fail-fast=true.然后你需要添加spring-retry和spring-boot-starter-aop到你的类路径。您可以配置重试属性,例如
最大尝试次数、回退选项,如初始间隔、乘数、最大间隔,通过设置spring.cloud.kubernetes.config.retry.*性能。
如果您已经有spring-retry和spring-boot-starter-aop出于某种原因在类路径上
并且想要启用快速故障,但不希望启用重试;您可以禁用重试ConfigMap PropertySources通过设置spring.cloud.kubernetes.config.retry.enabled=false. |
| 名称 | 类型 | 默认值 | 描述 |
|---|---|---|---|
|
|
|
启用 ConfigMap |
|
|
|
设置 |
|
|
客户端命名空间 |
设置要查找的 Kubernetes 命名空间 |
|
|
|
设置路径,其中 |
|
|
|
启用或禁用消费 |
|
|
|
在加载时发生错误时启用或禁用应用程序启动失败 |
|
|
|
启用或禁用配置重试。 |
|
|
|
初始重试间隔(以毫秒为单位)。 |
|
|
|
最大尝试次数。 |
|
|
|
回退的最大间隔。 |
|
|
|
下一个区间的乘数。 |