使用ConfigMap
PropertySource
Kubernetes 提供了一个名为ConfigMap
要将
参数以键值对或嵌入式的形式传递给应用程序application.properties
或application.yaml
文件。
Spring Cloud Kubernetes Config 项目使 KubernetesConfigMap
可用实例
在应用程序启动期间,并在检测到更改时触发 bean 或 Spring 上下文的热重载
观察ConfigMap
实例。
接下来的所有内容主要是指使用 ConfigMaps 的示例,但同样代表 Secrets,即:两者都支持每个功能。
默认行为是创建一个Fabric8ConfigMapPropertySource
(或KubernetesClientConfigMapPropertySource
)ConfigMap
该metadata.name
其中之一:
-
的值
spring.cloud.kubernetes.config.name
-
值(由
spring.application.name
property) -
String 文本
"application"
但是,在您可以使用多个ConfigMap
实例。
这spring.cloud.kubernetes.config.sources
List 使这成为可能。
例如,您可以定义以下内容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
ignored,因为dev
不是活动的配置文件 -
not-my-app.yaml
ignored,因为它不匹配spring.application.name
-
someProp: someValue
plain 属性
加载属性的顺序如下:
-
首先加载所有属性
my-app.yaml
-
然后 all from profile-based sources:
my-app-k8s.yaml
-
然后是所有 Plain 属性
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
这将搜索 namespace 中的每个 configmapspring-k8s
具有标签{letter : a}
.重要的
这里需要注意的是,与按名称读取 configMap 不同,这可能会导致读取多个 config map。
像往常一样,密钥也支持相同的功能。
您还可以根据合并在一起的活动配置文件以不同的方式配置 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
在前面的示例中,加载到 Spring 应用程序中的配置使用development
profile 如下:
greeting:
message: Say Hello to the Developers
farewell:
message: Say Goodbye to the Developers
但是,如果production
profile 处于活动状态,则配置将变为:
greeting:
message: Say Hello to the Ops
farewell:
message: Say Goodbye
如果两个配置文件都处于活动状态,则最后显示在ConfigMap
覆盖任何前面的值。
另一种选择是为每个配置文件创建不同的 config map,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 中定义该变量。
Deployment 资源文件,如下所示:
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"
你可能会遇到多个具有相同属性名称的 configs 映射的情况。例如:
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
.
这允许您为所有源设置 “default” 策略,同时只允许覆盖少数源。
如果无法使用配置映射名称,则可以指定不同的策略,称为: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 配置前缀的方式相同,您也可以为 secret 配置前缀;两者都适用于基于 name 的 secret 以及基于标签的 API。例如:
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
生成 property source 时,处理规则与生成 config maps 的处理规则相同。唯一的区别是
按标签查找密钥可能意味着我们会找到多个来源。在这种情况下,前缀(如果通过useNameAsPrefix
)
将为这些特定标签找到的所有密钥的名称。
还有一点要记住,我们支持prefix
按源,而不是按密钥。解释这一点的最简单方法是通过一个例子:
spring:
application:
name: prefix-based-secrets
cloud:
kubernetes:
secrets:
enableApi: true
useNameAsPrefix: true
namespace: spring-k8s
sources:
- labels:
color: blue
useNameAsPrefix: true
假设与此类标签匹配的查询将提供两个密钥作为结果:secret-a
和secret-b
.
这两个密钥具有相同的属性名称:color=sea-blue
和color=ocean-blue
.未定义color
将作为 property sources 的一部分结束,但它的前缀将是secret-a.secret-b
(自然地连接排序,秘密的名称)。
如果您需要更精细的结果,则可以选择添加更多标签来唯一标识密钥。
默认情况下,除了读取sources
configuration 时,Spring 也会尝试读取
来自 “Profile Aware” 源的所有属性。解释这一点的最简单方法是通过一个例子。假设您的应用程序
启用名为 “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
;按此特定顺序。每个活动配置文件
生成这样的配置文件感知配置 Map。
虽然你的应用程序不应该受到这种配置映射的影响,但如果需要,可以禁用它:
spring:
application:
name: spring-k8s
cloud:
kubernetes:
config:
includeProfileSpecificSources: false
namespace: default-namespace
sources:
- name: config-map-one
includeProfileSpecificSources: false
请注意,和之前一样,有两个级别可以指定此属性:for all config maps 或 对于单个 ID;后者具有更高的优先级。
您应该检查安全配置部分。要从 Pod 内部访问配置映射,你需要拥有正确的 Kubernetes 服务帐户、角色和角色绑定。 |
使用ConfigMap
实例是通过运行 Spring Cloud Kubernetes 应用程序将它们挂载到 Pod 中
以及让 Spring Cloud Kubernetes 从文件系统中读取它们。
此功能已弃用,并将在未来发行版中删除(使用spring.config.import 相反)。
此行为由spring.cloud.kubernetes.config.paths 财产。您可以在
添加或代替前面描述的机制。spring.cloud.kubernetes.config.paths 需要每个属性文件的完整路径的 List,因为目录不会被递归解析。例如: |
spring:
cloud:
kubernetes:
config:
paths:
- /tmp/application.properties
- /var/application.yaml
如果您使用spring.cloud.kubernetes.config.paths 或spring.cloud.kubernetes.secrets.path 自动重新加载
功能将不起作用。您需要制作一个POST 请求发送到/actuator/refresh endpoint 或
重新启动/重新部署应用程序。 |
在某些情况下,您的应用程序可能无法加载某些ConfigMaps
使用 Kubernetes API。
如果您希望应用程序在这种情况下启动过程失败,则可以设置spring.cloud.kubernetes.config.fail-fast=true
使应用程序启动失败并显示 Exception。
您还可以让应用程序重试加载ConfigMap
property sources 的 source 来执行。首先,您需要
设置spring.cloud.kubernetes.config.fail-fast=true
.然后你需要添加spring-retry
和spring-boot-starter-aop
添加到您的 Classpath 中。您可以配置重试属性,例如
最大尝试次数、回退选项(如 Initial Interval、Multiplier、Max Interval),方法是将spring.cloud.kubernetes.config.retry.*
性能。
如果您已经拥有spring-retry 和spring-boot-starter-aop 由于某种原因,在 Classpath 上
并希望启用快速失败,但不希望启用重试;您可以对ConfigMap PropertySources 通过设置spring.cloud.kubernetes.config.retry.enabled=false . |
名字 | 类型 | 违约 | 描述 |
---|---|---|---|
|
|
|
启用 ConfigMap |
|
|
|
设置 |
|
|
客户端命名空间 |
设置要查找的 Kubernetes 命名空间 |
|
|
|
设置路径 |
|
|
|
启用或禁用使用 |
|
|
|
启用或禁用在加载 |
|
|
|
启用或禁用配置重试。 |
|
|
|
初始重试间隔(以毫秒为单位)。 |
|
|
|
最大尝试次数。 |
|
|
|
回退的最大间隔。 |
|
|
|
下一个间隔的乘数。 |