# Spring Cloud Kubernetes
本参考指南介绍了如何使用 Spring Cloud Kubernetes。
# 1. Why do you need Spring Cloud Kubernetes?
Spring Cloud Kubernetes 提供了众所周知的 Spring Cloud接口的实现,允许开发人员在 Kubernetes 上构建和运行 Spring Cloud应用程序。虽然这个项目在构建云原生应用程序时可能对你很有用,但在 Kubernetes 上部署 Spring 启动应用程序也不是必需的。如果你刚刚开始在 Kubernetes 上运行你的启动应用程序,你只需要一个基本的启动应用程序和 Kubernetes 本身就可以完成很多事情。要了解更多信息,你可以从阅读Spring Boot reference documentation for deploying to Kubernetes (opens new window)开始,还可以阅读研讨会材料Spring and Kubernetes (opens new window)。
# 2.初学者
启动器是可以包含在应用程序中的方便的依赖关系描述符。包括一个启动器,以获得依赖关系和 Spring 一个功能集的启动自动配置。以spring-cloud-starter-kubernetes-fabric8
开头的启动器使用Fabric8Kubernetes Java 客户端 (opens new window)提供实现。以spring-cloud-starter-kubernetes-client
开头的启动器使用Kubernetes Java 客户端 (opens new window)提供实现。
起动器 | Features |
---|---|
Fabric8dependency<br/><dependency><br/> <groupId>org.springframework.cloud</groupId><br/> <artifactId>spring-cloud-starter-kubernetes-fabric8</artifactId><br/></dependency><br/> Kubernetes client dependency <br/><dependency><br/> <groupId>org.springframework.cloud</groupId><br/> <artifactId>spring-cloud-starter-kubernetes-client</artifactId><br/></dependency><br/> | Discovery Client implementation that resolves service names to Kubernetes Services. |
Fabric8dependency<br/><dependency><br/> <groupId>org.springframework.cloud</groupId><br/> <artifactId>Spring-cloud-starter-kubernetes-fabric8-config</artifactId><br/></dependency><br/> Kubernetes client dependency <br/><dependency><br/> <groupId>org.springframework.cloud</groupId><br/> <artifactId>spring-cloud-starter-kubernetes-client-config</artifactId><br/></dependency><br/> | Load application properties from KubernetesConfigMaps and Secrets.Reload application properties when a ConfigMap or Secret changes. |
Fabric8dependency<br/><dependency><br/> <groupId>org.springframework.cloud</groupId><br/> <artifactId>spring-cloud-starter-kubernetes-fabric8-all</artifactId><br/></dependency><br/> Kubernetes client dependency <br/><dependency><br/> <groupId>org.springframework.cloud</groupId><br/> <artifactId>spring-cloud-starter-kubernetes-client-all</artifactId><br/></dependency><br/> | All Spring Cloud Kubernetes features. |
# 3.Kubernetes 的发现
该项目为Kubernetes (opens new window)提供了发现客户端 (opens new window)的实现。这个客户机允许你按名称查询 Kubernetes 端点(参见services (opens new window))。Kubernetes API 服务器通常将服务公开为表示http
和https
地址的端点集合,客户端可以从 Spring 以 POD 形式运行的启动应用程序访问这些端点。
这是通过在项目中添加以下依赖项而免费获得的:
基于 httpDiscoveryClient
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-discoveryclient</artifactId>
</dependency>
spring-cloud-starter-kubernetes-discoveryclient 是设计用于Spring Cloud Kubernetes DiscoveryServer的。 |
---|
Fabric8Kubernetes 客户端
<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;
通过在application.properties
中设置以下属性,你可以从所有名称空间中选择启用DiscoveryClient
:
spring.cloud.kubernetes.discovery.all-namespaces=true
要发现未被 Kubernetes API 服务器标记为“ready”的服务端点地址,可以在application.properties
(默认:false)中设置以下属性:
spring.cloud.kubernetes.discovery.include-not-ready-addresses=true
在为监视目的发现服务时,这可能是有用的,并且将允许检查未准备好的服务实例的/health 端点。 |
---|
如果你的服务公开了多个端口,那么你将需要指定DiscoveryClient
应该使用哪个端口。DiscoveryClient
将使用以下逻辑选择端口。
如果服务有一个标签
primary-port-name
,它将使用在标签的值中指定名称的端口。如果不存在标签,则将使用
spring.cloud.kubernetes.discovery.primary-port-name
中指定的端口号。如果上面两个都没有指定,它将使用名为
https
的端口。如果上述条件都不满足,它将使用名为
http
的端口。作为最后的手段,它 WIL 在港口列表中选择第一个港口。
最后一个选项可能会导致非确定性行为。 请确保相应地配置你的服务和/或应用程序。 |
---|
默认情况下,所有端口及其名称都将添加到ServiceInstance
的元数据中。
如果出于任何原因,需要禁用DiscoveryClient
,则可以在application.properties
中设置以下属性:
spring.cloud.kubernetes.discovery.enabled=false
Spring 一些云组件使用DiscoveryClient
以便获得有关本地服务实例的信息。为此,你需要将 Kubernetes 服务名称与spring.application.name
属性对齐。
spring.application.name 对于在 Kubernetes 中为应用程序注册的名称没有任何效力 |
---|
Spring Cloud Kubernetes 还可以观察 Kubernetes 服务目录的变化并相应地更新DiscoveryClient
实现。为了启用此功能,你需要在应用程序中的配置类上添加@EnableScheduling
。
# 4.Kubernetes 原生服务发现
Kubernetes 本身能够(服务器端)发现服务(参见:Kubernetes.io/DOCS/概念/服务-网络/服务/# 发现-服务 (opens new window))。使用本机 Kubernetes 服务发现可以确保与其他工具的兼容性,例如 Istio(istio.io (opens new window)),这是一种能够实现负载平衡、断路器、故障转移等功能的服务网格。
调用方服务只需要引用特定 Kubernetes 集群中可解析的名称。一个简单的实现可以使用一个 Spring RestTemplate
,它引用一个完全限定的域名,例如[{service-name}.{namespace}.svc.{cluster}.local:{service-port}](https://{service-name}.{namespace}.svc.{cluster}.local:{service-port})
。
此外,你可以将 Hystrix 用于:
在调用方实现断路器,通过用
@EnableCircuitBreaker
注释 Spring 引导应用程序类回退功能,通过使用
@HystrixCommand(fallbackMethod=
注释相应的方法
# 5.Kubernetes PropertySource 实现
配置 Spring 启动应用程序的最常见方法是创建application.properties
或application.yaml
或application-profile.properties
或application-profile.yaml
文件,该文件包含为应用程序或 Spring 启动程序提供定制值的键值对。你可以通过指定系统属性或环境变量来覆盖这些属性。
# 5.1.使用ConfigMap``PropertySource
Kubernetes 提供了一个名为[ConfigMap
]的资源(https://kubernetes.io/DOCS/user-guide/configmap/),以外部化以键值对的形式传递给应用程序的参数,或嵌入application.properties
或application.yaml
文件。Spring Cloud Kubernetes Config (opens new window)项目使 KubernetesConfigMap
实例在应用程序引导过程中可用,并在观察到的ConfigMap
实例上检测到更改时触发 bean 或 Spring 上下文的热重载。
默认的行为是基于 Kubernetes 创建Fabric8ConfigMapPropertySource
它具有一个metadata.name
值,该值既是你的 Spring 应用程序的名称(由其spring.application.name
属性定义),也是在bootstrap.properties
文件中定义的自定义名称,该文件位于以下键下: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
,则将在应用程序运行的名称空间中查找名为ConfigMap
的c1
。请参阅名称空间解析,以更好地了解如何解析应用程序的名称空间。
找到的任何匹配的ConfigMap
将按以下方式进行处理:
应用单独的配置属性。
将名为
yaml
的任何属性的内容应用为application.yaml
。将任何名为
application.properties
的属性的内容作为属性文件应用。
上述流的一个例外是,当ConfigMap
包含一个单身键时,该键指示该文件是 YAML 或 Properties 文件。在这种情况下,键的名称不必是application.yaml
或application.properties
(它可以是任何东西),并且该属性的值被正确地处理。这个特性促进了ConfigMap
是通过使用如下内容创建的用例:
kubectl create configmap game-config --from-file=/path/to/app-config.yaml
假设我们有一个名为demo
的 Spring 引导应用程序,该应用程序使用以下属性来读取其线程池配置。
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
你还可以根据读取ConfigMap
时合并在一起的活动配置文件来不同地配置 Spring 引导应用程序。你可以通过使用application.properties
或application.yaml
属性为不同的配置文件提供不同的属性值,并在各自的文档中指定配置文件特定的值(由---
序列指示),如下所示:
kind: ConfigMap
apiVersion: v1
metadata:
name: demo
data:
application.yml: |-
greeting:
message: Say Hello to the World
farewell:
message: Say Goodbye
---
spring:
profiles: development
greeting:
message: Say Hello to the Developers
farewell:
message: Say Goodbye to the Developers
---
spring:
profiles: production
greeting:
message: Say Hello to the Ops
在前一种情况下,使用development
配置文件加载到 Spring 应用程序中的配置如下:
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 启动将基于活动配置文件自动获取它
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 在引导时应该启用哪个profile
,可以传递SPRING_PROFILES_ACTIVE
环境变量。为此,你可以使用一个环境变量启动你的 Spring 引导应用程序,你可以在容器规范的 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
and
kind: ConfigMap
apiVersion: v1
metadata:
name: config-map-two
data:
application.yml: |-
greeting:
message: Say Hello from two
根据在bootstrap.yaml|properties
中放置这些参数的顺序,你可能最终会得到一个未预期的结果(最后一个配置映射获胜)。例如:
spring:
application:
name: cloud-k8s-app
cloud:
kubernetes:
config:
namespace: default-namespace
sources:
- name: config-map-two
- name: config-map-one
将导致属性greetings.message
为Say Hello from one
。
有一种方法可以通过指定useNameAsPrefix
来更改此默认配置。例如:
spring:
application:
name: with-prefix
cloud:
kubernetes:
config:
useNameAsPrefix: true
namespace: default-namespace
sources:
- name: config-map-one
useNameAsPrefix: false
- name: config-map-two
这样的配置将生成两个属性:
greetings.message
等于Say Hello from one
。config-map-two.greetings.message
等于Say Hello from two
注意,spring.cloud.kubernetes.config.useNameAsPrefix
比spring.cloud.kubernetes.config.sources.useNameAsPrefix
具有下层的优先权。这允许你为所有源设置一个“默认”策略,同时只允许覆盖少数几个源。
如果使用配置映射名称不是一个选项,则可以指定一个不同的策略,称为:explicitPrefix
。由于这是你选择的显式前缀,因此它只能提供给sources
级别。同时它具有比useNameAsPrefix
更高的优先级。假设我们有第三个配置映射,它包含以下条目:
kind: ConfigMap
apiVersion: v1
metadata:
name: config-map-three
data:
application.yml: |-
greeting:
message: Say Hello from three
如下所示的配置:
spring:
application:
name: with-prefix
cloud:
kubernetes:
config:
useNameAsPrefix: true
namespace: default-namespace
sources:
- name: config-map-one
useNameAsPrefix: false
- name: config-map-two
explicitPrefix: two
- name: config-map-three
将生成三个属性:
greetings.message
等于Say Hello from one
。two.greetings.message
等于Say Hello from two
。config-map-three.greetings.message
等于Say Hello from three
。
默认情况下,除了读取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.cloud.kubernetes.config.paths
属性控制。你可以在前面描述的机制之外使用它,也可以使用它来代替它。通过使用,
分隔符,可以在spring.cloud.kubernetes.config.paths
中指定多个(精确的)文件路径。
你必须为每个属性文件提供完整的精确路径,因为目录不是递归解析的。 |
---|
如果使用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
。然后,你需要在 Classpath 中添加spring-retry
和spring-boot-starter-aop
。你可以通过设置spring.cloud.kubernetes.config.retry.*
属性来配置重试属性,如最大尝试次数、退避选项(如初始间隔、乘法器、最大间隔)。
如果由于某种原因在 Classpath 上已经有spring-retry 和spring-boot-starter-aop 并且希望启用 fail-fast,但是不希望被启用重试;你可以通过设置 ConfigMap 来禁用PropertySources 的重试。 |
---|
Name | Type | Default | 说明 |
---|---|---|---|
spring.cloud.kubernetes.config.enabled | Boolean | true | 启用配置图PropertySource |
spring.cloud.kubernetes.config.name | String | ${spring.application.name} | 设置ConfigMap 的名称以进行查找 |
spring.cloud.kubernetes.config.namespace | String | Client namespace | 设置要查找的 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.秘密 PropertySource
Kubernetes 有Secrets (opens new window)的概念,用于存储诸如密码、OAuth 令牌等敏感数据。该项目提供了与Secrets
的集成,以使 Spring 引导应用程序能够访问秘密。你可以通过设置spring.cloud.kubernetes.secrets.enabled
属性显式地启用或禁用此功能。
启用后,Fabric8SecretsPropertySource
将从以下来源查找Secrets
的 kubernetes:
从秘密挂载中递归地读取
以应用程序命名(由
spring.application.name
定义)匹配一些标签
注:
默认情况下,出于安全原因,通过 API(以上第 2 点和第 3 点)未启用消耗秘密。Secrets 上的权限“列表”允许客户端检查指定名称空间中的 Secrets 值。此外,我们建议容器通过安装的卷共享秘密。
如果你允许通过 API 使用机密,我们建议你使用授权策略(例如 RBAC)来限制对机密的访问。有关通过 API 使用秘密时的风险和最佳实践的更多信息,请参阅this doc (opens new window)。
如果发现了这些秘密,它们的数据就会提供给应用程序。
假设我们有一个名为demo
的 Spring 引导应用程序,该应用程序使用属性来读取其数据库配置。我们可以使用以下命令创建一个 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
请注意,该数据包含由create
命令提供的基本 64 编码版本的文字。
然后,你的应用程序可以使用这个秘密——例如,通过将秘密的值导出为环境变量:
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
你可以通过多种方式选择要使用的秘密:
通过列出映射秘密的目录:
-Dspring.cloud.kubernetes.secrets.paths=/etc/secrets/db-secret,etc/secrets/postgresql
如果你将所有的秘密映射到一个公共根,则可以将它们设置为:
-Dspring.cloud.kubernetes.secrets.paths=/etc/secrets
通过设置一个命名的秘密:
-Dspring.cloud.kubernetes.secrets.name=db-secret
通过定义标签列表:
-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
,则将在应用程序运行的名称空间中查找名为Secret
的Secret
。请参阅名称空间分辨率,以更好地了解如何解析应用程序的名称空间。
[类似于ConfigMaps
](#config-map-fail-fast);如果你希望你的应用程序在无法加载Secrets
属性源时启动失败,则可以设置spring.cloud.kubernetes.secrets.fail-fast=true
。
也可以为Secret
属性源[比如ConfigMaps
]启用重试(#config-map-retry)。与ConfigMap
属性源一样,首先需要设置spring.cloud.kubernetes.secrets.fail-fast=true
。然后,你需要在 Classpath 中添加spring-retry
和spring-boot-starter-aop
。通过设置spring.cloud.kubernetes.secrets.retry.*
属性,可以配置Secret
属性源的重试行为。
如果由于某种原因在 Classpath 上已经有spring-retry 和spring-boot-starter-aop 并且希望启用 fail-fast,但是不希望被启用重试;你可以通过设置 spring.cloud.kubernetes.secrets.retry.enabled=false 来禁用PropertySources 的重试。 |
---|
Name | Type | Default | 说明 |
---|---|---|---|
spring.cloud.kubernetes.secrets.enabled | Boolean | true | 启用秘密PropertySource |
spring.cloud.kubernetes.secrets.name | String | ${spring.application.name} | 设置要查找的秘密的名称 |
spring.cloud.kubernetes.secrets.namespace | String | Client namespace | 将 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
属性的行为由基于地图的绑定 (opens new window)定义。spring.cloud.kubernetes.secrets.paths
属性的行为由基于集合的绑定 (opens new window)定义。出于安全原因,通过 API 访问机密可能会受到限制。最好的办法是把秘密装在吊舱里。
你可以在spring-boot-camel-config (opens new window)找到一个使用秘密的应用程序示例(尽管它尚未更新为使用新的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
请记住,配置映射也可以这样做。如果没有指定这样的命名空间,则将读取它(按此顺序):
来自 property
spring.cloud.kubernetes.client.namespace
来自驻留在由
spring.cloud.kubernetes.client.serviceAccountNamespacePath
属性表示的文件中的字符串来自驻留在
/var/run/secrets/kubernetes.io/serviceaccount/namespace
文件中的字符串(Kubernetes 缺省名称空间路径)从指定的客户端方法调用(例如 Fabric8 的:
KubernetesClient::getNamespace
),如果客户端提供了这样的方法。这又可以通过环境属性进行配置。例如,可以通过“Kubernetes_Namespace”属性配置 Fabric8 客户机;有关详细信息,请参阅客户机文档。
未能从上述步骤中找到名称空间将导致引发异常。
# 5.4.PropertySource
重新加载
该功能在 2020.0 版本中已被弃用。请参阅 的Spring Cloud Kubernetes Configuration Watcher控制器以替代 的方式实现相同的功能。 |
---|
一些应用程序可能需要检测外部属性源上的更改,并更新其内部状态以反映新的配置。 Spring Cloud Kubernetes 的重新加载功能能够在相关的ConfigMap
或Secret
发生变化时触发应用程序重新加载。
默认情况下,此功能将被禁用。你可以通过使用spring.cloud.kubernetes.reload.enabled=true
配置属性(例如,在application.properties
文件中)来启用它。
支持以下级别的重新加载(通过设置spring.cloud.kubernetes.reload.strategy
属性):
refresh
(缺省):只有注解为@ConfigurationProperties
或@RefreshScope
的配置 bean 才会重新加载。这个重新加载级别利用了 Spring Cloud上下文的刷新功能。restart_context
:整个 SpringApplicationContext
被优雅地重新启动。使用新配置重新创建 bean。为了使 Restart 上下文功能正常工作,你必须启用并公开 Restart Actuator 端点
management:
endpoint:
restart:
enabled: true
endpoints:
web:
exposure:
include: restart
shutdown
:关闭 SpringApplicationContext
以激活容器的重新启动。使用此级别时,请确保所有非守护进程线程的生命周期都绑定到ApplicationContext
,并且配置了一个复制控制器或复制集来重新启动 POD。
假设使用默认设置(refresh
模式)启用了 Reload 功能,则在配置映射发生更改时将刷新以下 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 关联](#configmap-propertysource)在本章的前面进行了解释。
完整示例可在[spring-cloud-kubernetes-reload-example
](https://github.com/ Spring-cloud/ Spring-cloud-kubernetes/tree/main/ Spring-cloud-kubernetes-examples/kubernetes-reload-example)中找到。
Reload 功能支持两种操作模式:* 事件(默认):通过使用 Kubernetes API(Web 套接字)监视配置映射或秘密中的更改。任何事件都会产生对配置的重新检查,如果发生更改,还会产生重新加载。为了监听配置映射更改,服务帐户上的view
角色是必需的。机密需要更高级别的角色(例如edit
)(默认情况下,机密不受监视)。* 轮询:周期性地从配置映射和秘密中重新创建配置,以查看它是否已更改。可以使用spring.cloud.kubernetes.reload.period
属性配置轮询周期,默认设置为 15 秒。它需要与受监视的属性源具有相同的角色。这意味着,例如,在文件挂载的秘密源上使用轮询不需要特定的权限。
Name | Type | Default | 说明 |
---|---|---|---|
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 | 在启动重新加载时使用的策略(refresh ,restart_context ,或shutdown ) |
spring.cloud.kubernetes.reload.mode | Enum | event | 指定如何侦听属性源中的更改(event 或polling ) |
spring.cloud.kubernetes.reload.period | Duration | 15s | 使用polling 策略时验证更改的周期 |
注意:* 你不应该在配置映射或秘密中使用spring.cloud.kubernetes.reload
下的属性。在运行时更改这些属性可能会导致意想不到的结果。* 当你使用refresh
级别时,删除属性或整个配置映射不会恢复 bean 的原始状态。
# 6.Kubernetes 生态系统意识
无论你的应用程序是否在 Kubernetes 内部运行,本指南前面描述的所有功能都同样有效。这对于开发和故障排除非常有帮助。从开发的角度来看,这允许你启动 Spring 引导应用程序,并调试该项目的一个模块。你不需要在 Kubernetes 中部署它,因为项目的代码依赖于Fabric8Kubernetes Java 客户端 (opens new window),这是一种 Fluent DSL,可以通过使用http
协议与 Kubernetes 服务器的 REST API 进行通信。
要禁用与 Kubernetes 的集成,你可以将spring.cloud.kubernetes.enabled
设置为false
。请注意,当spring-cloud-kubernetes-config
在 Classpath 上时,spring.cloud.kubernetes.enabled
应设置在bootstrap.{properties|yml}
(或配置文件指定的一个)中,否则应设置在application.{properties|yml}
(或配置文件指定的一个)中。由于我们在spring-cloud-kubernetes-config
中设置特定的EnvironmentPostProcessor
的方式,你还需要通过系统属性(或环境变量)禁用该处理器,例如,你可以通过-DSPRING_CLOUD_KUBERNETES_ENABLED=false
启动应用程序(任何形式的放松绑定也可以工作)。还要注意这些属性:spring.cloud.kubernetes.config.enabled
和spring.cloud.kubernetes.secrets.enabled
仅在bootstrap.{properties|yml}
中设置时才生效
# 6.1.Kubernetes 配置文件自动配置
当应用程序在 Kubernetes 中作为 POD 运行时,一个名为kubernetes
的 Spring 配置文件会自动被激活。这使你可以定制配置,以定义在 Spring 引导应用程序部署在 Kubernetes 平台中时应用的 bean(例如,不同的开发和生产配置)。
# 6.2.Istio 意识
当在应用程序 Classpath 中包含spring-cloud-kubernetes-fabric8-istio
模块时,将向应用程序添加一个新的配置文件,前提是该应用程序在安装了Istio (opens new window)的 Kubernetes 集群中运行。然后可以在 bean 和@Configuration
类中使用 Spring @Profile("istio")
注释。
Istio Awareness 模块使用me.snowdrop:istio-client
与 Istio API 进行交互,让我们发现交通规则、断路器等等,使我们的 Spring 引导应用程序很容易使用这些数据来根据环境动态配置自己。
# 7.POD 健康指示器
Spring Boot 使用[HealthIndicator
](https://github.com/ Spring-projects/ Spring-boot/blob/master/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/health/healthendpoint.java)来公开有关应用程序健康的信息。这使得它对于向用户公开与健康相关的信息非常有用,并且非常适合作为准备状态调查 (opens new window)使用。
Kubernetes 健康指示器(它是核心模块的一部分)公开了以下信息:
POD 名称、IP 地址、命名空间、服务帐户、节点名称及其 IP 地址
指示 Spring 引导应用程序是 Kubernetes 的内部还是外部的标志
你可以通过在application.[properties | yaml]
中将management.health.kubernetes.enabled
设置为false
来禁用此HealthContributor
。
# 8.信息贡献者
Spring Cloud Kubernetes 包括一个InfoContributor
,它将 POD 信息添加到 Spring Boot 的/info
Acturator 端点。
你可以通过在application.[properties | yaml]
中将management.info.kubernetes.enabled
设置为false
来禁用此InfoContributor
。
# 9.领导人选举
Spring Cloud Kubernetes 领导人选举机制使用 Kubernetes 配置图实现 Spring 集成的领导人选举 API。
多个应用程序实例竞争领导权,但领导权将只授予一个。当授予领导权时,领导者应用程序将接收带有领导权OnGrantedEvent
的OnGrantedEvent
应用程序事件。应用程序会定期尝试获得领导力,并将领导力授予第一个呼叫者。领导者将一直是领导者,直到被从集群中移除,或者交出领导者。当领导层被撤职时,前一位领导人将收到OnRevokedEvent
应用程序事件。删除后,集群中的任何实例都可能成为新的领导者,包括旧的领导者。
要将它包含在项目中,请添加以下依赖项。
Fabric8Leader 实现
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-fabric8-leader</artifactId>
</dependency>
要指定用于领导者选举的配置图的名称,请使用以下属性。
spring.cloud.kubernetes.leader.config-map-name=leader
# 10.Kubernetes 负载平衡器
Spring 该项目包括用于基于 Kubernetes 端点的负载平衡的云负载平衡器和提供基于 Kubernetes 服务的负载平衡器的实现。要将它包含到项目中,请添加以下依赖项。
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 发行版,你需要确保使用spring-cloud-kubernetes
运行的 POD 能够访问 Kubernetes API。对于分配给部署或 POD 的任何服务帐户,你需要确保它们具有正确的角色。
根据需求,你将需要get
、list
和watch
对以下资源的权限:
依赖性 | Resources |
---|---|
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 |
出于开发目的,你可以将cluster-reader
权限添加到你的default
服务帐户。在生产系统中,你可能希望提供更细粒度的权限。
下面的 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 提供了在应用程序的容器中将配置图或秘密挂载为卷 (opens new window)的功能。当配置图或秘密的内容发生变化时,安装的卷将会随着这些变化而更新。 (opens new window)。
然而, Spring 启动不会自动更新这些更改,除非重新启动应用程序。 Spring Cloud提供了在不重新启动应用程序的情况下刷新应用程序上下文的能力,而无需通过点击执行器端点/refresh
或通过使用 Spring Cloud总线发布RefreshRemoteApplicationEvent
。
要实现在 Kubernetes 上运行的 Spring Cloud应用程序的这种配置刷新,你可以将 Spring Cloud Kubernetes 配置观察控制器部署到你的 Kubernetes 集群中。
该应用程序作为容器发布,并在Docker Hub (opens new window)上可用。
Spring Cloud Kubernetes 配置观察者可以通过两种方式向应用程序发送刷新通知。
在 HTTP 上,在这种情况下,被通知的应用程序必须将
/refresh
执行器端点公开并可从集群内访问Spring 使用云总线,在这种情况下,你将需要部署到你的 Custer 的消息代理,以便应用程序使用。
# 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 集群中的配置映射、POD、服务、端点和秘密的数据。
# 13.2.监视配置图和秘密
Spring Cloud Kubernetes Configuration Watcher 将对带有值true
的标签的spring.cloud.kubernetes.config
的配置映射中的更改或带有值true
的标签的spring.cloud.kubernetes.secret
的任何秘密做出反应。如果配置图或秘密没有这些标签中的任何一个,或者这些标签的值不是true
,那么任何更改都将被忽略。
Spring Cloud Kubernetes 配置观察者在配置地图上寻找的标签和秘密可以通过分别设置spring.cloud.kubernetes.configuration.watcher.configLabel
和spring.cloud.kubernetes.configuration.watcher.secretLabel
来进行更改。
如果对具有有效标签的配置图或秘密进行了更改,则 Spring Cloud Kubernetes 配置观察者将获取配置图或秘密的名称,并向具有该名称的应用程序发送通知。
# 13.3.HTTP 实现
默认情况下使用的是 HTTP 实现。当使用 Spring Cloud Kubernetes 配置监视器并且发生对配置图或秘密的更改时,那么 HTTP 实现将使用 Spring Cloud Kubernetes 发现客户端来获取与配置图或秘密的名称相匹配的应用程序的所有实例并向应用程序的执行器/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.actuatorPath
和spring.cloud.kubernetes.configuration.watcher.actuatorPort
。
# 13.4.消息传递实现
当 Spring Cloud Kubernetes Configuration Watcher 应用程序部署到 Kubernetes 时,可以通过将配置文件设置为或来启用消息传递实现。
# 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 代理实例的位置。这可以通过设置标准 Spring Kafka 属性来完成,例如
spring:
kafka:
producer:
bootstrap-servers: localhost:9092
# 14. Spring Cloud Kubernetes Config Server
Spring Cloud Kubernetes Config 服务器基于Spring Cloud Config Server (opens new window),并为 Kubernetes配置映射 (opens new window)和Secrets (opens new window)添加了环境存储库 (opens new window)。
这是一个完全可选的组件。然而,它允许你继续利用你在 Kubernetes 上运行的应用程序来利用可能存储在现有环境存储库(Git、SVN、Vault 等)中的配置。
默认映像位于Docker Hub (opens new window)上,这将允许你轻松地获得部署在 Kubernetes 上的配置服务器,而无需自己构建代码和映像。但是,如果你需要自定义配置服务器行为,你可以轻松地从 Github 上的源代码构建自己的映像并使用它。
# 14.1.配置
# 14.1.1.启用 Kubernetes 环境存储库
要启用 Kubernetes 环境存储库,kubernetes
配置文件必须包含在活动配置文件列表中。你也可以激活其他配置文件来使用其他环境存储库实现。
# 14.1.2.配置映射和秘密 PropertySources
默认情况下,将只获取配置映射数据。要启用秘密,还需要设置spring.cloud.kubernetes.secrets.enableApi=true
。你可以通过设置spring.cloud.kubernetes.config.enableApi=false
来禁用配置映射PropertySource
。
# 14.1.3.从其他名称空间获取配置映射和秘密数据
默认情况下,Kubernetes 环境存储库将仅从部署它的名称空间获取配置映射和秘密。如果希望包括来自其他名称空间的数据,则可以将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 配置服务器使用 Kubernetes API 服务器获取配置映射和秘密数据。为了做到这一点,它需要get
和list
配置映射和秘密(取决于你启用/禁用的内容)。
# 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 Discovery Server
Spring Cloud Kubernetes 发现服务器提供了应用程序可以用来收集关于 Kubernetes 集群中可用的服务的信息的 HTTP 端点。 Spring Cloud Kubernetes 发现服务器可以由使用spring-cloud-starter-kubernetes-discoveryclient
的应用程序使用,以向由该启动器提供的DiscoveryClient
实现提供数据。
# 15.1.权限
Spring Cloud发现服务器使用 Kubernetes API 服务器来获取有关服务和端点重排的数据,因此它需要列表、监视和获得使用这些端点的权限。有关如何在 Kubernetes 上配置服务帐户的示例,请参见下面的示例 Kubernetes Deployment YAML。
# 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./app/{name}
可以使用对/app/{name}
的GET
请求来获取给定服务的所有实例的实例数据。下面是对GET
请求进行/app/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}
向/app/{name}/{instanceid}
发出的GET
请求将返回给定服务的特定实例的实例数据。下面是当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发现服务器的图像托管在Docker Hub (opens new window)上。
下面是一个示例部署 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:2.1.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 发现客户机)的任何其他依赖项。这同样适用于PropertySourceLocator
,其中你需要将spring-cloud-kubernetes-config
添加到 Classpath 中,并删除包含PropertySourceLocator
实现(即配置服务器客户端)的任何其他依赖项。
下面的项目重点介绍了这些依赖关系的用法,并演示了如何从任何 Spring 启动应用程序中使用这些库:
Spring Cloud Kubernetes Examples (opens new window):位于此存储库中的那些。
Spring Cloud Kubernetes 完整示例:小黄人和老板
Spring Cloud Kubernetes 全例:Springone 站台售票服务 (opens new window)
Spring Cloud Gateway with Spring Cloud Kubernetes Discovery and Config (opens new window)
Spring Boot Admin with Spring Cloud Kubernetes Discovery and Config (opens new window)
# 17.其他资源
本节列出了其他资源,例如关于 Spring Cloud Kubernetes 的演示文稿(幻灯片)和视频。
请随时通过 pull 请求提交其他资源到这个存储库 (opens new window)。
# 18.配置属性
要查看所有 Kubernetes 相关配置属性的列表,请检查附录页。
# 19.建筑物
# 19.1.基本编译和测试
要构建源代码,你需要安装 JDK17.
Spring Cloud 在大多数与构建相关的活动中使用 Maven,你应该能够通过克隆感兴趣的项目并键入来很快地开始工作。
$ ./mvnw install
你也可以自己安装 Maven(>=3.3.3),并在下面的示例中运行mvn 命令来代替 ./mvnw 。如果你这样做,那么如果你的本地 Maven 设置不包含 Spring 预发布工件的存储库声明,那么你可能还需要添加 -P spring 。 |
---|
请注意,你可能需要通过将 环境变量设置为 -Xmx512m -XX:MaxPermSize=128m ,从而增加 Maven 可用的内存量。我们试图在 .mvn 配置中覆盖此内容,因此,如果你发现必须这样做才能使构建成功,请提出一张票据,以将设置添加到 源代码控制中。 |
---|
需要中间件(即 Redis)进行测试的项目通常需要安装并运行[Docker](WWW.docker.com/get-started (opens new window))的本地实例。
# 19.2.文件
Spring-cloud-build 模块有一个“DOCS”配置文件,如果你将其打开,它将尝试从src/main/asciidoc
构建 ASCIIDoc 源。作为该过程的一部分,它将寻找README.adoc
,并通过加载所有的包含来处理它,但不是解析或呈现它,只是将其复制到${main.basedir}
(默认为$/tmp/releaser-1645122597379-0/spring-cloud-kubernetes/docs
,即项目的根)。如果 README 中有任何更改,那么在构建 Maven 之后,它将在正确的位置显示为经过修改的文件。只要承诺并推动改变就行了。
# 19.3.使用代码
如果你没有 IDE 偏好,我们建议你在使用代码时使用Spring Tools Suite (opens new window)或Eclipse (opens new window)。我们使用m2eclipse (opens new window)Eclipse 插件来提供 Maven 支持。其他 IDE 和工具也应该在没有问题的情况下工作,只要它们使用 Maven 3.3.3 或更好。
# 19.3.1. Activate the Spring Maven profile
Spring Cloud项目需要激活“ Spring” Maven 配置文件以解析 Spring 里程碑和快照存储库。使用你首选的 IDE 将此配置文件设置为活动的,否则你可能会遇到构建错误。
# 19.3.2.用 M2Eclipse 导入到 Eclipse 中
在使用 Eclipse 时,我们推荐m2eclipse (opens new window)Eclipse 插件。如果你还没有安装 M2Eclipse,它可以从“Eclipse 市场”获得。
较早版本的 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
可以通过从file
菜单中选择import existing projects
来导入生成的 Eclipse 项目。
# 20.贡献
Spring Cloud是在非限制性的 Apache2.0 许可下发布的,并遵循非常标准的 GitHub 开发过程,使用 GitHub Tracker 处理问题并将拉请求合并到 Master 中。如果你想贡献一些微不足道的东西,请不要犹豫,但要遵循下面的指导方针。
# 20.1.签署贡献者许可协议
在我们接受一个重要的补丁或拉请求之前,我们需要你签署贡献者许可协议 (opens new window)。签署贡献者协议并不会授予任何人对主库的提交权限,但这确实意味着我们可以接受你的贡献,并且如果我们接受了,你将获得作者信用。活跃的贡献者可能会被要求加入核心团队,并被赋予合并拉请求的能力。
# 20.2.行为守则
此项目遵守贡献者契约行为守则 (opens new window)。通过参与,你将被期望坚持这一准则。请向[[电子邮件保护]]报告不可接受的行为(/cdn-cgi/l/email-protection#D4A7A4A6BDBAB3F9B7BBB0B1F9BBB2F9B7BBBAB0A1B7A7A7A7A9A094A4BDA2BBA0B5B8FABDBB)。
# 20.3.守则惯例和内部管理
这些都不是拉请求所必需的,但它们都会有所帮助。它们也可以在原始的拉请求之后但在合并之前添加。
使用 Spring 框架代码格式约定。如果使用 Eclipse,则可以使用
eclipse-code-formatter.xml
文件从Spring Cloud Build (opens new window)项目导入格式化设置。如果使用 IntelliJ,可以使用Eclipse 代码格式化插件 (opens new window)导入相同的文件。确保所有新的
.java
文件都有一个简单的 Javadoc 类注释,其中至少有一个@author
标记来标识你,并且最好至少有一个段落来说明类的用途。将 ASF 许可标头注释添加到所有新的
.java
文件(从项目中的现有文件复制)将自己作为
@author
添加到要进行实质性修改的.java 文件中(不仅仅是外观上的更改)。添加一些 Javadocs,如果你更改了名称空间,还可以添加一些 XSDDOC 元素。
几个单元测试也会有很大帮助——必须有人去做。
如果没有其他人正在使用你的分支,请将它重新设置为当前的主分支(或主项目中的其他目标分支)。
在编写提交消息时,请遵循这些约定 (opens new window),如果你正在修复现有的问题,请在提交消息的末尾添加
Fixes gh-XXXX
(其中 xxxx 是问题编号)。
# 20.4.checkstyle
Spring Cloud构建附带一组 CheckStyle 规则。你可以在spring-cloud-build-tools
模块中找到它们。该模块下最值得注意的文件是:
Spring-云构建工具/
└── src
├── checkstyle
│ └── checkstyle-suppressions.xml (3)
└── main
└── resources
├── checkstyle-header.txt (2)
└── checkstyle.xml (1)
1 | 默认的 checkstyle 规则 |
---|---|
2 | 文件头设置 |
3 | 默认抑制规则 |
# 20.4.1.checkstyle 配置
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 格式插件,该插件将重新格式化你的代码,以传递大多数 CheckStyle 格式设置规则 |
5 | 将 CheckStyle 插件添加到构建和报告阶段 |
如果你需要抑制一些规则(例如行长需要更长),那么在${project.root}/src/checkstyle/checkstyle-suppressions.xml
下定义一个文件就足够了。示例:
projectRoot/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 思想
为了设置 IntelliJ,你应该导入我们的编码约定、检查配置文件并设置 CheckStyle 插件。以下文件可以在Spring Cloud Build (opens new window)项目中找到。
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 | 适用大多数 CheckStyle 规则的 IntelliJ 的项目默认值 |
5 | 适用大多数 CheckStyle 规则的 IntelliJ 的项目风格约定 |
图 1.代码样式
转到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
文件。
图 2.检查剖面
转到File``Settings``Editor``Inspections
。点击Profile
区域旁边的图标。在那里,单击Import Profile
并导入spring-cloud-build-tools/src/main/resources/intellij/Intellij_Project_Defaults.xml
文件。
checkstyle
要让 IntelliJ 使用 CheckStyle,你必须安装Checkstyle
插件。建议还安装Assertions2Assertj
来自动转换 JUnit 断言
转到File``Settings``Other settings``Checkstyle
。点击Configuration file
部分中的+
图标。在这里,你必须定义应该从哪里选择 CheckStyle 规则。在上面的图片中,我们从克隆的 Spring Cloud构建存储库中选择了规则。但是,你可以指向 Spring Cloud Build 的 GitHub 存储库(例如checkstyle.xml
:[raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle.xml](https://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](https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle-header.txt)
URL。checkstyle.suppressions.file
-默认抑制。请将它指向 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](https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml)
URL。checkstyle.additional.suppressions.file
-此变量对应于本地项目中的抑制。例如,你正在处理spring-cloud-contract
。然后指向project-root/src/checkstyle/checkstyle-suppressions.xml
文件夹。spring-cloud-contract
的例子是:/home/username/spring-cloud-contract/src/checkstyle/checkstyle-suppressions.xml
。
请记住将Scan Scope 设置为All sources ,因为我们为生产和测试源应用了 checkstyle 规则。 |
---|
# 20.6.重复查找器
Spring Cloud构建带来了basepom:duplicate-finder-maven-plugin
,这使得能够在 Java Classpath 上标记重复的和冲突的类和资源。
# 20.6.1.重复查找器配置
重复查找器是默认启用,将在 Maven 构建的verify
阶段运行,但是只有在项目的duplicate-finder-maven-plugin
部分中添加duplicate-finder-maven-plugin
,它才会在项目中生效。
POM.xml
<build>
<plugins>
<plugin>
<groupId>org.basepom.maven</groupId>
<artifactId>duplicate-finder-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
对于其他属性,我们设置了插件文档 (opens new window)中列出的默认值。
你可以轻松地重写它们,但可以使用duplicate-finder-maven-plugin
前缀设置所选属性的值。例如,将duplicate-finder-maven-plugin.skip
设置为true
,以便在构建中跳过重复检查。
如果需要将ignoredClassPatterns
或ignoredResourcePatterns
添加到设置中,请确保将它们添加到项目的插件配置部分中:
<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>