本参考指南介绍了如何使用 Spring Cloud Kubernetes。

1.为什么需要Spring Cloud Kubernetes?

Spring Cloud Kubernetes 提供了众所周知的 Spring Cloud 接口的实现,允许开发人员在 Kubernetes 上构建和运行 Spring Cloud 应用程序。虽然此项目在构建云原生应用程序时可能对您有用,但它也不是在 Kubernetes 上部署 Spring Boot 应用程序的必要条件。如果您刚刚开始在 Kubernetes 上运行 Spring Boot 应用程序,那么只需一个基本的 Spring Boot 应用程序和 Kubernetes 本身就可以完成很多工作。要了解更多信息,您可以首先阅读用于部署到 Kubernetes 的 Spring Boot 参考文档,并学习研讨会材料Spring 和 Kubernetes

2. 初学者

Starters 是方便的依赖描述符,您可以将其包含在应用程序中。包括一个启动器来获取功能集的依赖项和 Spring Boot 自动配置。首先提供使用Fabric8 Kubernetes Java 客户端spring-cloud-starter-kubernetes-fabric8 的实现。首先 提供使用Kubernetes Java 客户端的实现。spring-cloud-starter-kubernetes-client

起动机 特征
Fabric8 依赖项
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-kubernetes-fabric8</artifactId>
</dependency>
Kubernetes 客户端依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-kubernetes-client</artifactId>
</dependency>

将服务名称解析为 Kubernetes 服务的Discovery Client实现。

Fabric8 依赖项
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-kubernetes-fabric8-config</artifactId>
</dependency>
Kubernetes 客户端依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-kubernetes-client-config</artifactId>
</dependency>

从 Kubernetes ConfigMapsSecrets加载应用程序属性。 当 ConfigMap 或 Secret 更改时重新加载应用程序属性。

Fabric8 依赖项
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-kubernetes-fabric8-all</artifactId>
</dependency>
Kubernetes 客户端依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-kubernetes-client-all</artifactId>
</dependency>

所有 Spring Cloud Kubernetes 功能。

3.Kubernetes 的 DiscoveryClient

该项目提供了Kubernetes Discovery Client实现。该客户端允许您按名称查询 Kubernetes 端点(请参阅services)。http服务通常由 Kubernetes API 服务器公开为表示和寻址的端点集合https,客户端可以从作为 Pod 运行的 Spring Boot 应用程序进行访问。

DiscoveryClient 还可以查找 类型的服务ExternalName(请参阅ExternalName services)。目前,仅当以下属性 spring.cloud.kubernetes.discovery.include-external-name-services设置true为且仅在fabric8实现中时,外部名称支持类型的服务才可用。在后续版本中,还将添加对 kubernetes 本机客户端的支持。

通过在项目中添加以下依赖项,您可以免费获得此功能:

基于HTTPDiscoveryClient

<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到相应的配置或应用程序类,如以下示例所示:

@SpringBootApplication
@EnableDiscoveryClient
public class Application {
  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }
}

然后,您只需通过自动装配即可将客户端注入代码中,如以下示例所示:

@Autowired
private DiscoveryClient discoveryClient;

DiscoveryClient您可以通过在中设置以下属性来选择从所有命名空间启用application.properties

spring.cloud.kubernetes.discovery.all-namespaces=true

要仅从指定的命名空间发现服务和端点,您应该将属性设置all-namespacesfalse并在中设置以下属性application.properties(在此示例中,命名空间为:ns1ns2)。

spring.cloud.kubernetes.discovery.namespaces[0]=ns1
spring.cloud.kubernetes.discovery.namespaces[1]=ns2

要发现 kubernetes api 服务器未标记为“就绪”的服务端点地址,您可以在application.properties(默认值: false)中设置以下属性:

spring.cloud.kubernetes.discovery.include-not-ready-addresses=true
当发现用于监视目的的服务时,这可能很有用,并且可以检查/health未就绪服务实例的端点。

如果您的服务公开多个端口,您将需要指定DiscoveryClient应使用哪个端口。将DiscoveryClient使用以下逻辑选择端口。

  1. 如果服务有标签,primary-port-name它将使用标签值中指定名称的端口。

  2. 如果不存在标签,则将spring.cloud.kubernetes.discovery.primary-port-name使用中指定的端口名称。

  3. 如果以上均未指定,它将使用名为 的端口https

  4. 如果上述条件均不满足,它将使用名为 的端口http

  5. 作为最后的手段,它会选择端口列表中的第一个端口。

最后一个选项可能会导致不确定的行为。请确保相应地配置您的服务和/或应用程序。

默认情况下,所有端口及其名称都将添加到ServiceInstance.

如前所述,如果您想获取ServiceInstance还包含ExternalName类型服务的列表,则需要通过以下方式启用该支持:spring.cloud.kubernetes.discovery.include-external-name-services=true。因此,调用时DiscoveryClient::getInstances这些也会被返回。您可以通过检查和查找名为 的字段来区分ExternalName和任何其他类型。这将是返回的服务的类型:/等。ServiceInstance::getMetadatatypeExternalNameClusterIP

ServiceInstance可以包含来自底层服务实例的特定 Pod 的标签和注释。要获取此类信息,您还需要启用:

spring.cloud.kubernetes.discovery.metadata.add-pod-labels=true和/或spring.cloud.kubernetes.discovery.metadata.add-pod-annotations=true。目前,此类功能仅存在于fabric8客户端实现中,但将在以后的版本中添加到kubernetes本机客户端中。

如果出于任何原因需要禁用DiscoveryClient,您可以在 中设置以下属性application.properties

spring.cloud.kubernetes.discovery.enabled=false

一些 Spring Cloud 组件使用DiscoveryClient来获取有关本地服务实例的信息。为此,您需要将 Kubernetes 服务名称与spring.application.name属性对齐。

spring.application.name就 Kubernetes 中为应用程序注册的名称而言没有影响

Spring Cloud Kubernetes 还可以监视 Kubernetes 服务目录的更改并 DiscoveryClient相应地更新实现。通过“观察”,我们的意思是我们将每毫秒发布一次心跳事件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

为了启用此功能,您需要 @EnableScheduling在应用程序中添加配置类。

