本站(springdoc.cn)中的内容来源于 spring.io ,原始版权归属于 spring.io。由 springdoc.cn 进行翻译,整理。可供个人学习、研究,未经许可,不得进行任何转载、商用或与之相关的行为。 商标声明:Spring 是 Pivotal Software, Inc. 在美国以及其他国家的商标。 |
本参考指南包括如何使用Spring Cloud Kubernetes。
1. 为什么你需要 Spring Cloud Kubernetes?
Spring Cloud Kubernetes提供了众所周知的Spring Cloud接口的实现,允许开发者在Kubernetes上构建和运行Spring Cloud应用。虽然这个项目在构建云原生应用时可能对你有用,但它也不是在Kubernetes上部署Spring Boot应用的必要条件。如果你刚刚开始在Kubernetes上运行你的Spring Boot应用,你只需要一个基本的Spring Boot应用和Kubernetes本身就可以完成很多事情。要了解更多信息,你可以通过阅读 Spring Boot部署到Kubernetes的参考文档 开始,也可以通过 Spring 和 Kubernetes 的研讨会材料开始。
2. Starter
Starter 是方便的依赖描述,你可以在你的应用程序中包含它。导入一个Starter,以获得功能集的依赖和Spring Boot自动配置。以 spring-cloud-starter-kubernetes-fabric8
开头的Starter提供了使用 Fabric8 Kubernetes Java 客户端 的实现。以 spring-cloud-starter-kubernetes-client
开头的Starter提供了使用 Kubernetes Java 客户端 的实现。
Starter | Features |
---|---|
Fabric8 依赖
Kubernetes Client 依赖
|
Discovery Client 实现,将服务名称(service name)解析为Kubernetes服务。 |
Fabric8 依赖
Kubernetes Client 依赖
|
从Kubernetes ConfigMap 和 Secret 加载应用 application properties。当 ConfigMap 或 Secret 发生变化时,重新加载 application properties。 |
Fabric8 依赖
Kubernetes Client 依赖
|
所有 Spring Cloud Kubernetes 的特性。 |
3. 用于 Kubernetes 的 DiscoveryClient
该项目提供了 Kubernetes 的 Discovery Client 的实现。这个客户端(Client)可以让你按名称查询Kubernetes端点(见 services)。服务通常由Kubernetes API服务器公开,是代表 http
和 https
地址的端点的集合,客户端可以从作为pod运行的Spring Boot应用程序中访问这些端点。
这是你通过在你的项目中添加以下依赖而自动得到的东西。
基于 HTTP 的 DiscoveryClient
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-discoveryclient</artifactId>
</dependency>
spring-cloud-starter-kubernetes-discoveryclient 旨在与 Spring Cloud Kubernetes DiscoveryServer 一起使用。
|
Fabric8 Kubernetes 客户端
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-fabric8</artifactId>
</dependency>
Kubernetes Java 客户端
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-client</artifactId>
</dependency>
要启用 DiscoveryClient
的加载,请将 @EnableDiscoveryClient
添加到相应的配置或 application 类中,如下例所示。
@SpringBootApplication
@EnableDiscoveryClient
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
然后,你可以通过自动注入将 client 注入你的代码中,如下例所示。
@Autowired
private DiscoveryClient discoveryClient;
你可以通过在 application.properties
中设置以下属性来选择从所有命名空间启用 DiscoveryClient
。
spring.cloud.kubernetes.discovery.all-namespaces=true
要想只从指定的命名空间发现服务和端点,你应该将属性 all-namespaces
设置为 false
,并在 application.properties
中设置以下属性(在这个例子中命名空间是:ns1
和 ns2
)。
spring.cloud.kubernetes.discovery.namespaces[0]=ns1
spring.cloud.kubernetes.discovery.namespaces[1]=ns2
要发现未被 kubernetes api 服务器标记为 "ready" 的服务端点地址,可以在 application.properties
中设置以下属性(默认:false
)。
spring.cloud.kubernetes.discovery.include-not-ready-addresses=true
这在为监控目的而发现服务时可能很有用,并且能够检查未准备好(not-ready)的服务实例的 /health 端点。
|
如果你的服务暴露了多个端口,你将需要指定 DiscoveryClient
应该使用哪个端口。 DiscoveryClient
将使用以下逻辑来选择端口。
-
如果该服务有一个标签(label)
primary-port-name
,它将使用标签值中指定的名称的端口。 -
如果没有标签,那么将使用
spring.cloud.kubernetes.discovery.primary-port-name
中指定的端口名称。 -
如果以上两项都没有指定,它将使用名为
https
的端口。 -
如果上述条件都不满足,它将使用名为
http
的端口。 -
作为最后的手段,它将选择端口列表中的第一个端口。
最后一个选项可能会导致非确定性的行为。请确保对你的服务和/或应用程序进行相应的配置。 |
默认情况下,所有的端口和它们的名字将被添加到 ServiceInstance
的元数据(metadata)中。
如果出于任何原因,你需要禁用 DiscoveryClient
,你可以在 application.properties
中设置以下属性。
spring.cloud.kubernetes.discovery.enabled=false
一些Spring Cloud组件使用 DiscoveryClient
,以获取本地服务实例的信息。要做到这一点,你需要将 Kubernetes 服务名称与 spring.application.name
属性对齐。
spring.application.name 对于在 Kubernetes 中为 application 注册的名称没有影响。
|
Spring Cloud Kubernetes还可以观察Kubernetes服务目录的变化,并相应地更新 DiscoveryClient
实现。我们所说的 "观察"(watch)是指每隔 spring.cloud.kubernetes.discovery.catalog-services-watch-delay
毫秒(默认为30000)发布一个心跳事件。该心跳事件将包含目标引用以及所有端点地址的命名空间(关于返回的确切细节,你可以看看 KubernetesCatalogWatch
内部)。这是一个实现细节,心跳事件的监听者不应该依赖这些细节。相反,他们应该通过 equals
方法查看两个后续心跳之间是否存在差异。我们会注意返回一个正确的实现,遵守 equals
契约。端点将以两种方式进行查询。
-
所有命名空间 (通过
spring.cloud.kubernetes.discovery.all-namespaces=true
启用) -
特定的命名空间 (通过
spring.cloud.kubernetes.discovery.namespaces
启用), 例如:
spring:
cloud:
kubernetes:
discovery:
namespaces:
- namespace-a
- namespace-b
-
如果不采取上述两种途径,我们将使用 命名空间解析(Namespace Resolution)。
为了启用这个功能,你需要在你的 application 中的配置(configuration)类上添加 @EnableScheduling
。
默认情况下,我们使用 Endpoints
(见 kubernetes.io/docs/concepts/services-networking/service/#endpoints ) API来查找服务的当前状态。但还有另一种方法,通过 EndpointSlices
( kubernetes.io/docs/concepts/services-networking/endpoint-slices/ )。这种支持可以通过一个属性启用:spring.cloud.kubernetes.discovery.use-endpoint-slices=true
(默认为 false
)。当然,你的集群也必须支持它。事实上,如果你启用了这个属性,但你的集群不支持它,我们将无法启动应用程序。如果你决定启用这种支持,你还需要适当地设置 Role/ClusterRole。例如:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: namespace-reader
rules:
- apiGroups: ["discovery.k8s.io"]
resources: ["endpointslices"]
verbs: ["get", "list", "watch"]
4. Kubernetes 原生服务发现(service discovery)
Kubernetes 本身能够进行(服务端)服务发现(见: kubernetes.io/docs/concepts/services-networking/service/#discovering-services )。使用原生的kubernetes服务发现确保了与其他工具的兼容性,如Istio( istio.io ),这是一个能够进行负载均衡、断路器、故障转移等的 service mesh。
然后,调用者服务只需引用特定Kubernetes集群中可解析的名称。一个简单的实现可以使用一个指向完整域名(FQDN)的 spring RestTemplate
,例如 {service-name}.{namespace}.svc.{cluster}.local:{service-port}
。
此外,你还可以将 Hystrix 用于:
-
通过在 spring boot application 中注解
@EnableCircuitBreaker
,在调用方实现断路器。 -
Fallback 功能,通过用
@HystrixCommand(fallbackMethod=…)
注解相应的方法。
5. Kubernetes PropertySource 的实现
配置Spring Boot应用程序的最常见方法是创建 application.properties
或 application.yaml
或 application-profile.properties
或 application-profile.yaml
文件,其中包含为你的应用程序或Spring Boot Starter 提供定制值的键值对。你可以通过指定系统属性(system properties)或环境变量来覆盖这些属性。
要启用这一功能,你需要在应用程序的配置属性中设置 spring.config.import=kubernetes
:目前,你不能使用 spring.config.import
指定要加载的 ConfigMap
或 Secret
,默认情况下,Spring Cloud Kubernetes 将根据 spring.application.name
属性加载 ConfigMap
和 /
或 Secret
。如果没有设置 spring.application.name
,它将加载一个带有 application
名称的 ConfigMap
和 /
或 Secret
。
如果你想在启动阶段加载 Kubernetes PropertySource
,就像3.0.x版本之前那样,你可以将 spring-cloud-starter-bootstrap
添加到你的应用程序的 classpath 中,或者将 spring.cloud.bootstrap.enabled=true
作为一个环境变量。
5.1. 使用 ConfigMap
PropertySource
Kubernetes提供了一种名为 ConfigMap
的资源,以键值对或嵌入式 application.properties
或 application.yaml
文件的形式将参数外部化,以传递给你的应用程序。Spring Cloud Kubernetes Config 项目使Kubernetes ConfigMap
实例在应用程序启动期间可用,并在观察到的 ConfigMap
实例上检测到变化时触发Bean或Spring上下文的热重载。
下面的一切解释主要是指使用 ConfigMap
的例子,但对 Secret
来说也是如此,即:两者都支持每一个功能。
默认行为是基于 Kubernetes ConfigMap
创建 Fabric8ConfigMapPropertySource
(或 KubernetesClientConfigMapPropertySource
),其 metadata.name
值为Spring应用程序的名称(由其 spring.application.name
属性定义)或在 application.properties
文件中定义的自定义名称,key如下:spring.cloud.kubernetes.config.name
。
然而,更高级的配置是可能的,你可以使用多个 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
没有被设置,名为 c1
的 ConfigMap
将在应用程序运行的 namespace 中被查找。请参阅 Namespace 解析,以更好地了解应用程序的 namespace 是如何解析的。
找到的任何匹配的 ConfigMap
将被处理如下。
-
应用个别配置属性。
-
将以
spring.application.name
的值命名的任何属性的内容作为yaml
(或properties
)应用(如果它不存在,则通过application.yaml/properties
)。 -
将上述名称的内容作为 properties file 应用 + 每个活动的配置文件(active profile)。
一个例子应该更有意义。让我们假设 spring.application.name=my-app
,并且我们有一个叫 k8s
的活动配置文件(active profile)。对于下面的配置。
kind: ConfigMap
apiVersion: v1
metadata:
name: my-app
data:
my-app.yaml: |-
...
my-app-k8s.yaml: |-
..
my-app-dev.yaml: |-
..
someProp: someValue
这些就是我们最终要加载的东西。
-
my-app.yaml
被视为一个文件。 -
my-app-k8s.yaml
被视为一个文件。 -
my-app-dev.yaml
忽略,因为 "dev" 不是一个活跃的配置文件。 -
someProp: someValue
普通属性。
上述流程的唯一例外是,当 ConfigMap
包含一个表明文件是 YAML 或 properties file 的单一KEY时。在这种情况下,key的名称不必是 application.yaml
或 application.properties
(它可以是任何东西),而且属性的值也被正确处理。这个特点有助于通过使用类似以下的东西来创建 ConfigMap
的用例。
kubectl create configmap game-config --from-file=/path/to/app-config.yaml
假设我们有一个名为 Demo 的 Spring Boot 应用程序,它使用以下属性来读取其线程池配置。
-
pool.size.core
-
pool.size.maximum
这可以外化为 yaml
格式的 config map,如下所示。
kind: ConfigMap
apiVersion: v1
metadata:
name: demo
data:
pool.size.core: 1
pool.size.max: 16
单独的 properties 在大多数情况下工作得很好。然而,有时,嵌入的 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。这里需要注意的是,与按名称读取 configmap 不同,这可能导致读取多个configmap。像往常一样,同样的功能也支持 secret。
你还可以根据读取 ConfigMap
时合并在一起的活动配置文件,对Spring Boot应用程序进行不同的配置。你可以通过使用 application.properties
或 application.yaml
属性为不同的 profiles 提供不同的属性值,指定特定于 profile 的值,每一个都在它们自己的文档中(用 ---
序列表示),如下所示。
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
profile 加载到你的Spring应用程序的配置如下。
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会根据活动的配置文件(active profiles)自动获取它。
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"
你可能会遇到这样的情况:有多个 config map 有相同的属性名称。比如说:
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
中放置这些东西的顺序,你可能会得到一个意外的结果(最后一个 config map 获胜)。比如说。
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" 策略,同时只允许覆盖少数源。
如果使用 config map name 不是一个选项,你可以指定一个不同的策略,叫做: explicitPrefix
。因为这是你选择的显式前缀,它只能提供给 sources
级。同时,它比 useNameAsPrefix
有更高的优先级。让我们假设我们有第三个 config map,有这些条目。
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
将导致三个 properties 被生成:
-
greetings.message
等于Say Hello from one
. -
two.greetings.message
等于Say Hello from two
. -
config-map-three.greetings.message
等于Say Hello from three
.
你为 configmap 配置前缀的方式相同,你也可以为 secret 配置前缀;对于基于名称的 secret 和基于标签(label)的 secret 都是如此。比如说。
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
生成属性源(source)时适用的处理规则与 config map 相同。唯一不同的是,按标签查找 secret 可能意味着我们会找到一个以上的源。在这种情况下,前缀(如果通过 useNameAsPrefix
指定)将是为这些特定标签找到的所有 secret 的名称。
还有一件事要记住,我们支持每个 source 的 prefix
,而不是每个secret。解释这一点的最简单方法是通过一个例子。
spring:
application:
name: prefix-based-secrets
cloud:
kubernetes:
secrets:
enableApi: true
useNameAsPrefix: true
namespace: spring-k8s
sources:
- labels:
color: blue
useNameAsPrefix: true
假设与这样一个标签相匹配的查询将提供两个 secret 作为结果:secret-a
和 secret-b
。这两个secret都有相同的属性名称:color=sea-blue
和 color=ocean-blue
。它没有定义哪个 color
将最终成为 property sources 的一部分,但它的前缀将是 secret-a.secret-b
(自然地串联排序,secret 的名称)。
如果你需要更细化的结果,添加更多的标签(label)来独特地识别 secret 将是一个选择。
默认情况下,除了读取 sources
配置中指定的config map外,Spring还将尝试从 "profile aware" sources 读取所有属性。解释这一点的最简单方法是通过一个例子。假设你的应用程序启用了一个名为 "dev 的 profile,并且你有一个类似下面的配置。
spring:
application:
name: spring-k8s
cloud:
kubernetes:
config:
namespace: default-namespace
sources:
- name: config-map-one
除了读取 config-map-one
,Spring还将尝试读取 config-map-one-dev
;以这种特定的顺序。每个活动的配置文件(active profile)都会生成这样一个 profile aware config map。
虽然你的应用程序不应该受到这样的 config map 的影响,但如果需要,可以禁用它。
spring:
application:
name: spring-k8s
cloud:
kubernetes:
config:
includeProfileSpecificSources: false
namespace: default-namespace
sources:
- name: config-map-one
includeProfileSpecificSources: false
请注意,就像以前一样,你可以在两个层面上指定这个属性:为所有的config map或为个别的config map;后者的优先级更高。
你应该检查安全配置(security configuration)部分。要从 pod 内部访问config map,你需要有正确的Kubernetes服务账户、角色和角色绑定。 |
使用 ConfigMap
实例的另一个选择是通过运行Spring Cloud Kubernetes应用程序并让Spring Cloud Kubernetes从文件系统中读取它们来将它们挂载到Pod中。这种行为是由 spring.cloud.kubernetes.config.paths
属性控制的。你可以用它来补充或代替前面描述的机制。你可以在 spring.cloud.kubernetes.config.paths
中通过使用 ,
来指定多个(精确)文件路径。
你必须提供每个 property file 的完整准确路径,因为目录没有被递归解析。 |
如果你使用 spring.cloud.kubernetes.config.paths 或 spring.cloud.kubernetes.secrets.path ,自动重载功能将不起作用。你将需要向 /actuator/refresh 端点发出 POST 请求,或者重新启动/重新部署应用程序。
|
在某些情况下,您的应用程序可能无法使用Kubernetes API加载某些 ConfigMaps
。如果你想让你的应用程序在这种情况下启动过程失败,你可以设置 spring.cloud.kubernetes.config.fail-fast=true
,使应用程序启动时出现异常。
你也可以让你的应用程序在失败时重试加载 ConfigMap
属性源。首先,你需要设置 spring.cloud.kubernetes.config.fail-fast=true
。然后你需要将 spring-retry
和 spring-boot-starter-aop
添加到你的classpath。你可以通过设置 spring.cloud.kubernetes.config.retry.*
属性来配置重试属性,如最大尝试次数、初始间隔、倍数、最大间隔等 backoff 选项。
如果你因为某些原因在classpath上已经有 spring-retry 和 spring-boot-starter-aop ,并且想启用 fail-fast ,但不希望启用重试;你可以通过设置 spring.cloud.kubernetes.config.retry.enabled=false 来禁用 ConfigMap PropertySources 的重试。
|
属性 | 类型 | 默认 | 说明 |
---|---|---|---|
|
|
|
启用 ConfigMaps |
|
|
|
设置 |
|
|
Client namespace |
设置查询的 Kubernetes namespac |
|
|
|
设置 |
|
|
|
启用或禁用通过API消费 |
|
|
|
当加载 |
|
|
|
启用或禁用 config retry。 |
|
|
|
初始重试时间间隔,以毫秒为单位。 |
|
|
|
最大的尝试次数。 |
|
|
|
backoff的最大时间间隔。 |
|
|
|
下一个区间的倍数。 |
5.2. Secret PropertySource
Kubernetes有 Secrets 的概念,用于存储敏感数据,如密码、OAuth令牌等。该项目提供了与 Secrets
的集成,使Spring Boot应用程序可以访问Secrets。你可以通过设置 spring.cloud.kubernetes.secrets.enabled
属性明确地启用或禁用该功能。
启用后,Fabric8SecretsPropertySource
会从以下源查找 Kubernetes 的 Secrets
。
-
递归地读取 secrets 挂载。
-
以应用程序命名(如
spring.application.name
所定义)。 -
匹配某些标签
Note:
默认情况下,由于安全原因,通过API消费Secrets(上面第2和第3点)是不启用的。在secrets上的权限 "list" 允许客户端检查指定命名空间中的secrets值。此外,我们建议容器通过挂载的卷来共享 secrets。
如果你启用了通过API消费Secrets的功能,我们建议你通过使用授权策略(如RBAC)来限制对Secrets的访问。有关通过API消费Secrets的风险和最佳做法的更多信息,请参考 本文档。
如果发现 secrets ,它们的数据就会被提供给应用程序。
假设我们有一个名为 demo
的spring boot应用程序,它使用 properties 来读取其数据库配置。我们可以通过使用以下命令创建一个 Kubernetes secret。
kubectl create secret generic db-secret --from-literal=username=user --from-literal=password=p455w0rd
前面的命令将创建以下secret(你可以通过使用 kubectl get secrets db-secret -o yaml
查看)。
apiVersion: v1
data:
password: cDQ1NXcwcmQ=
username: dXNlcg==
kind: Secret
metadata:
creationTimestamp: 2017-07-04T09:15:57Z
name: db-secret
namespace: default
resourceVersion: "357496"
selfLink: /api/v1/namespaces/default/secrets/db-secret
uid: 63c89263-6099-11e7-b3da-76d6186905a8
type: Opaque
请注意,这些数据包含 create
命令所提供的字词的Base64编码版本。
然后,你的应用程序可以使用这个secret — 例如,通过将 secret 的值导出为环境变量。
apiVersion: v1
kind: Deployment
metadata:
name: ${project.artifactId}
spec:
template:
spec:
containers:
- env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-secret
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
你可以通过多种方式选择要消费的Secrets 。
-
通过列出 secrets 被映射的目录。
-Dspring.cloud.kubernetes.secrets.paths=/etc/secrets/db-secret,etc/secrets/postgresql
如果你把所有的 secrets 都映射到一个共同的 root上,你可以像这样设置它们。
-Dspring.cloud.kubernetes.secrets.paths=/etc/secrets
-
通过设置一个命名的secret。
-Dspring.cloud.kubernetes.secrets.name=db-secret
-
通过定义一个标签(label)列表。
-Dspring.cloud.kubernetes.secrets.labels.broker=activemq -Dspring.cloud.kubernetes.secrets.labels.db=postgresql
与 ConfigMap
的情况一样,更高级的配置也是可能的,你可以使用多个 Secret
实例。spring.cloud.kubernetes.secrets.sources
列表使这成为可能。例如,你可以定义以下 Secret
实例。
spring:
application:
name: cloud-k8s-app
cloud:
kubernetes:
secrets:
name: default-name
namespace: default-namespace
sources:
# Spring Cloud Kubernetes looks up a Secret named s1 in namespace default-namespace
- name: s1
# Spring Cloud Kubernetes looks up a Secret named default-name in namespace n2
- namespace: n2
# Spring Cloud Kubernetes looks up a Secret named s3 in namespace n3
- namespace: n3
name: s3
在前面的例子中,如果 spring.cloud.kubernetes.secrets.namespace
没有被设置,名为 s1
的 Secret
将在应用程序运行的命名空间中被查找。请参阅 命名空间解析,以更好地了解应用程序的命名空间是如何解析的。
与 ConfigMaps
类似,如果你希望你的应用程序在无法加载 Secrets
源时无法启动,你可以设置 spring.cloud.kubernetes.secrets.fail-fast=true
。
也可以像 ConfigMaps
一样为 Secret
源启用重试。与 ConfigMap
源一样,首先你需要设置 spring.cloud.kubernetes.secrets.fail-fast=true
。然后你需要在classpath中添加 spring-retry
和 spring-boot-starter-aop
。Secret 源的重试行为可以通过设置 spring.cloud.kubernetes.secrets.retry.*
属性进行配置。
如果你因为某些原因已经在 classpath 上有 spring-retry 和 spring-boot-starter-aop ,并且想启用 fail-fast ,但不希望启用重试;你可以通过设置 spring.cloud.kubernetes.secrets.retry.enabled=false 来禁用 Secrets PropertySources 的重试。
|
属性 | 类型 | 默认 | 说明 |
---|---|---|---|
|
|
|
启用 Secrets |
|
|
|
设置要查询的 secret 的名称 |
|
|
Client namespace |
设置Kubernetes namespace,以便在其中查找 |
|
|
|
设置用于查询 secrets 的标签(label) |
|
|
|
设置安装 secrets 的路径(例子1)。 |
|
|
|
启用或禁用通过API消费 secrets 的功能(例子2和3)。 |
|
|
|
启用或禁用在加载 |
|
|
|
启用或禁用secrets retry。 |
|
|
|
初始重试时间间隔,以毫秒为单位。 |
|
|
|
最大的尝试次数。 |
|
|
|
backoff 的最大时间间隔。 |
|
|
|
下一个区间的倍数。 |
Notes:
-
spring.cloud.kubernetes.secrets.labels
属性的行为与 基于Map的绑定 所定义的一样。 -
spring.cloud.kubernetes.secrets.paths
属性的行为与 基于集合(Collection)的绑定 所定义的相同。 -
出于安全原因,通过API访问 secrets 可能会受到限制。首选的方法是将 secrets 挂载到Pod上。
你可以在 spring-boot-camel-config 找到一个使用 secrets 的应用程序的例子(尽管它还没有被更新到使用新的 spring-cloud-kubernetes
项目)。
5.3. 命名空间解析
寻找一个应用程序的命名空间是在尽力而为的基础上进行的。为了找到它,我们要反复进行一些步骤。最简单和最常见的步骤是在适当的配置中指定它,例如。
spring:
application:
name: app
cloud:
kubernetes:
secrets:
name: secret
namespace: default
sources:
# Spring Cloud Kubernetes looks up a Secret named 'a' in namespace 'default'
- name: a
# Spring Cloud Kubernetes looks up a Secret named 'secret' in namespace 'b'
- namespace: b
# Spring Cloud Kubernetes looks up a Secret named 'd' in namespace 'c'
- namespace: c
name: d
记住,对 config map 也可以这样做。如果没有指定这样的命名空间,它将被读取(按照这个顺序)。
-
从
spring.cloud.kubernetes.client.namespace
属性。 -
从驻留在
spring.cloud.kubernetes.client.serviceAccountNamespacePath
文件中的一个字符串。 -
从驻留在
/var/run/secrets/kubernetes.io/serviceaccount/namespace
文件(kubernetes默认命名空间路径)中的一个字符串。 -
从指定的客户端方法调用(例如 fabric8 的 :
KubernetesClient::getNamespace
),如果客户端提供这种方法。反过来,这可以通过环境属性来配置。例如,fabric8客户端可以通过 "KUBERNETES_NAMESPACE" 属性进行配置;具体细节请查阅客户端文档。
如果不能从上述步骤中找到一个命名空间,将抛出异常。
5.4. PropertySource
重新加载
该功能在2020.0版本中已被弃用。请参阅 Spring Cloud Kubernetes Configuration Watcher controller,以获取实现相同功能的替代方法。 |
一些应用程序可能需要检测外部属性源(property sources)上的变化,并更新其内部状态以反映新的配置。Spring Cloud Kubernetes的重载功能能够在相关的 ConfigMap
或 Secret
发生变化时触发应用程序的重载。
默认情况下,该功能是禁用的。你可以通过使用 spring.cloud.kubernetes.reload.enabled=true
配置属性(例如,在 application.properties
文件中)来启用它。请注意,这将只启用对 configmap 的监控(即:spring.cloud.kubernetes.reload.monitoring-config-maps
将被设置为 true
)。如果你想启用对 secrets 的监控,必须通过:spring.cloud.kubernetes.reload.monitoring-secrets=true
明确地完成。
支持以下级别的重载(通过设置 spring.cloud.kubernetes.reload.strategy
属性)。
-
refresh
(默认):只有用@ConfigurationProperties
或@RefreshScope
注解的配置bean被重新加载。这个重载级别利用了Spring Cloud Context 的刷新功能。 -
restart_context
:整个 SpringApplicationContext
会被优雅地重新启动。bean类将以新的配置重新创建。为了使重启上下文功能正常工作,你必须启用并公开 actuator 的 restart 端点
management: endpoint: restart: enabled: true endpoints: web: exposure: include: restart
-
shutdown
:SpringApplicationContext
被关闭以激活容器的重启。当你使用这个级别时,请确保所有非daemon线程的生命周期都与ApplicationContext
绑定,并确保 replication controller 或 replica set 被配置为重启 pod。
假设在默认设置下启用了重载功能(refresh
模式),当 config map 发生变化时,会刷新以下 bean 类。
@Configuration @ConfigurationProperties(prefix = "bean") public class MyConfig { private String message = "a message that can be changed live"; // getter and setters }
为了看到变化的有效发生,你可以创建另一个Bean,定期打印消息,如下所示。
@Component
public class MyBean {
@Autowired
private MyConfig config;
@Scheduled(fixedDelay = 5000)
public void hello() {
System.out.println("The message is: " + config.getMessage());
}
}
你可以通过使用 ConfigMap
来改变应用程序打印的信息,如下所示。
apiVersion: v1
kind: ConfigMap
metadata:
name: reload-example
data:
application.properties: |-
bean.message=Hello World!
对与pod相关的 ConfigMap
中名为 bean.message
的属性的任何改变都会反映在输出中。更一般地说,与以 @ConfigurationProperties
注解的 prefix
字段所定义的值为前缀的属性相关的变化会被检测到并反映在应用程序中。本章前面解释了 将 ConfigMap
与 pod 关联 的问题。
完整的示例可在 spring-cloud-kubernetes-reload-example
中找到。
重载功能支持两种操作模式。
-
Event (默认): 通过使用Kubernetes API(web socket)观察config map或secrets的变化。任何事件都会产生对配置的重新检查,如果有变化,会重新加载。为了监听config map的变化,service account 上的
view
角色是必需的。secrets 需要一个更高级别的角色(如edit
)(默认情况下,secrets 不被监控)。 -
Polling: 定期从 config map 和 secrets 中重新创建配置,以查看是否有变化。你可以通过使用
spring.cloud.kubernetes.reload.period
属性来配置轮询周期,默认为 15 秒。它要求与被监控的属性源的角色相同。这意味着,例如,在文件挂载的 secret 源上使用轮询不需要特别的权限。
5.5. 重新加载命名空间和标签过滤
默认情况下,使用 命名空间解析 中概述的步骤选择的命名空间将被用来监听 configmap 和 secrets 的变化。 也就是说:如果你没有告诉reload要监听哪些命名空间和 configmap/secrets,它将监听来自命名空间的所有configmap /secrets,这些命名空间将使用上述算法进行计算。
另一方面,你可以定义一个更细化的方法。例如,你可以指定将被监控的变化的命名空间。
spring:
application:
name: event-reload
cloud:
kubernetes:
reload:
enabled: true
strategy: shutdown
mode: event
namespaces:
- my-namespace
这样的配置将使应用程序只观察 my-namespace
中的变化。请注意,这将监视所有的 configmap/secrets(取决于你启用哪一个)。如果你想要一个更精细的方法,你可以启用 "label-filtering"。首先,我们需要通过以下方式启用这种支持: enable-reload-filtering: true
spring:
application:
name: event-reload
cloud:
kubernetes:
reload:
enabled: true
strategy: shutdown
mode: event
namespaces:
- my-namespaces
monitoring-config-maps: true
enable-reload-filtering: true
这样做的目的是监视只有 spring.cloud.kubernetes.config.informer.enabled: true
标签的 configmap/secrets。
属性 | 类型 | 默认 | 说明 |
---|---|---|---|
|
|
|
启用对 property sources 的监控和配置重载 |
|
|
|
允许监控config map中的变化 |
|
|
|
允许监控secrets的变化 |
|
|
|
触发重载时使用的策略( |
|
|
|
指定如何监听 property sources 的变化( |
|
|
|
使用 |
|
|
要监控变化的 |
|
|
|
启用了重新加载功能的标签过滤功能。 |
Notes:
-
你不应该在config map或secrets中使用
spring.cloud.kubernetes.reload
下的属性。在运行时改变这些属性可能会导致意外的结果。 -
当你使用
refresh
级别时,删除一个属性或整个config map并不能恢复bean的原始状态。
6. Kubernetes 生态系统的感知
无论你的应用程序是否在Kubernetes内运行,本指南前面描述的所有功能都同样有效。这对开发和故障排除真的很有帮助。从开发的角度来看,这可以让你启动你的Spring Boot应用,并调试属于这个项目的一个模块。你不需要将其部署在Kubernetes中,因为该项目的代码依赖于 Fabric8 Kubernetes Java客户端,它是一个fluent DSL,可以通过使用 http
协议与Kubernetes服务器的REST API进行通信。
Kubernetes 感知是基于Spring Boot API的,特别是基于 ConditionalOnCloudPlatform。该属性将自动检测你的应用程序当前是否部署在kubernetes中。可以通过 spring.main.cloud-platform
来覆盖该设置。
例如,如果你需要测试一些功能,但不想部署到一个集群,只需设置:spring.main.cloud-platform=KUBERNETES
。这将使 spring-cloud-kubernetes
像部署在一个真正的集群中一样行动。
如果你的 classpath 上有 spring-cloud-starter-bootstrap 或者正在设置 spring.cloud.bootstrap.enabled=true ,那么你将不得不在 bootstrap.{properties|yml} 中设置 spring.main.cloud-platform (或特定的配置文件)。此外,请注意这些属性:spring.cloud.kubernetes.config.enabled 和 spring.cloud.kubernetes.secrets.enabled 只有在你的 classpath 上有 spring-cloud-starter-bootstrap 或者设置 spring.cloud.bootstrap.enabled=true 时,在 bootstrap.{properties|yml} 中的设置才会生效。
|
6.1. 3.0.x 中的破坏性变化
在3.0.x之前的Spring Cloud Kubernetes版本中,Kubernetes 感知是通过 spring.cloud.kubernetes.enabled
属性实现的。该属性已被删除,不受支持。相反,我们使用Spring Boot API ConditionalOnCloudPlatform。如果需要明确启用或禁用这一感应,请使用 spring.main.cloud-platform=NONE/KUBERNETES
。
6.2. Kubernetes Profile 的自动配置
当应用程序在Kubernetes内以pod形式运行时,一个名为 kubernetes
的 Spring profile 会自动被激活。这让你可以定制配置,定义Spring Boot应用在 Kubernetes 平台内部署时应用的bean(例如,不同的开发和生产配置)。
6.3. Istio 感知
当你在应用程序的 classpath 中包含 spring-cloud-kubernetes-fabric8-istio
模块时,一个新的 profile 就会被添加到应用程序中,前提是该应用程序是在安装了 Istio 的Kubernetes集群中运行。然后你可以在你的Bean和 @Configuration
类中使用spring @Profile("istio")
注解。
Istio 感知模块使用 me.snowdrop:istio-client
与 Istio API 交互,让我们发现流量规则、断路器等,使我们的Spring Boot应用能够轻松地消费这些数据,根据环境动态地配置自己。
7. Pod 健康指标
Spring Boot使用 HealthIndicator
来暴露应用程序的健康信息。这使得它在向用户公开与健康有关的信息方面非常有用,并使它很适合作为 readiness 探针 使用。
Kubernetes健康指标(是核心模块的一部分)暴露了以下信息。
-
Pod名称、IP地址、命名空间、服务账户、节点名称及其IP地址。
-
表示Spring Boot应用程序是在Kubernetes内部还是外部的一个flag。
你可以通过在 application.[properties | yaml]
中设置 management.health.kubernetes.enabled
为 false
来禁用这个 HealthContributor
。
8. Info Contributor
Spring Cloud Kubernetes 包括一个 InfoContributor
,它将Pod信息添加到Spring Boot的 /info
Acturator端点。
你可以通过在 application.[properties | yaml]
中设置 management.info.kubernetes.enabled
为 false
来禁用这个 InfoContributor
。
9. Leader 选举
Spring Cloud Kubernetes Leader 选举机制使用Kubernetes ConfigMap 实现了Spring Integration 的 Leader 选举API。
多个应用程序实例竞争领导权(leadership),但领导权只授予一个。当被授予领导权时,leader 应用程序会收到一个带有 leadership Context
的 OnGrantedEvent
application event。应用程序周期性地尝试获得领导权,领导权授予第一个调用者。一个leader将一直是一个leader,直到它被从集群中移除,或者它放弃了它的领导权。当领导权被移除时,前一个 leader 会收到 OnRevokedEvent
application event。在移除之后,集群中的任何实例都可以成为新的 leader,包括旧的 leader。
要在你的项目中包含它,请添加以下依赖。
Fabric8 Leader 实现
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-fabric8-leader</artifactId>
</dependency>
要指定用于 leader 选举的 configmap 的名称,请使用以下属性。
spring.cloud.kubernetes.leader.config-map-name=leader
10. 适用于 Kubernetes 的 LoadBalancer
该项目包括Spring Cloud Load Balancer,用于基于 Kubernetes Endpoints 的负载均衡,并提供了基于Kubernetes Service的负载均衡器的实现。要将其纳入你的项目,请添加以下依赖。
Fabric8 实现
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-fabric8-loadbalancer</artifactId>
</dependency>
Kubernetes Java Client 实现
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-client-loadbalancer</artifactId>
</dependency>
要启用基于 Kubernetes Service name 的负载均衡,请使用以下属性。然后负载均衡器将尝试使用地址调用应用程序,例如 service-a.default.svc.cluster.local
。
spring.cloud.kubernetes.loadbalancer.mode=SERVICE
要启用所有命名空间的负载均衡,请使用以下属性。遵守 spring-cloud-kubernetes-discovery
模块的属性。
spring.cloud.kubernetes.discovery.all-namespaces=true
如果一个服务需要通过HTTPS访问,你需要在你的服务定义中添加一个标签(add)或注解(annotation),名称为 secured
,值为 true
,然后负载均衡器将使用HTTPS向该服务发出请求。
11. Kubernetes 内部的安全配置
11.1. 命名空间(Namespace)
本项目中提供的大多数组件都需要知道命名空间。对于Kubernetes(1.3以上),命名空间作为 service account secret 的一部分提供给pod,并由客户端自动检测。对于早期版本,它需要作为环境变量指定给pod。做到这一点的快速方法如下。
env:
- name: "KUBERNETES_NAMESPACE"
valueFrom:
fieldRef:
fieldPath: "metadata.namespace"
11.2. Service Account
对于支持集群内更精细的基于角色的访问的Kubernetes发行版,你需要确保使用 spring-cloud-kubernetes
运行的pod能够访问 Kubernetes API。对于你分配给deployment或pod的任何服务账户(service account),你需要确保它们有正确的角色。
根据要求,你需要 get
、list
和 watch
以下资源的许可。
依赖 | 资源 |
---|---|
spring-cloud-starter-kubernetes-fabric8 |
pods, services, endpoints |
spring-cloud-starter-kubernetes-fabric8-config |
configmaps, secrets |
spring-cloud-starter-kubernetes-client |
pods, services, endpoints |
spring-cloud-starter-kubernetes-client-config |
configmaps, secrets |
出于开发的目的,你可以在你的 default
服务账户中添加 cluster-reader
的权限。在生产系统中,你可能希望提供更细化的权限。
下面 的Role 和 RoleBinding 是 default
账户的命名空间权限的一个例子。
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: YOUR-NAME-SPACE
name: namespace-reader
rules:
- apiGroups: [""]
resources: ["configmaps", "pods", "services", "endpoints", "secrets"]
verbs: ["get", "list", "watch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: namespace-reader-binding
namespace: YOUR-NAME-SPACE
subjects:
- kind: ServiceAccount
name: default
apiGroup: ""
roleRef:
kind: Role
name: namespace-reader
apiGroup: ""
12. 服务注册的实现
在Kubernetes中,服务注册由平台控制,应用程序本身并不像在其他平台中那样控制注册。因此,使用 spring.cloud.service-registry.auto-registration.enabled
或设置 @EnableDiscoveryClient(autoRegister=false)
在Spring Cloud Kubernetes中没有效果。
13. Spring Cloud Kubernetes Configuration Watcher
Kubernetes 提供了 将 ConfigMap 或 Secret 挂载到应用程序的容器中作为卷 的能力。当 ConfigMap 或 Secret 的内容发生变化时, 挂载的卷就会根据这些变化进行更新。
然而,除非你重新启动应用程序,否则Spring Boot不会自动更新这些变化。Spring Cloud 提供了刷新 application context 的能力,无需重启应用程序,方法是点击 actuator 的 /refresh
端点,或通过使用 Spring Cloud Bus 发布 RefreshRemoteApplicationEvent
。
为了实现在Kubernetes上运行的Spring Cloud应用程序的这种配置刷新,你可以将 Spring Cloud Kubernetes Configuration Watcher controller 部署到你的Kubernetes集群中。
该应用程序以容器形式发布,可在 Docker Hub 上使用。然而,如果你需要定制配置 watcher 的行为,或者喜欢自己构建镜像,你可以很容易地从 GitHub上的源代码 构建自己的镜像并使用它。
Spring Cloud Kubernetes Configuration Watcher 可以通过两种方式向应用程序发送刷新通知。
-
通过HTTP,在这种情况下,被通知的应用程序必须有
/refresh
actuator 端点暴露出来,并且可以从集群内访问。 -
使用Spring Cloud Bus,在这种情况下,你将需要在你的集群中部署一个message broker,以便应用程序使用。
13.1. Deployment YAML
下面是一个 deployment YAML 的样本,你可以用来将 Kubernetes Configuration Watcher 部署到 Kubernetes。
---
apiVersion: v1
kind: List
items:
- apiVersion: v1
kind: Service
metadata:
labels:
app: spring-cloud-kubernetes-configuration-watcher
name: spring-cloud-kubernetes-configuration-watcher
spec:
ports:
- name: http
port: 8888
targetPort: 8888
selector:
app: spring-cloud-kubernetes-configuration-watcher
type: ClusterIP
- apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app: spring-cloud-kubernetes-configuration-watcher
name: spring-cloud-kubernetes-configuration-watcher
- apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
app: spring-cloud-kubernetes-configuration-watcher
name: spring-cloud-kubernetes-configuration-watcher:view
roleRef:
kind: Role
apiGroup: rbac.authorization.k8s.io
name: namespace-reader
subjects:
- kind: ServiceAccount
name: spring-cloud-kubernetes-configuration-watcher
- apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: namespace-reader
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["configmaps", "pods", "services", "endpoints", "secrets"]
verbs: ["get", "list", "watch"]
- apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-kubernetes-configuration-watcher-deployment
spec:
selector:
matchLabels:
app: spring-cloud-kubernetes-configuration-watcher
template:
metadata:
labels:
app: spring-cloud-kubernetes-configuration-watcher
spec:
serviceAccount: spring-cloud-kubernetes-configuration-watcher
containers:
- name: spring-cloud-kubernetes-configuration-watcher
image: springcloud/spring-cloud-kubernetes-configuration-watcher:2.0.1-SNAPSHOT
imagePullPolicy: IfNotPresent
readinessProbe:
httpGet:
port: 8888
path: /actuator/health/readiness
livenessProbe:
httpGet:
port: 8888
path: /actuator/health/liveness
ports:
- containerPort: 8888
Service Account 和相关的角色绑定对于 Spring Cloud Kubernetes 配置的正常工作非常重要。controller 需要读取 Kubernetes 集群中的 ConfigMaps、Pods、Services、Endpoints和Secrets 数据的权限。
13.2. 监控 ConfigMap 和 Secret
Spring Cloud Kubernetes Configuration Watcher 将对标签(label)为 spring.cloud.kubernetes.config
且值为 true
的 ConfigMaps
或标签为 spring.cloud.kubernetes.secret
且值为 true
的任何 Secret
中的更改做出反应。如果 ConfigMap 或 Secret 没有这些标签,或者这些标签的值不是 true
,那么任何变化都将被忽略。
如果对具有有效标签的ConfigMap或Secret进行了更改,那么Spring Cloud Kubernetes Configuration Watcher 将采用 ConfigMap 或 Secret 的名称,并向具有该名称的应用程序发送通知。但这可能还不足以满足你的使用需求,例如,你可以。
-
将一个config-map绑定到多个应用程序上,这样,在一个configmap内的变化会触发许多服务的刷新。
-
基于 profile 的 sources 为你的应用程序触发事件
由于这个原因,有一个额外的annotation,你可以指定。
spring.cloud.kubernetes.configmap.apps
或 spring.cloud.kubernetes.secret.apps
。它需要一个用逗号分隔的应用程序字符串,指定当此 secret/configmap 发生变化时将收到通知的应用程序名称。
例如:
kind: ConfigMap
apiVersion: v1
metadata:
name: example-configmap
labels:
spring.cloud.kubernetes.config: "true"
annotations:
spring.cloud.kubernetes.configmap.apps: "app-a, app-b"
13.3. HTTP 实现
HTTP实现是默认使用的。当使用该实现时,Spring Cloud Kubernetes Configuration Watcher和ConfigMap或Secret发生变化,那么HTTP实现将使用Spring Cloud Kubernetes Discovery Client来获取与ConfigMap或Secret名称相匹配的应用程序的所有实例,并向应用程序的 actuator /refres
h端点发送HTTP POST请求。默认情况下,它将使用 discovery client 中注册的端口向 /actuator/refresh
发送post请求。
13.3.1. 非默认的 Management Port 和 Actuator Path
如果应用程序使用非默认的 actuator path 和/或为 management endpoint 使用不同的端口,应用程序的Kubernetes服务可以添加一个名为 boot.spring.io/actuator
的 annotation,并将其值设置为应用程序使用的路径和端口。例如
apiVersion: v1
kind: Service
metadata:
labels:
app: config-map-demo
name: config-map-demo
annotations:
boot.spring.io/actuator: http://:9090/myactuator/home
spec:
ports:
- name: http
port: 8080
targetPort: 8080
selector:
app: config-map-demo
你可以选择配置 actuator path 和/或 management port 的另一种方式是设置 spring.cloud.kubernetes.configuration.watcher.actuatorPath
和 spring.cloud.kubernetes.configuration.watcher.actuatorPort
。
13.4. Messaging 实现
当Spring Cloud Kubernetes Configuration Watcher应用程序被部署到Kubernetes时,可以通过将 profile 设置为 bus-amqp
(RabbitMQ)或 bus-kafka
(Kafka)来启用 messaging 实现。
13.5. RabbitMQ 配置
当启用 bus-amqp
配置文件时,你将需要配置 Spring RabbitMQ 以将其指向你希望使用的 RabbitMQ 实例的位置,以及验证所需的任何凭证。这可以通过设置标准 Spring RabbitMQ 属性来完成,例如。
spring:
rabbitmq:
username: user
password: password
host: rabbitmq
13.6. Kafka 配置
启用 bus-kafka
配置文件后,你需要配置Spring Kafka,将其指向你想使用的Kafka Broker实例的位置。这可以通过设置标准的Spring Kafka属性来完成,例如。
spring:
kafka:
producer:
bootstrap-servers: localhost:9092
14. Spring Cloud Kubernetes Config Server
Spring Cloud Kubernetes Config Server,基于 Spring Cloud Config Server,增加了一个 Kubernetes Config Maps 和 Secrets 的 environment repository。
这个组件是完全可选的。然而,它允许你继续利用你可能已经存储在现有 environment repository(Git、SVN、Vault等)中的配置,在Kubernetes上运行的应用程序。
Docker Hub 上有一个默认的镜像,它可以让你轻松地在Kubernetes上部署一个配置服务器(Config Server),而不需要自己构建代码和镜像。然而,如果你需要定制配置服务器的行为,或者喜欢自己构建镜像,你可以很容易地从 GitHub上的源代码 构建自己的镜像并使用它。
14.1. Configuration
14.1.1. 启用 Kubernetes Environment Repository
要启用 Kubernetes environment repository,kubernetes
profile 必须包含在 active profiles 列表中。你也可以激活其他 profile,以使用其他 environment repositor 的实现。
14.1.2. Config Map 和 Secret PropertySources
默认情况下,只有 Config Map 数据会被获取。要同时启用 Secrets,你需要设置 spring.cloud.kubernetes.secrets.enableApi=true
。你可以通过设置 spring.cloud.kubernetes.config.enableApi=false
来禁用 Config Map PropertySource
。
14.1.3. 从其他命名空间获取 Config Map 和 Secret 数据
默认情况下,Kubernetes environment repository 只会从其部署的命名空间中获取Config Map和Secrets。如果你想包括其他命名空间的数据,你可以将 spring.cloud.kubernetes.configserver.config-map-namespaces
和/或 spring.cloud.kubernetes.configserver.secrets-namespaces
设置为逗号分隔的命名空间值列表。
如果你设置了 spring.cloud.kubernetes.configserver.config-map-namespaces 和/或 spring.cloud.kubernetes.configserver.secrets-namespaces ,你将需要包括配置服务器所部署的命名空间,以便继续从该命名空间获取Config Map和Secret数据。
|
14.1.4. Kubernetes 访问控制
Kubernetes Config Server 使用 Kubernetes API server 来获取 Config Map 和 Secret 数据。为了做到这一点,它需要 get
和 list
Config Map 和 Secret 的能力(取决于你启用/禁用的内容)。
14.2. Deployment Yaml
下面是一个 deployment、service 和 permissions 配置的样本,你可以用来将一个基本的配置服务器部署到Kubernetes。
---
apiVersion: v1
kind: List
items:
- apiVersion: v1
kind: Service
metadata:
labels:
app: spring-cloud-kubernetes-configserver
name: spring-cloud-kubernetes-configserver
spec:
ports:
- name: http
port: 8888
targetPort: 8888
selector:
app: spring-cloud-kubernetes-configserver
type: ClusterIP
- apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app: spring-cloud-kubernetes-configserver
name: spring-cloud-kubernetes-configserver
- apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
app: spring-cloud-kubernetes-configserver
name: spring-cloud-kubernetes-configserver:view
roleRef:
kind: Role
apiGroup: rbac.authorization.k8s.io
name: namespace-reader
subjects:
- kind: ServiceAccount
name: spring-cloud-kubernetes-configserver
- apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: namespace-reader
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["configmaps", "secrets"]
verbs: ["get", "list"]
- apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-kubernetes-configserver-deployment
spec:
selector:
matchLabels:
app: spring-cloud-kubernetes-configserver
template:
metadata:
labels:
app: spring-cloud-kubernetes-configserver
spec:
serviceAccount: spring-cloud-kubernetes-configserver
containers:
- name: spring-cloud-kubernetes-configserver
image: springcloud/spring-cloud-kubernetes-configserver
imagePullPolicy: IfNotPresent
env:
- name: SPRING_PROFILES_INCLUDE
value: "kubernetes"
readinessProbe:
httpGet:
port: 8888
path: /actuator/health/readiness
livenessProbe:
httpGet:
port: 8888
path: /actuator/health/liveness
ports:
- containerPort: 8888
15. Spring Cloud Kubernetes Discovery Server
Spring Cloud Kubernetes Discovery Server 提供了HTTP端点,应用程序可用于收集Kubernetes集群内可用服务的信息。使用 spring-cloud-starter-kubernetes-discoveryclient
的应用程序可以使用 Spring Cloud Kubernetes Discovery Server,向该 starter 提供的 DiscoveryClient
实现提供数据。
15.1. 权限
Spring Cloud Discovery server 使用Kubernetes API服务器来获取有关服务和端点资源的数据,因此它需要列出、观察并获得使用这些端点的权限。请看下面的Kubernetes deployment YAML示例,了解如何在Kubernetes上配置服务账户。
15.2. 端点
有三个端点由服务器公开。
15.2.1. /apps
发送到 /apps
的 GET
请求将返回一个可用服务的JSON数组。每个项目包含 Kubernetes 服务的名称和服务实例信息。下面是一个响应示例。
[
{
"name":"spring-cloud-kubernetes-discoveryserver",
"serviceInstances":[
{
"instanceId":"836a2f25-daee-4af2-a1be-aab9ce2b938f",
"serviceId":"spring-cloud-kubernetes-discoveryserver",
"host":"10.244.1.6",
"port":8761,
"uri":"http://10.244.1.6:8761",
"secure":false,
"metadata":{
"app":"spring-cloud-kubernetes-discoveryserver",
"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"v1\",\"kind\":\"Service\",\"metadata\":{\"annotations\":{},\"labels\":{\"app\":\"spring-cloud-kubernetes-discoveryserver\"},\"name\":\"spring-cloud-kubernetes-discoveryserver\",\"namespace\":\"default\"},\"spec\":{\"ports\":[{\"name\":\"http\",\"port\":80,\"targetPort\":8761}],\"selector\":{\"app\":\"spring-cloud-kubernetes-discoveryserver\"},\"type\":\"ClusterIP\"}}\n",
"http":"8761"
},
"namespace":"default",
"scheme":"http"
}
]
},
{
"name":"kubernetes",
"serviceInstances":[
{
"instanceId":"1234",
"serviceId":"kubernetes",
"host":"172.18.0.3",
"port":6443,
"uri":"http://172.18.0.3:6443",
"secure":false,
"metadata":{
"provider":"kubernetes",
"component":"apiserver",
"https":"6443"
},
"namespace":"default",
"scheme":"http"
}
]
}
]
15.2.2. /apps/{name}
对 /apps/{name}
的 GET
请求可以用来获取某个服务的所有实例的数据。下面是一个向 /apps/kubernetes
发出 GET
请求时的响应样本。
[
{
"instanceId":"1234",
"serviceId":"kubernetes",
"host":"172.18.0.3",
"port":6443,
"uri":"http://172.18.0.3:6443",
"secure":false,
"metadata":{
"provider":"kubernetes",
"component":"apiserver",
"https":"6443"
},
"namespace":"default",
"scheme":"http"
}
]
15.2.3. /app/{name}/{instanceid}
向 /app/{name}/{instanceid}
发出的 GET
请求将返回某个服务的特定实例的实例数据。下面是向 /app/kubernetes/1234
发出 GET
请求时的响应样本。
{
"instanceId":"1234",
"serviceId":"kubernetes",
"host":"172.18.0.3",
"port":6443,
"uri":"http://172.18.0.3:6443",
"secure":false,
"metadata":{
"provider":"kubernetes",
"component":"apiserver",
"https":"6443"
},
"namespace":"default",
"scheme":"http"
}
15.3. Deployment YAML
Spring Cloud Discovery Server 的镜像托管在 Docker Hub。然而,如果你需要定制 discovery server 的行为,或者喜欢自己建立镜像,你可以很容易地从 GitHub上的源代码 建立自己的镜像并使用它。
下面是一个 deployment YAML的样本,你可以用来将 Kubernetes Configuration Watcher 部署到 Kubernetes。
---
apiVersion: v1
kind: List
items:
- apiVersion: v1
kind: Service
metadata:
labels:
app: spring-cloud-kubernetes-discoveryserver
name: spring-cloud-kubernetes-discoveryserver
spec:
ports:
- name: http
port: 80
targetPort: 8761
selector:
app: spring-cloud-kubernetes-discoveryserver
type: ClusterIP
- apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app: spring-cloud-kubernetes-discoveryserver
name: spring-cloud-kubernetes-discoveryserver
- apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
app: spring-cloud-kubernetes-discoveryserver
name: spring-cloud-kubernetes-discoveryserver:view
roleRef:
kind: Role
apiGroup: rbac.authorization.k8s.io
name: namespace-reader
subjects:
- kind: ServiceAccount
name: spring-cloud-kubernetes-discoveryserver
- apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: namespace-reader
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["services", "endpoints"]
verbs: ["get", "list", "watch"]
- apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-kubernetes-discoveryserver-deployment
spec:
selector:
matchLabels:
app: spring-cloud-kubernetes-discoveryserver
template:
metadata:
labels:
app: spring-cloud-kubernetes-discoveryserver
spec:
serviceAccount: spring-cloud-kubernetes-discoveryserver
containers:
- name: spring-cloud-kubernetes-discoveryserver
image: springcloud/spring-cloud-kubernetes-discoveryserver:3.0.0-SNAPSHOT
imagePullPolicy: IfNotPresent
readinessProbe:
httpGet:
port: 8761
path: /actuator/health/readiness
livenessProbe:
httpGet:
port: 8761
path: /actuator/health/liveness
ports:
- containerPort: 8761
16. 示例
Spring Cloud Kubernetes 试图让你的应用程序通过遵循Spring Cloud接口来消费Kubernetes原生服务,这一点很透明。
在你的应用程序中,您需要将 spring-cloud-kubernetes-discovery
依赖项添加到classpath中,并删除任何包含 DiscoveryClient
实现(即 Eureka discovery 客户端)的其他依赖项。这同样适用于 PropertySourceLocator
,你需要将 spring-cloud-kubernetes-config
添加到classpath中,并删除任何包含 PropertySourceLocator
实现(即 configuration server client)的其他依赖。
下面的项目强调了这些依赖的用法,并演示了你如何从任何Spring Boot应用程序中使用这些库。
-
Spring Cloud Kubernetes Examples: 位于该资源库内的示例。
-
Spring Cloud Kubernetes全例:Minions 和 Boss
-
Spring Cloud Kubernetes全例: SpringOne Platform Tickets Service
-
Spring Cloud Gateway 和 Spring Cloud Kubernetes Discovery and Config
-
Spring Boot Admin 和 Spring Cloud Kubernetes Discovery 和 Config
17. 其他资源
本节列出了其他资源,如关于Spring Cloud Kubernetes的介绍(幻灯片)和视频。
请随时通过PR 向 该 repository 提交其他资源。
19. 构建
19.1. 基本的编译和测试
要构建源代码,你需要安装JDK 17。
Spring Cloud使用Maven进行大多数构建相关的活动,通过克隆你感兴趣的项目并键入以下内容,你应该能很快上手
$ ./mvnw install
你也可以自己安装Maven(>=3.3.3),运行 mvn 命令来代替下面例子中的 ./mvnw 。如果你这样做,如果你的本地Maven设置不包含 spring 预发布 artifact 的 repository 声明,你可能还需要添加 -P spring 。
|
请注意,您可能需要通过设置 MAVEN_OPTS 环境变量,如 -Xmx512m -XX:MaxPermSize=128m 来增加Maven的可用内存。我们试图在 .mvn 配置中涵盖这一点,所以如果你发现你必须这样做才能使构建成功,请提出一个raise,将设置添加到 source control 中。
|
需要中间件(如,Redis)进行测试的项目一般需要安装和运行 Docker 的本地实例。
19.2. 文档
spring-cloud-build
模块有一个 "docs" profile,如果你打开它,它将尝试从 src/main/asciidoc
构建 asciidoc 源。作为该过程的一部分,它将寻找 README.adoc,并通过加载所有内容来处理它,但不对其进行解析或渲染,只是将其复制到 ${main.basedir}
(默认为 $C:\Users\KevinBlandy\Desktop\SpringDoc\spring-cloud-kubernetes-doc\docs
,即项目的根目录)。如果README有任何改动,在Maven构建后就会以修改过的文件出现在正确位置。提交并推送修改内容即可。
19.3. 使用代码工作
如果你没有IDE的偏好,我们建议你在处理代码时使用 Spring Tools Suite 或 Eclipse。我们使用 m2eclipse eclipse插件来支持maven。其他IDE和工具只要使用Maven 3.3.3或更高版本,也应能顺利工作。
19.3.1. 激活 Spring Maven profile
Spring Cloud 项目需要激活 "spring" Maven profile,以解决spring里程碑和快照库的问题。使用你喜欢的IDE将该 profile 设置为 active 状态,否则你可能会遇到构建错误。
19.3.2. 用 m2eclipse 导入到 eclipse 中
在使用eclipse时,我们推荐使用 m2eclipse eclipse插件。如果你还没有安装m2eclipse,它可以从 "eclipse marketplace" 获得。
旧版本的m2e不支持Maven 3.3,所以一旦项目被导入Eclipse,你还需要告诉m2eclipse为项目使用正确的profile。如果你看到项目中与POMs有关的许多不同的错误,请检查你是否有一个最新的安装。如果你不能升级m2e,把 "spring" profile加入你的 settings.xml 。或者你可以从父pom的 "spring" profile 中复制版本库设置到你的 settings.xml 中。
|
19.3.3. 在没有 m2eclipse 的情况下导入 eclipse 中
如果你不愿意使用 m2eclipse,你可以用以下命令生成 eclipse 项目元数据。
$ ./mvnw eclipse:eclipse
生成的 eclipse 项目可以通过在 file
菜单中选择 import existing projects
来导入。
20. 贡献
Spring Cloud在非限制性的Apache 2.0许可下发布,并遵循非常标准的Github开发流程,使用Github tracker 处理 issue,并将 pull request 合并到 master。如果你想做出贡献,哪怕是一些微不足道的事情,请不要犹豫,但要遵循以下准则。
20.1. 签署贡献者许可协议
在我们接受一个补丁或 pull request 之前,我们需要你签署 贡献者许可协议。签署贡献者协议并不授予任何人对主仓库的提交权,但这意味着我们可以接受你的贡献,如果我们接受你的贡献,你将获得作者的荣誉。积极的贡献者可能会被要求加入核心团队,并被赋予合并 pull request 的能力。
20.2. 行为准则
本项目遵守 《贡献者公约》 的行为准则。通过参与,你被期望维护这一准则。请将不可接受的行为报告给 spring-code-of-conduct@pivotal.io 。
20.3. 准则公约和内部管理
这些都不是 pull request 的必要条件,但它们都会有帮助。它们也可以在原始 pull request 之后、合并之前添加。
-
使用Spring框架的代码格式约定。如果你使用Eclipse,你可以使用 Spring Cloud Build 项目中的
eclipse-code-formatter.xml
文件导入格式化设置。如果使用IntelliJ,你可以使用 Eclipse Code Formatter Plugin 来导入相同的文件。 -
确保所有新的
.java
文件都有一个简单的 Javadoc 类注释,至少有一个@author
的标签来标识你,最好至少有一段关于类的用途。 -
在所有新的
.java
文件中添加ASF license header 注释(从项目中的现有文件中复制)。 -
在你大量修改的
.java
文件中加入自己作为@author
(不仅仅是外观上的修改)。 -
添加一些 Javadocs,如果你改变了命名空间,则添加一些XSD doc元素。
-
一些单元测试也会有很大的帮助—总得有人来做。
-
如果没有人在使用你的分支,请将其与当前的主干分支(或主项目中的其他目标分支)重新建立基线。
-
在写提交信息时,请遵循 这些惯例,如果你要修复一个现有的问题,请在提交信息的末尾加上
Fixes gh-XXXX
(其中XXXX是 issue 编号)。
20.4. 检查风格(Checkstyle)
Spring Cloud Build自带一套检查风格(checkstyle)的规则。你可以在 spring-cloud-build-tools
模块中找到它们。该模块下最值得注意的文件是。
└── src ├── checkstyle │ └── checkstyle-suppressions.xml (3) └── main └── resources ├── checkstyle-header.txt (2) └── checkstyle.xml (1)
1 | 默认的检查风格规则 |
2 | 文件头设置 |
3 | 默认的 suppression 规则 |
20.4.1. Checkstyle 配置
Checkstyle 规则默认是禁用的。要在你的项目中添加 checkstyle,只需定义以下属性和插件。
<properties> <maven-checkstyle-plugin.failsOnError>true</maven-checkstyle-plugin.failsOnError> (1) <maven-checkstyle-plugin.failsOnViolation>true </maven-checkstyle-plugin.failsOnViolation> (2) <maven-checkstyle-plugin.includeTestSourceDirectory>true </maven-checkstyle-plugin.includeTestSourceDirectory> (3) </properties> <build> <plugins> <plugin> (4) <groupId>io.spring.javaformat</groupId> <artifactId>spring-javaformat-maven-plugin</artifactId> </plugin> <plugin> (5) <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-checkstyle-plugin</artifactId> </plugin> </plugins> <reporting> <plugins> <plugin> (5) <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-checkstyle-plugin</artifactId> </plugin> </plugins> </reporting> </build>
1 | 构建时出现 Checkstyle error 而失败 |
2 | 违反Checkstyle规定时,不合格。 |
3 | Checkstyle还分析了test sources |
4 | 添加Spring Java Format 插件,它将重新格式化你的代码,以通过大多数Checkstyle格式化规则。 |
5 | 在你的构建和报告阶段添加checkstyle插件 |
如果你需要抑制某些规则(例如,行长需要更长),那么你只需在 ${project.root}/src/checkstyle/checkstyle-suppressions.xml
下定义一个文件,写上你的抑制措施即可。例子。
<?xml version="1.0"?> <!DOCTYPE suppressions PUBLIC "-//Puppy Crawl//DTD Suppressions 1.1//EN" "https://www.puppycrawl.com/dtds/suppressions_1_1.dtd"> <suppressions> <suppress files=".*ConfigServerApplication\.java" checks="HideUtilityClassConstructor"/> <suppress files=".*ConfigClientWatch\.java" checks="LineLengthCheck"/> </suppressions>
建议将 ${spring-cloud-build.rootFolder}/.editorconfig
和 ${spring-cloud-build.rootFolder}/.springformat
复制到你的项目。这样一来,一些默认的格式化规则就会被应用。你可以通过运行这个脚本来做到这一点。
$ curl https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/.editorconfig -o .editorconfig
$ touch .springformat
20.5. IDE设置
20.5.1. Intellij IDEA
为了设置Intellij,你应该导入我们的编码惯例、检查配置文件并设置checkstyle插件。在 Spring Cloud Build 项目中可以找到以下文件。
└── src ├── checkstyle │ └── checkstyle-suppressions.xml (3) └── main └── resources ├── checkstyle-header.txt (2) ├── checkstyle.xml (1) └── intellij ├── Intellij_Project_Defaults.xml (4) └── Intellij_Spring_Boot_Java_Conventions.xml (5)
1 | 默认的Checkstyle规则 |
2 | 文件头的设置 |
3 | 默认的 suppression 规则 |
4 | Intellij的项目默认值,适用于大多数Checkstyle规则 |
5 | 适用于Intellij的项目风格惯例,适用于大多数Checkstyle规则 |
进入 File
→ Settings
→ Editor
→ Code style
。在那里点击 Scheme
部分旁边的图标。在那里,点击 Import Scheme
,选择 Intellij IDEA code style XML
选项。导入 spring-cloud-build-tools/src/main/resources/intellij/Intellij_Spring_Boot_Java_Conventions.xml
文件。
进入 File
→ Settings
→ Editor
→ Inspections
。在那里点击 Profile
部分旁边的图标。在那里,点击 Import Profile
并导入 spring-cloud-build-tools/src/main/resources/intellij/Intellij_Project_Defaults.xml
文件。
为了让Intellij与Checkstyle一起工作,你必须安装 Checkstyle
插件。建议同时安装 Assertions2Assertj
来自动转换JUnit断言。
进入 File
→ Settings
→ Other settings
→ Checkstyle
。在那里点击 Configuration file
部分的 +
图标。在那里,你必须定义检查风格规则应该从哪里提取。在上图中,我们从克隆的Spring Cloud Build资源库中挑选规则。不过,你也可以指向Spring Cloud Build的GitHub仓库(例如,对于 checkstyle.xml
: raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle.xml )。我们需要提供以下变量。
-
checkstyle.header.file
- 请将其指向Spring Cloud Build的,spring-cloud-build-tools/src/main/resources/checkstyle-header.txt
文件,无论是在你克隆的 repo 中还是通过raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle-header.txt
URL。 -
checkstyle.suppressions.file
- 默认的 suppression 措施。请将其指向Spring Cloud Build的,spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml
文件,无论是在你克隆的 repo中还是通过raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml
URL。 -
checkstyle.additional.suppressions.file
- 这个变量对应于你本地项目中的suppression。例如,你在spring-cloud-contract
上工作。然后指向project-root/src/checkstyle/checkstyle-suppressions.xml`文件夹。 `spring-cloud-contract
的例子是。/home/username/spring-cloud-contract/src/checkstyle/checkstyle-suppressions.xml
。
记住将扫描范围设置为所有来源,因为我们对生产和测试来源应用检查式规则。 |
20.6. Duplicate Finder(重复搜索器)
Spring Cloud Build带来了 basepom:duplicate-finder-maven-plugin
,它可以标记java classpath上重复和冲突的类和资源。
20.6.1. Duplicate Finder 配置
Duplicate finder 默认是启用的,会在Maven构建的 verify
阶段运行,但只有当你在项目的pom.xml build
部分添加了 duplicate-finder-maven-plugin
,它才会在项目中生效。
<build>
<plugins>
<plugin>
<groupId>org.basepom.maven</groupId>
<artifactId>duplicate-finder-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
对于其他属性,我们已经设置了 插件文档 中列出的默认值。
你可以通过设置以 double-finder-maven-plugin
为前缀的选定属性的值来轻松覆盖它们。例如,将 double-finder-maven-plugin.skip
设为 true
,以便在构建中跳过重复检查。
如果你需要在你的设置中添加 ignoredClassPatterns
或 ignoredResourcePatterns
,请确保在你项目的 plugin configuration 部分添加它们。
<build>
<plugins>
<plugin>
<groupId>org.basepom.maven</groupId>
<artifactId>duplicate-finder-maven-plugin</artifactId>
<configuration>
<ignoredClassPatterns>
<ignoredClassPattern>org.joda.time.base.BaseDateTime</ignoredClassPattern>
<ignoredClassPattern>.*module-info</ignoredClassPattern>
</ignoredClassPatterns>
<ignoredResourcePatterns>
<ignoredResourcePattern>changelog.txt</ignoredResourcePattern>
</ignoredResourcePatterns>
</configuration>
</plugin>
</plugins>
</build>
21. AOT 和 原生镜像(native image)的支持
在这一点上,Spring Cloud Kubernetes不支持Spring Boot AOT转换或原生镜像。在未来的版本中可能会增加部分支持。