默认情况下,我们使用Endpoints(请参阅kubernetes.io/docs/concepts/services-networking/service/#endpoints)API 来查找服务的当前状态。不过,还有另一种方法,通过EndpointSliceskubernetes.io/docs/concepts/services-networking/endpoint-slices/)。可以通过属性启用此类支持:(spring.cloud.kubernetes.discovery.use-endpoint-slices=true默认情况下为false)。当然,您的集群也必须支持它。事实上,如果您启用此属性,但您的集群不支持它,我们将无法启动应用程序。如果您决定启用此类支持,您还需要正确的角色/集群角色设置。例如:

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原生服务发现

Kubernetes 本身能够(服务器端)服务发现(请参阅:kubernetes.io/docs/concepts/services-networking/service/#discovering-services)。使用原生 kubernetes 服务发现可确保与其他工具的兼容性,例如 Istio ( istio.io ),这是一个能够实现负载平衡、断路器、故障转移等功能的服务网格。

然后,调用者服务只需要引用特定 Kubernetes 集群中可解析的名称。RestTemplate一个简单的实现可能会使用引用完全限定域名 (FQDN) 的spring ,例如{service-name}.{namespace}.svc.{cluster}.local:{service-port}.

此外,您还可以将 Hystrix 用于:

  • 在调用方实现断路器,通过注释 Spring Boot 应用程序类@EnableCircuitBreaker

  • 后备功能,通过注释相应的方法@HystrixCommand(fallbackMethod=

5. Kubernetes PropertySource 实现

配置 Spring Boot 应用程序的最常见方法是创建一个application.propertiesorapplication.yaml或一个application-profile.propertiesorapplication-profile.yaml文件,其中包含为应用程序或 Spring Boot 启动器提供自定义值的键值对。您可以通过指定系统属性或环境变量来覆盖这些属性。

要启用此功能,您需要spring.config.import=kubernetes:在应用程序的配置属性中进行设置。目前您无法使用 指定要加载的 ConfigMap 或 Secret spring.config.import,默认情况下 Spring Cloud Kubernetes 将根据spring.application.name属性加载 ConfigMap 和/或 Secret。如果spring.application.name未设置,它将加载名称为 的 ConfigMap 和/或 Secret application

如果您想PropertySource在引导阶段加载 Kubernetes,就像在 3.0.x 版本之前一样,您可以添加spring-cloud-starter-bootstrap到应用程序的类路径或设置spring.cloud.bootstrap.enabled=true 为环境变量。

5.1. 用一个ConfigMap PropertySource

Kubernetes 提供了一个名为 的资源ConfigMap来外部化参数,以键值对或嵌入application.propertiesapplication.yaml文件的形式传递给您的应用程序。Spring Cloud Kubernetes Config项目使 KubernetesConfigMap实例在应用程序启动期间可用,并在观察到的实例上检测到更改时触发 Bean 或 Spring 上下文的热重新加载ConfigMap

接下来的所有内容主要参考使用 ConfigMaps 的示例进行解释,但同样代表 Secrets,即:两者都支持每个功能。

默认行为是基于 Kubernetes创建一个Fabric8ConfigMapPropertySource(或一个) ,其值为Spring 应用程序的名称(由其属性定义)或在以下键下的文件中定义的自定义名称 : 。KubernetesClientConfigMapPropertySourceConfigMapmetadata.namespring.application.nameapplication.propertiesspring.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未设置,则将在应用程序运行的命名空间中查找ConfigMapname 。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: |-
   ..
  someProp: someValue

这些是我们最终将加载的内容:

  • my-app.yaml作为文件处理

  • my-app-k8s.yaml作为文件处理

  • my-app-dev.yaml 被忽略,因为dev不是活动配置文件

  • someProp: someValue普通财产

上述流程的唯一例外是当ConfigMap包含指示文件是 YAML 或属性文件的单个键时。在这种情况下,键的名称不必是application.yamlor application.properties(它可以是任何内容),并且属性的值会被正确处理。ConfigMap此功能简化了使用以下内容创建的用例:

kubectl create configmap game-config --from-file=/path/to/app-config.yaml

假设我们有一个名为 的 Spring Boot 应用程序demo,它使用以下属性来读取其线程池配置。

  • pool.size.core

  • pool.size.maximum

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具有 labels 的每个配置映射{letter : a}。这里需要注意的重要一点是,与按名称读取配置映射不同,这可能会导致读取多个配置映射。与往常一样,秘密支持相同的功能。

您还可以根据读取时合并在一起的活动配置文件以不同方式配置 Spring Boot 应用程序ConfigMap。您可以通过使用 application.propertiesapplication.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如下:

  greeting:
    message: Say Hello to the Developers
  farewell:
    message: Say Goodbye to the Developers

但是,如果production配置文件处于活动状态,则配置将变为:

  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 Bootprofile应该启用哪个,请参阅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.messageSay 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 配置前缀的方式相同,您也可以为 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

生成属性源时适用与配置映射相同的处理规则。唯一的区别是,通过标签查找秘密可能意味着我们会找到多个来源。在这种情况下,前缀(如果通过指定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-asecret-b。这两个秘密都具有相同的属性名称:color=sea-bluecolor=ocean-blue。它是未定义的, color最终将作为属性源的一部分,但它的前缀将是secret-a.secret-b (自然连接排序,秘密名称)。

如果您需要更细粒度的结果,可以选择添加更多标签来唯一地标识秘密。

默认情况下,除了读取配置中指定的配置映射之外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 应用程序并让 Spring Cloud Kubernetes 从文件系统读取它们来将它们安装到 Pod 中。

此功能已弃用,并将在未来版本中删除(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/refresh端点发出请求或重新启动/重新部署应用程序。

在某些情况下,您的应用程序可能无法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-retryandspring-boot-starter-aop并且想要启用快速失败,但不希望启用重试;ConfigMap PropertySources 您可以通过设置禁用重试spring.cloud.kubernetes.config.retry.enabled=false
表 1. 属性:
姓名 类型 默认 描述

spring.cloud.kubernetes.config.enabled

Boolean

true

启用 ConfigMapPropertySource

spring.cloud.kubernetes.config.name

String

${spring.application.name}

ConfigMap设置要查找的名称

spring.cloud.kubernetes.config.namespace

String

客户端命名空间

设置 Kubernetes 命名空间的查找位置

spring.cloud.kubernetes.config.paths

List

null

ConfigMap设置实例挂载路径

spring.cloud.kubernetes.config.enableApi

Boolean

true

通过 API启用或禁用消费ConfigMap实例

spring.cloud.kubernetes.config.fail-fast

Boolean

false

启用或禁用加载应用程序时发生错误时应用程序启动失败ConfigMap

spring.cloud.kubernetes.config.retry.enabled

Boolean

true

启用或禁用配置重试。

spring.cloud.kubernetes.config.retry.initial-interval

Long

1000

初始重试间隔(以毫秒为单位)。

spring.cloud.kubernetes.config.retry.max-attempts

Integer

6

最大尝试次数。

spring.cloud.kubernetes.config.retry.max-interval

Long

2000

退避的最大间隔。

spring.cloud.kubernetes.config.retry.multiplier

Double

1.1

下一个间隔的乘数。

5.2. 秘密财产来源

Kubernetes 有Secrets的概念,用于存储密码、OAuth 令牌等敏感数据。该项目提供了集成,Secrets使 Spring Boot 应用程序可以访问机密。您可以通过设置spring.cloud.kubernetes.secrets.enabled属性来显式启用或禁用此功能。

启用后,将从以下来源Fabric8SecretsPropertySource查找 Kubernetes :Secrets

  1. 从秘密安装中递归读取

  2. 以应用程序命名(由 定义spring.application.name

  3. 匹配一些标签

笔记:

默认情况下,出于安全原因,未启用通过 API 使用 Secret(上述第 2 点和第 3 点) 。秘密上的权限“列表”允许客户端检查指定命名空间中的秘密值。此外,我们建议容器通过安装的卷共享秘密。

如果您启用通过 API 使用 Secret,我们建议您使用授权策略(例如 RBAC)限制对 Secret 的访问。有关通过 API 使用 Secret 时的风险和最佳实践的更多信息,请参阅此文档

如果发现秘密,则其数据可供应用程序使用。

假设我们有一个名为 的 Spring Boot 应用程序demo,它使用属性来读取其数据库配置。我们可以使用以下命令创建 Kubernetes 密钥:

kubectl create secret generic db-secret --from-literal=username=user --from-literal=password=p455w0rd

前面的命令将创建以下秘密(您可以使用查看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

请注意,数据包含命令提供的文字的 Base64 编码版本create

然后,您的应用程序可以使用此秘密 - 例如,通过将秘密的值导出为环境变量:

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

您可以通过多种方式选择要使用的 Secret:

  1. 通过列出映射机密的目录:

    -Dspring.cloud.kubernetes.secrets.paths=/etc/secrets/db-secret,etc/secrets/postgresql

    如果您将所有秘密映射到公共根,则可以将它们设置为:

    -Dspring.cloud.kubernetes.secrets.paths=/etc/secrets
  2. 通过设置命名秘密:

    -Dspring.cloud.kubernetes.secrets.name=db-secret
  3. 通过定义标签列表:

    -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未设置,则将在应用程序运行的命名空间中查找Secretname 。s1请参阅命名空间解析以更好地了解应用程序的命名空间是如何解析的。

类似于ConfigMaps;如果您希望应用程序在无法加载Secrets属性源时无法启动,您可以设置spring.cloud.kubernetes.secrets.fail-fast=true.

还可以为Secret属性源(例如ConfigMaps. 与ConfigMap属性源一样,首先您需要设置spring.cloud.kubernetes.secrets.fail-fast=true. 然后您需要将spring-retry和添加spring-boot-starter-aop到您的类路径中。Secret可以通过设置属性来配置属性源的重试行为spring.cloud.kubernetes.secrets.retry.*

如果由于某种原因您已经在类路径上有了spring-retryandspring-boot-starter-aop并且想要启用快速失败,但不希望启用重试;Secrets PropertySources 您可以通过设置禁用重试spring.cloud.kubernetes.secrets.retry.enabled=false
表 2. 属性:
姓名 类型 默认 描述

spring.cloud.kubernetes.secrets.enabled

Boolean

true

启用秘密PropertySource

spring.cloud.kubernetes.secrets.name

String

${spring.application.name}

设置要查找的秘密的名称

spring.cloud.kubernetes.secrets.namespace

String

客户端命名空间

设置 Kubernetes 命名空间的查找位置

spring.cloud.kubernetes.secrets.labels

Map

null

设置用于查找秘密的标签

spring.cloud.kubernetes.secrets.paths

List

null

设置安装机密的路径(示例 1)

spring.cloud.kubernetes.secrets.enableApi

Boolean

false

启用或禁用通过 API 使用机密(示例 2 和 3)

spring.cloud.kubernetes.secrets.fail-fast

Boolean

false

启用或禁用加载应用程序时发生错误时应用程序启动失败Secret

spring.cloud.kubernetes.secrets.retry.enabled

Boolean

true

启用或禁用机密重试。

spring.cloud.kubernetes.secrets.retry.initial-interval

Long

1000

初始重试间隔(以毫秒为单位)。

spring.cloud.kubernetes.secrets.retry.max-attempts

Integer

6

最大尝试次数。

spring.cloud.kubernetes.secrets.retry.max-interval

Long

2000

退避的最大间隔。

spring.cloud.kubernetes.secrets.retry.multiplier

Double

1.1

下一个间隔的乘数。

笔记:

  • 该属性的行为由基于映射的spring.cloud.kubernetes.secrets.labels绑定定义 。

  • 该属性的行为由基于集合的spring.cloud.kubernetes.secrets.paths绑定定义 。

  • 出于安全原因,通过 API 访问机密可能会受到限制。首选方法是将机密安装到 Pod。

您可以在spring-boot-camel-config找到使用机密的应用程序示例(尽管尚未更新以使用新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

请记住,可以对配置映射执行相同的操作。如果没有指定这样的命名空间,它将被读取(按此顺序):

  1. 来自财产spring.cloud.kubernetes.client.namespace

  2. spring.cloud.kubernetes.client.serviceAccountNamespacePath来自驻留在由属性表示的文件中的字符串

  3. 来自文件中的字符串/var/run/secrets/kubernetes.io/serviceaccount/namespace(kubernetes 默认名称空间路径)

  4. 从指定的客户端方法调用(例如fabric8的:)KubernetesClient::getNamespace,如果客户端提供了这样的方法。反过来,这可以通过环境属性进行配置。例如,fabric8 客户端可以通过“KUBERNETES_NAMESPACE”属性进行配置;有关确切的详细信息,请参阅客户文档。

如果未能从上述步骤中找到名称空间,将导致引发异常。

5.4. ConfigMap 和 Secret 的顺序

如果出于某种原因,您同时启用了 configmap 和 Secret,并且它们之间存在公共属性,则 ConfigMap 中的值将具有更高的优先级。也就是说:它将覆盖在秘密中找到的任何值。

5.5. PropertySource重新加载

此功能已在 2020.0 版本中弃用。请参阅Spring Cloud Kubernetes 配置观察器控制器,了解实现相同功能的替代方法。

某些应用程序可能需要检测外部属性源的更改并更新其内部状态以反映新配置。Spring Cloud Kubernetes 的重新加载功能能够在相关ConfigMapSecret更改时触发应用程序重新加载。

默认情况下,此功能处于禁用状态。您可以使用spring.cloud.kubernetes.reload.enabled=true配置属性(例如在application.properties文件中)启用它。请注意,这将仅启用对配置映射的监视(即:spring.cloud.kubernetes.reload.monitoring-config-maps将设置为true)。如果您想启用秘密监控,则必须通过 : 显式完成spring.cloud.kubernetes.reload.monitoring-secrets=true

支持以下级别的重新加载(通过设置属性spring.cloud.kubernetes.reload.strategy):

  • refresh(默认):仅重新加载带有@ConfigurationProperties或注释的配置 bean @RefreshScope。此重新加载级别利用了 Spring Cloud Context 的刷新功能。

  • restart_context:整个SpringApplicationContext优雅地重启了。Bean 将使用新配置重新创建。为了使重新启动上下文功能正常工作,您必须启用并公开重新启动执行器端点

management:
  endpoint:
    restart:
      enabled: true
  endpoints:
    web:
      exposure:
        include: restart
  • shutdown:SpringApplicationContext被关闭以激活容器的重新启动。使用此级别时,请确保所有非守护线程的生命周期都绑定到 ,ApplicationContext 并且复制控制器或副本集配置为重新启动 pod。

假设使用默认设置(refresh模式)启用重新加载功能,当配置映射更改时,将刷新以下 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());
    }
}

您可以使用 a 更改应用程序打印的消息ConfigMap,如下所示:

apiVersion: v1
kind: ConfigMap
metadata:
  name: reload-example
data:
  application.properties: |-
    bean.message=Hello World!

对与 Pod 关联的属性进行的任何更改都会反映在输出bean.message中。ConfigMap更一般地说,与以注释prefix 字段定义的值为前缀的属性关联的更改@ConfigurationProperties会被检测到并反映在应用程序中。 本章前面解释了将 aConfigMap与 pod关联。

完整的示例可以在 中找到spring-cloud-kubernetes-reload-example

重新加载功能支持两种操作模式:

  • 事件(默认):使用 Kubernetes API(Web 套接字)监视配置映射或机密的更改。任何事件都会对配置进行重新检查,如果发生更改,则会重新加载。view为了侦听配置映射更改,需要服务帐户上的角色。edit机密需要更高级别的角色(例如)(默认情况下,不监视机密)。

  • 轮询:定期从配置映射和机密重新创建配置,以查看其是否已更改。您可以使用spring.cloud.kubernetes.reload.period属性配置轮询周期,默认为 15 秒。它需要与受监控的属性源具有相同的角色。例如,这意味着对安装在文件上的秘密源使用轮询不需要特定的权限。

5.6. 重新加载命名空间和标签过滤

默认情况下,使用命名空间解析中概述的步骤选择的命名空间将用于侦听配置映射和机密中的更改。即:如果您不告诉重新加载要监视哪些名称空间和配置映射/秘密,它将监视将使用上述算法计算的名称空间中的所有配置映射/秘密。

另一方面,您可以定义更细粒度的方法。例如,您可以指定将监视更改的名称空间:

spring:
  application:
    name: event-reload
  cloud:
    kubernetes:
      reload:
        enabled: true
        strategy: shutdown
        mode: event
        namespaces:
          - my-namespace

这样的配置将使应用程序仅监视my-namespace命名空间中的更改。请注意,这将监视所有配置映射/秘密(取决于您启用哪一个)。如果您想要更细粒度的方法,可以启用“标签过滤”。首先我们需要通过以下方式启用此类支持: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标签的配置映射/秘密。

表 3. 属性:
姓名 类型 默认 描述

spring.cloud.kubernetes.reload.enabled

Boolean

false

启用属性源监控和配置重新加载

spring.cloud.kubernetes.reload.monitoring-config-maps

Boolean

true

允许监视配置映射中的更改

spring.cloud.kubernetes.reload.monitoring-secrets

Boolean

false

允许监控秘密的变化

spring.cloud.kubernetes.reload.strategy

Enum

refresh

触发重新加载时使用的策略(refreshrestart_contextshutdown

spring.cloud.kubernetes.reload.mode

Enum

event

指定如何侦听属性源的更改 (eventpolling)

spring.cloud.kubernetes.reload.period

Duration

15s

polling使用策略时验证变更的周期

spring.cloud.kubernetes.reload.namespaces

String[]

我们应该注意变化的命名空间

spring.cloud.kubernetes.reload.enable-reload-filtering

String

为重新加载功能启用标签过滤

笔记:

  • 您不应spring.cloud.kubernetes.reload在配置映射或机密中使用属性。在运行时更改此类属性可能会导致意外结果。

  • 使用级别时,删除属性或整个配置映射不会恢复 Bean 的原始状态refresh

6. Kubernetes 生态系统意识

无论您的应用程序是否在 Kubernetes 内运行,本指南前面描述的所有功能都同样有效。这对于开发和故障排除确实很有帮助。从开发的角度来看,这可以让您启动 Spring Boot 应用程序并调试属于该项目的模块之一。您不需要将其部署在 Kubernetes 中,因为该项目的代码依赖于 Fabric8 Kubernetes Java 客户端,它是一个流畅的 DSL,可以使用http协议与 Kubernetes 服务器的 REST API 进行通信。

Kubernetes 感知基于 Spring Boot API,特别是ConditionalOnCloudPlatform。该属性将自动检测您的应用程序当前是否部署在 kubernetes 中。可以通过 覆盖该设置spring.main.cloud-platform

例如,如果您需要测试某些功能,但不想部署到集群,则设置: 就足够了 spring.main.cloud-platform=KUBERNETES。这将使它spring-cloud-kubernetes的行为就像部署在真实的集群中一样。

如果您spring-cloud-starter-bootstrap的类路径上有或正在设置spring.cloud.bootstrap.enabled=true,那么您必须设置应该设置spring.main.cloud-platformbootstrap.{properties|yml} 或配置文件特定的设置)。另请注意,这些属性:spring.cloud.kubernetes.config.enabled和仅当您在类路径上有或正在设置时spring.cloud.kubernetes.secrets.enabled 设置才生效。 bootstrap.{properties|yml}spring-cloud-starter-bootstrapspring.cloud.bootstrap.enabled=true

6.1. 3.0.x 中的重大变化

在 Spring Cloud Kubernetes 之前的版本中3.0.x,Kubernetes 感知是使用spring.cloud.kubernetes.enabled属性来实现的。该属性已被删除并且不受支持。相反,我们使用 Spring Boot API:ConditionalOnCloudPlatform。如果需要显式启用或禁用此感知,请使用spring.main.cloud-platform=NONE/KUBERNETES

6.2. Kubernetes 配置文件自动配置

当应用程序作为 Kubernetes 中的 pod 运行时,kubernetes会自动激活名为 的 Spring 配置文件。这使您可以自定义配置,以定义在 Kubernetes 平台内部署 Spring Boot 应用程序时应用的 bean(例如,不同的开发和生产配置)。

6.3. Istio 意识

当您将该模块包含在应用程序类路径中时,如果该应用程序在安装了Istio 的spring-cloud-kubernetes-fabric8-istioKubernetes 集群内运行,则会向该应用程序添加一个新的配置文件。然后,您可以在 Bean 和类中使用 spring注释。@Profile("istio")@Configuration

Istio 感知模块用于 me.snowdrop:istio-client与 Istio API 进行交互,让我们发现流量规则、断路器等,使我们的 Spring Boot 应用程序可以轻松地使用这些数据来根据环境动态配置自身。

7. Pod 健康状况指示器

Spring Boot 用于HealthIndicator公开有关应用程序运行状况的信息。这使得它对于向用户公开健康相关信息非常有用,并且非常适合用作就绪探针

Kubernetes 健康指示器(核心模块的一部分)公开以下信息:

  • Pod 名称、IP 地址、命名空间、服务帐户、节点名称及其 IP 地址

  • 指示 Spring Boot 应用程序是 Kubernetes 内部还是外部的标志

您可以HealthContributor通过设置management.health.kubernetes.enabledfalse来禁用此功能application.[properties | yaml]

8. 信息贡献者

Spring Cloud Kubernetes 包含一个InfoContributor将 Pod 信息添加到 Spring Boot 的/infoActurator 端点的功能。

您可以InfoContributor通过设置management.info.kubernetes.enabledfalse来禁用此功能application.[properties | yaml]

9. 领导人选举

Spring Cloud Kubernetes 领导者选举机制使用 Kubernetes ConfigMap 实现了 Spring Integration 的领导者选举 API。

多个应用程序实例竞争领导权,但领导权只会授予一个。当被授予领导力时,领导者应用程序会收到OnGrantedEvent具有领导力的应用程序事件Context。应用程序定期尝试获得领导权,并将领导权授予第一个调用者。领导者将一直是领导者,直到它被从集群中删除或放弃领导权为止。当发生领导移除时,前任领导会收到OnRevokedEvent申请事件。删除后,集群中的任何实例都可能成为新的领导者,包括旧的领导者。

要将其包含在您的项目中,请添加以下依赖项。

Fabric8 领导者实施

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-kubernetes-fabric8-leader</artifactId>
</dependency>

要指定用于领导者选举的 configmap 的名称,请使用以下属性。

spring.cloud.kubernetes.leader.config-map-name=leader

10.Kubernetes 的负载均衡器

该项目包括基于 Kubernetes Endpoints 进行负载均衡的 Spring Cloud Load Balancer,并提供基于 Kubernetes Service 的负载均衡器的实现。要将其包含到您的项目中,请添加以下依赖项。

Fabric8 实施

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-kubernetes-fabric8-loadbalancer</artifactId>
</dependency>

Kubernetes Java 客户端实现

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-kubernetes-client-loadbalancer</artifactId>
</dependency>

要基于 Kubernetes 服务名称启用负载平衡,请使用以下属性。然后负载均衡器将尝试使用地址调用应用程序,例如service-a.default.svc.cluster.local

spring.cloud.kubernetes.loadbalancer.mode=SERVICE

要跨所有命名空间启用负载平衡,请使用以下属性。spring-cloud-kubernetes-discovery尊重模块的属性。

spring.cloud.kubernetes.discovery.all-namespaces=true

如果需要通过 HTTPS 访问服务,您需要在服务定义中添加标签或注释以及名称secured和值true,然后负载均衡器将使用 HTTPS 向服务发出请求。

11. Kubernetes 内部的安全配置

11.1. 命名空间

该项目中提供的大多数组件都需要知道名称空间。对于 Kubernetes (1.3+),命名空间作为服务帐户密钥的一部分可供 pod 使用,并由客户端自动检测到。对于早期版本,需要将其指定为 pod 的环境变量。执行此操作的快速方法如下:

      env:
      - name: "KUBERNETES_NAMESPACE"
        valueFrom:
          fieldRef:
            fieldPath: "metadata.namespace"

11.2. 服务帐号

对于支持集群内更细粒度的基于角色的访问的 Kubernetes 发行版,您需要确保运行的 podspring-cloud-kubernetes可以访问 Kubernetes API。对于分配给部署或 Pod 的任何服务帐户,您需要确保它们具有正确的角色。

根据要求,您需要get和对以下资源的权限listwatch

表 4. Kubernetes 资源权限
依赖性 资源

弹簧云启动器-kubernetes-fabric8

Pod、服务、端点

spring-cloud-starter-kubernetes-fabric8-config

配置映射、秘密

spring-cloud-starter-kubernetes-客户端

Pod、服务、端点

spring-cloud-starter-kubernetes-客户端配置

配置映射、秘密

出于开发目的,您可以cluster-readerdefault服务帐户添加权限。在生产系统上,您可能希望提供更细化的权限。

以下 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 配置观察器

Kubernetes 提供了将ConfigMap 或 Secret 作为卷安装 在应用程序容器中的功能。当 ConfigMap 或 Secret 的内容发生更改时,已安装的卷将随着这些更改而更新

但是,除非您重新启动应用程序,否则 Spring Boot 不会自动更新这些更改。Spring Cloud 提供了刷新应用程序上下文的功能,而无需通过点击执行器端点或通过使用 Spring Cloud Bus/refresh发布来重新启动应用程序。RefreshRemoteApplicationEvent

要实现在 Kubernetes 上运行的 Spring Cloud 应用程序的配置刷新,您可以将 Spring Cloud Kubernetes Configuration Watcher 控制器部署到 Kubernetes 集群中。

该应用程序作为容器发布,并可在Docker Hub上使用。但是,如果您需要自定义配置观察器行为或者更喜欢自己构建映像,您可以轻松地从GitHub 上的源代码构建您自己的映像并使用它。

Spring Cloud Kubernetes Configuration Watcher 可以通过两种方式向应用程序发送刷新通知。

  1. 通过 HTTP,在这种情况下,被通知的应用程序必须/refresh公开并可从集群内访问执行器端点

  2. 使用 Spring Cloud Bus,在这种情况下,您需要将消息代理部署到集群以供应用程序使用。

13.1. 部署 YAML

下面是一个示例部署 YAML,可用于将 Kubernetes 配置观察器部署到 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

服务帐户和关联的角色绑定对于 Spring Cloud Kubernetes 配置正常工作非常重要。控制器需要访问权限才能读取 Kubernetes 集群中有关 ConfigMap、Pod、服务、端点和 Secret 的数据。

13.2. 监控 ConfigMap 和 Secret

Spring Cloud Kubernetes 配置观察器将对 ConfigMap 中标签为spring.cloud.kubernetes.configvalue的更改true 或任何标签为spring.cloud.kubernetes.secretvalue的 Secret 做出反应true。如果 ConfigMap 或 Secret 没有这些标签或这些标签的值没有,true则任何更改都将被忽略。

如果对具有有效标签的 ConfigMap 或 Secret 进行更改,则 Spring Cloud Kubernetes Configuration Watcher 将获取 ConfigMap 或 Secret 的名称,并向具有该名称的应用程序发送通知。但这可能不足以满足您的用例,例如您可以:

  • 将配置映射绑定到多个应用程序,以便单个配置映射内的更改触发许多服务的刷新

  • 为您的应用程序提供基于配置文件的源触发事件

因此,您可以指定一个附加注释:

spring.cloud.kubernetes.configmap.appsspring.cloud.kubernetes.secret.apps。它采用以逗号分隔的应用程序字符串,指定当此秘密/配置映射中发生更改时将收到通知的应用程序的名称。

例如:

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 配置观察器并且发生对 ConfigMap 或 Secret 的更改时,HTTP 实现将使用 Spring Cloud Kubernetes Discovery Client 来获取与 ConfigMap 或 Secret 名称匹配的应用程序的所有实例,并发送一个向应用程序的执行器 /refresh端点发出 HTTP POST 请求。默认情况下,它将使用/actuator/refresh发现客户端中注册的端口发送 post 请求。

13.3.1. 非默认管理端口和执行器路径

如果应用程序使用非默认执行器路径和/或对管理端点使用不同的端口,则应用程序的 Kubernetes 服务可以添加一个注释,并将其值设置为应用程序使用的路径和端口boot.spring.io/actuator。例如

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

您可以选择配置执行器路径和/或管理端口的另一种方法是通过设置 spring.cloud.kubernetes.configuration.watcher.actuatorPathspring.cloud.kubernetes.configuration.watcher.actuatorPort

13.4。消息传递实施

当 Spring Cloud Kubernetes Configuration Watcher 应用程序部署到 Kubernetes 时,可以通过将配置文件设置为bus-amqp(RabbitMQ) 或(Kafka) 来启用消息传递实现。bus-kafka

13.5。配置 RabbitMQ

启用配置文件后,bus-amqp您将需要配置 Spring RabbitMQ 以将其指向您要使用的 RabbitMQ 实例的位置以及进行身份验证所需的任何凭据。这可以通过设置标准 Spring RabbitMQ 属性来完成,例如

spring:
  rabbitmq:
    username: user
    password: password
    host: rabbitmq

13.6。配置卡夫卡

启用配置文件后,bus-kafka您将需要配置 Spring Kafka 以将其指向您要使用的 Kafka Broker 实例的位置。这可以通过设置标准 Spring Kafka 属性来完成,例如

spring:
  kafka:
    producer:
      bootstrap-servers: localhost:9092

14.Spring Cloud Kubernetes 配置服务器

Spring Cloud Kubernetes Config Server 在Spring Cloud Config Server 的基础上,添加了Kubernetes Config MapsSecrets的环境存储库

该组件是完全可选的。但是,它允许您继续利用在现有环境存储库(Git、SVN、Vault 等)中存储的配置以及在 Kubernetes 上运行的应用程序。

默认映像位于Docker Hub上,这使您可以轻松地在 Kubernetes 上部署配置服务器,而无需自己构建代码和映像。但是,如果您需要自定义配置服务器行为或者更喜欢自己构建映像,您可以轻松地从GitHub 上的源代码构建您自己的映像并使用它。

14.1. 配置

14.1.1. 启用 Kubernetes 环境存储库

要启用 Kubernetes 环境存储库,kubernetes配置文件必须包含在活动配置文件列表中。您也可以激活其他配置文件以使用其他环境存储库实现。

14.1.2. 配置映射和秘密属性源

默认情况下,仅获取配置映射数据。要启用 Secrets,您还需要设置spring.cloud.kubernetes.secrets.enableApi=true. PropertySource您可以通过设置禁用配置映射spring.cloud.kubernetes.config.enableApi=false

14.1.3。从其他命名空间获取配置映射和秘密数据

默认情况下,Kubernetes 环境存储库只会从部署的命名空间中获取 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 需要包含部署配置服务器的命名空间,以便继续从该命名空间获取配置映射和秘密数据。

14.1.4。Kubernetes 访问控制

Kubernetes Config Server 使用 Kubernetes API 服务器来获取 Config Map 和 Secret 数据。为了做到这一点,它需要能够配置映射getlist秘密(取决于您启用/禁用的内容)。

14.2. 部署Yaml

以下是示例部署、服务和权限配置,可用于将基本配置服务器部署到 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 发现服务器

Spring Cloud Kubernetes Discovery Server 提供了应用程序可用于收集有关 Kubernetes 集群内可用服务的信息的 HTTP 端点。应用程序可以使用 Spring Cloud Kubernetes Discovery Server为该启动器提供的实现spring-cloud-starter-kubernetes-discoveryclient提供数据。DiscoveryClient

15.1. 权限

Spring Cloud Discovery 服务器使用 Kubernetes API 服务器来获取有关服务和端点资源的数据,因此它需要列出、监视并获取使用这些端点的权限。请参阅下面的 Kubernetes 部署 YAML 示例,了解如何在 Kubernetes 上配置服务帐户的示例。

15.2. 端点

服务器公开了三个端点。

15.2.1./apps

GET发送的请求将/apps返回可用服务的 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}

请求GET/apps/{name}用于获取给定服务的所有实例的实例数据。GET以下是向发出请求时的示例响应/apps/kubernetes

[
     {
        "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}

GET发出的请求将/app/{name}/{instanceid}返回给定服务的特定实例的实例数据。GET以下是向发出请求时的示例响应/app/kubernetes/1234

 {
    "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。部署 YAML

Spring Cloud Discovery Server 的镜像托管在Docker Hub上。但是,如果您需要自定义发现服务器行为或者更喜欢自己构建映像,您可以轻松地从GitHub 上的源代码构建您自己的映像并使用它。

下面是一个示例部署 YAML,可用于将 Kubernetes 配置观察器部署到 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依赖项添加到类路径中,并删除包含DiscoveryClient实现(即 Eureka 发现客户端)的任何其他依赖项。这同样适用于PropertySourceLocator,您需要添加到类路径并删除包含实现(即配置服务器客户端)spring-cloud-kubernetes-config的任何其他依赖项。PropertySourceLocator

以下项目重点介绍了这些依赖项的用法,并演示了如何从任何 Spring Boot 应用程序中使用这些库:

17. 其他资源

本部分列出了其他资源,例如有关 Spring Cloud Kubernetes 的演示文稿(幻灯片)和视频。

18. 配置属性

要查看所有 Kubernetes 相关配置属性的列表,请查看附录页面

19. 建筑

19.1。基本编译和测试

要构建源代码,您需要安装 JDK 17。

Spring Cloud 使用 Maven 进行大多数与构建相关的活动,您应该能够通过克隆您感兴趣的项目并输入来快速开始工作

$ ./mvnw install
您还可以自行安装 Maven (>=3.3.3) 并运行以下示例中mvn的命令。如果您这样做,如果您的本地 Maven 设置不包含 Spring 预发布工件的存储库声明, ./mvnw您可能还需要添加。-P spring
MAVEN_OPTS请注意,您可能需要通过设置环境变量的值(例如 ) 来增加 Maven 可用的内存量-Xmx512m -XX:MaxPermSize=128m。我们尝试在配置中涵盖这一点.mvn,因此如果您发现必须这样做才能成功构建,请提出请求以将设置添加到源代码管理中。

需要中间件(即Redis)进行测试的项目通常需要安装并运行[Docker]( www.docker.com/get-started )的本地实例。

19.2。文档

spring-cloud-build 模块有一个“docs”配置文件,如果您打开它,它将尝试从 src/main/asciidoc. 作为该过程的一部分,它将查找 a README.adoc并通过加载所有包含内容来处理它,但不解析或渲染它,只是将其复制到${main.basedir} (默认为$/tmp/releaser-1690493683873-0/spring-cloud-kubernetes/docs,即项目的根目录)。如果 README 中有任何更改,它将在 Maven 构建后作为修改后的文件显示在正确的位置。只需提交并推动更改即可。

19.3。使用代码

如果您没有 IDE 偏好,我们建议您 在处理代码时使用Spring Tools SuiteEclipse 。我们使用 m2eclipse eclipse 插件来提供 Maven 支持。其他 IDE 和工具只要使用 Maven 3.3.3 或更高版本,也应该可以正常工作。

19.3.1。激活 Spring Maven 配置文件

Spring Cloud 项目需要激活“spring”Maven 配置文件才能解析 spring 里程碑和快照存储库。使用您首选的 IDE 将此配置文件设置为活动状态,否则您可能会遇到构建错误。

19.3.2。使用 m2eclipse 导入到 eclipse

使用 eclipse 时,我们推荐使用m2eclipse eclipse 插件。如果您尚未安装 m2eclipse,则可以从“eclipse market”获取它。

旧版本的 m2e 不支持 Maven 3.3,因此将项目导入到 Eclipse 后,您还需要告诉 m2eclipse 对项目使用正确的配置文件。如果您在项目中看到许多与 POM 相关的不同错误,请检查您是否安装了最新版本。如果您无法升级 m2e,请将“spring”配置文件添加到您的settings.xml. 或者,您可以将存储库设置从父 pom 的“spring”配置文件复制到您的settings.xml.

19.3.3。不使用m2eclipse导入eclipse

如果您不想使用 m2eclipse,可以使用以下命令生成 eclipse 项目元数据:

$ ./mvnw eclipse:eclipse

生成的 Eclipse 项目可以通过import existing projectsfile菜单中选择来导入。

19.4。在 ARM64 上构建 Docker 镜像

如果您在 ARM64 计算机上运行 Spring Cloud Kuberentes 构建,则用于集成测试的 docker 映像将由于使用错误的架构而无法运行。这是因为 Paketo 构建包尚不支持 ARM64。-Dspring-boot.build-image.builder=dashaun/builder:tiny要解决此问题,您可以通过传递给 Maven来运行构建。

例如:

./mvnw clean install -Dspring-boot.build-image.builder=dashaun/builder:tiny

20. 贡献

Spring Cloud 在非限制性 Apache 2.0 许可证下发布,并遵循非常标准的 Github 开发流程,使用 Github 跟踪器处理问题并将拉取请求合并到 master 中。如果您想贡献一些微不足道的东西,请不要犹豫,但请遵循以下准则。

20.1. 签署贡献者许可协议

在我们接受重要的补丁或拉取请求之前,我们需要您签署 贡献者许可协议。签署贡献者协议并不授予任何人对主存储库的提交权,但这确实意味着我们可以接受您的贡献,如果我们这样做,您将获得作者信用。活跃的贡献者可能会被要求加入核心团队,并被赋予合并拉取请求的能力。

20.2. 行为守则

该项目遵守贡献者契约行为准则。通过参与,您应该遵守此准则。请向spring-code-of-conduct@pivotal.io报告不可接受的行为。

20.3。代码约定和内务管理

这些对于拉取请求来说都不是必需的,但它们都会有所帮助。它们也可以在原始拉取请求之后、合并之前添加。

  • 使用 Spring 框架代码格式约定。如果您使用 Eclipse,则可以使用 Spring Cloud Buildeclipse-code-formatter.xml项目中的文件 导入格式化程序设置。如果使用 IntelliJ,您可以使用 Eclipse Code Formatter 插件导入相同的文件。

  • 确保所有新.java文件都有一个简单的 Javadoc 类注释,其中至少有一个 @author标识您的标签,最好至少有一段说明该类的用途。

  • 将 ASF 许可证头注释添加到所有新.java文件(从项目中的现有文件复制)

  • 将您自己添加到@author您进行大量修改(不仅仅是外观更改)的 .java 文件中。

  • 添加一些 Javadocs,如果更改命名空间,还添加一些 XSD 文档元素。

  • 一些单元测试也会有很大帮助——必须有人来做。

  • 如果没有其他人在使用您的分支,请根据当前主分支(或主项目中的其他目标分支)重新调整其基础。

  • 编写提交消息时请遵循以下约定,如果您要修复现有问题,请Fixes gh-XXXX在提交消息末尾添加(其中 XXXX 是问题编号)。

20.4。格子风格

Spring Cloud Build 附带了一组 checkstyle 规则。您可以在模块中找到它们spring-cloud-build-tools。该模块下最值得注意的文件是:

spring-cloud-build-tools/
└── src
    ├── checkstyle
    │   └── checkstyle-suppressions.xml (3)
    └── main
        └── resources
            ├── checkstyle-header.txt (2)
            └── checkstyle.xml (1)
1 默认 Checkstyle 规则
2 文件头设置
3 默认抑制规则

20.4.1。检查样式配置

默认情况下禁用Checkstyle 规则。要将 checkstyle 添加到您的项目中,只需定义以下属性和插件。

pom.xml
<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 错误而导致构建失败
2 因 Checkstyle 违规而导致构建失败
3 Checkstyle 还分析测试源
4 添加 Spring Java Format 插件,该插件将重新格式化您的代码以通过大多数 Checkstyle 格式化规则
5 将 checkstyle 插件添加到您的构建和报告阶段

如果您需要抑制某些规则(例如,行长度需要更长),那么您只需在${project.root}/src/checkstyle/checkstyle-suppressions.xml抑制下定义一个文件就足够了。例子:

项目根目录/src/checkstyle/checkstyle-suppresions.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项目中可以找到以下文件。

spring-cloud-build-tools/
└── 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 默认抑制规则
4 Intellij 的项目默认应用了大多数 Checkstyle 规则
5 应用大多数 Checkstyle 规则的 Intellij 项目样式约定
代码风格
图 1. 代码风格

转到FileSettingsEditorCode style。单击该Scheme部分旁边的图标。在那里,单击该Import Scheme值并选择该Intellij IDEA code style XML选项。导入spring-cloud-build-tools/src/main/resources/intellij/Intellij_Spring_Boot_Java_Conventions.xml文件。

代码风格
图 2. 检查概况

转到FileSettingsEditorInspections。单击该Profile部分旁边的图标。在那里,单击Import Profile并导入spring-cloud-build-tools/src/main/resources/intellij/Intellij_Project_Defaults.xml文件。

格子风格

要让 Intellij 与 Checkstyle 配合使用,您必须安装该Checkstyle插件。建议还安装Assertions2Assertj自动转换 JUnit 断言

格子风格

转到FileSettingsOther settingsCheckstyle。单击+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)。我们需要提供以下变量:

请记住设置为,Scan Scope因为All sources我们对生产和测试源应用 checkstyle 规则。

20.6。重复查找器

Spring Cloud Build 带来了 basepom:duplicate-finder-maven-plugin, ,可以在 java 类路径上标记重复和冲突的类和资源。

20.6.1。重复查找器配置

重复查找器默认启用,并将在verify您的 Maven 构建阶段运行,但只有将 添加到duplicate-finder-maven-plugin项目buildpom.xml.

pom.xml
<build>
    <plugins>
        <plugin>
            <groupId>org.basepom.maven</groupId>
            <artifactId>duplicate-finder-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

对于其他属性,我们设置了插件文档中列出的默认值。

您可以轻松地覆盖它们,但设置以 为前缀的所选属性的值duplicate-finder-maven-plugin。例如,设置duplicate-finder-maven-plugin.skiptrue以便在构建中跳过重复检查。

如果您需要添加ignoredClassPatternsignoredResourcePatterns到您的设置中,请确保将它们添加到项目的插件配置部分:

<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和原生镜像支持

目前,Spring Cloud Kubernetes 不支持 Spring Boot AOT 转换或原生镜像。未来版本中可能会添加部分支持。