Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Kubernetes native configuration management #3119

Open
wants to merge 37 commits into
base: 2021.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
37cafe4
add kubernetes module
DanielLiu1123 Jan 28, 2023
7a09dda
keep going, almost done
DanielLiu1123 Jan 29, 2023
233ce20
rollback docs
DanielLiu1123 Jan 29, 2023
bb5e461
not use raw type
DanielLiu1123 Jan 30, 2023
6b82542
remove dummy methods
DanielLiu1123 Jan 30, 2023
d425fa2
add comments
DanielLiu1123 Jan 30, 2023
bcd5756
rename to Preference
DanielLiu1123 Jan 30, 2023
4eda957
continue to optimize the code
DanielLiu1123 Jan 31, 2023
fb27ffd
fix checkstyle
DanielLiu1123 Jan 31, 2023
1cd0227
close context
DanielLiu1123 Jan 31, 2023
4335a72
optimize config properties
DanielLiu1123 Jan 31, 2023
632eb66
avoid property sources have same name
DanielLiu1123 Feb 1, 2023
0542d09
add kubernetes config README
DanielLiu1123 Feb 1, 2023
f00557c
make log method static
DanielLiu1123 Feb 2, 2023
2d2cb16
add example
DanielLiu1123 Feb 2, 2023
03a30bb
remove used code
DanielLiu1123 Feb 3, 2023
9706561
fix config missing when using both configmap and secret
DanielLiu1123 Feb 3, 2023
f795234
Revert "fix config missing when using both configmap and secret"
DanielLiu1123 Feb 3, 2023
36b03fd
only refresh current resource
DanielLiu1123 Feb 3, 2023
e630eda
make HasMetadataResourceEventHandler package private
DanielLiu1123 Feb 3, 2023
9b4ff99
method name lowercase
DanielLiu1123 Feb 3, 2023
92be687
docs and example done
DanielLiu1123 Feb 4, 2023
0f06277
fix docs
DanielLiu1123 Feb 4, 2023
38bbada
add zh docs
DanielLiu1123 Feb 4, 2023
4ac940d
fix docs
DanielLiu1123 Feb 4, 2023
565d545
revert rocketmq package
DanielLiu1123 Feb 4, 2023
dee3443
add comments
DanielLiu1123 Feb 4, 2023
837c41d
add exmaple docs note
DanielLiu1123 Feb 8, 2023
9043a5a
add it package for integration tests
DanielLiu1123 Feb 8, 2023
89c9ce2
rename to KubernetesConfigWatcher
DanielLiu1123 Feb 18, 2023
e5e5fbe
fix docs
DanielLiu1123 Feb 18, 2023
a554d7c
update docs
DanielLiu1123 Feb 22, 2023
c22d21e
optimize KubernetesClientHolder
DanielLiu1123 Feb 22, 2023
9e70430
change prefix to alibaba-kubernetes
DanielLiu1123 Mar 5, 2023
3ea493a
optimize getKubernetesClient method
DanielLiu1123 Mar 5, 2023
daa62f6
ci oom, ignore integration tests
DanielLiu1123 Mar 5, 2023
1059ca1
update maven 3.9.0
DanielLiu1123 Mar 5, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 12 additions & 0 deletions spring-cloud-alibaba-dependencies/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,18 @@
<version>${revision}</version>
</dependency>

<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-kubernetes-commons</artifactId>
<version>${revision}</version>
</dependency>

<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-kubernetes-config</artifactId>
<version>${revision}</version>
</dependency>

<dependency>
<groupId>com.alibaba.spring</groupId>
<artifactId>spring-context-support</artifactId>
Expand Down
145 changes: 145 additions & 0 deletions spring-cloud-alibaba-docs/src/main/asciidoc-zh/kubernetes-config.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
== Spring Cloud Alibaba Kubernetes Config

link:../asciidoc/kubernetes-config.adoc[English] | link:kubernetes-config.adoc[中文]

该模块的目的是利用 Kubernetes ConfigMap/Secret 作为分布式配置中心,实现无需重启应用的动态配置更新。

=== 快速开始

参考 link:../../../../spring-cloud-alibaba-examples/kubernetes-config-example/README-zh.md[example],按照文档运行一下 demo,你可以的!

=== 主要特性

如果你有使用 `spring-cloud-starter-alibaba-nacos-config` 的经验,你会发现其用法非常相似。`spring-cloud-starter-alibaba-kubernetes-config` 提供了 `spring-cloud-starter-alibaba-nacos-config` 的所有核心功能,并提供了更容易使用的配置,更好的性能和云原生程序契合度。

==== 配置动态刷新(ConfigMap/Secret)

当配置更新时,不需要重新启动应用程序,应用程序可以实时地动态更新配置。

NOTE: Spring Cloud 提供了在运行时动态刷新环境的能力,这主要是动态更新两类 Bean 的属性:`@ConfigurationProperties` 和 `@RefreshScope` Bean。

*最佳实践:使用 `@ConfigurationProperties` 来组织你的配置!*

相关配置:

[source,yaml]
----
spring:
cloud:
k8s:
config:
refreshable: false # 全局默认配置,默认值为 false
config-maps:
- name: my-configmap
refreshable: true # my-configmap 将检测配置更改并刷新
secrets:
- name: my-secret # my-secret 不会检测配置更改和刷新
----

==== 配置优先级

如果本地的 `application.yml` 和 ConfigMap/Secret 中有相同的配置,可以选择优先使用哪个配置。

相关配置:

[source,yaml]
----
spring:
cloud:
k8s:
config:
preference: remote # 全局默认配置,默认值为remote,表示远程配置会覆盖本地配置
config-maps:
- name: my-configmap
preference: local
----

==== 多种配置文件格式

支持 `yaml`、`properties`、`json` 和键值对配置。

NOTE: Secret 只支持键值对!

Example:

ConfigMap:

[source,yaml]
----
apiVersion: v1
kind: ConfigMap
metadata:
name: my-configmap
data:
blacklist.yml: |
blacklist:
user-ids:
- 1
- 2
----

Secret:

[source,yaml]
----
apiVersion: v1
kind: Secret
metadata:
name: my-secret
stringData:
blacklist.user-ids[0]: 1
blacklist.user-ids[1]: 2
----

上面的两个配置是等价的。

==== 异常操作保护

如果配置被错误地删除,你不希望你的应用程序崩溃,对吗?`spring-cloud-starter-alibaba-kubernetes-config` 提供了一个机制来保护应用程序免受异常操作的影响,比如误删配置。

相关配置:

[source,yaml]
----
spring:
cloud:
k8s:
config:
refresh-on-deleted: false # 当检测到配置被删除时,应用程序不会触发刷新。默认值为 false。
----

如果你的配置没有跨环境同步,你在 `dev` 环境中有 `import-config` 配置,但在 `prod` 环境中没有(有可能是你忘记同步到 `prod`),你可能希望有一个机制来帮助你发现这个问题,并提供快速失败的能力来阻止应用程序启动。

相关配置:

[source,yaml]
----
spring:
cloud:
k8s:
config:
fail-on-missing-config: true # 如果找不到配置,应用程序将无法启动。默认值为 true。
----

=== 核心配置

[source,yaml]
----
spring:
cloud:
k8s:
config:
enabled: true
namespace: default # 配置所在的命名空间(全局配置)。如果在 Kubernetes 集群内部,则默认为当前 pod 所在的命名空间;如果在 Kubernetes 集群之外,则默认为当前 context 的命名空间。
preference: remote
refreshable: false
refresh-on-delete: false
fail-on-missing-config: true
config-maps:
- name: my-configmap
preference: remote
refreshable: true
secrets:
- name: my-secret
namespace: secret-namespace
----
146 changes: 146 additions & 0 deletions spring-cloud-alibaba-docs/src/main/asciidoc/kubernetes-config.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
== Spring Cloud Alibaba Kubernetes Config

link:kubernetes-config.adoc[English] | link:../asciidoc-zh/kubernetes-config.adoc[中文]

The purpose of this module is to use Kubernetes ConfigMap/Secret as a distributed configuration center to achieve dynamic configuration updates without restarting the application.

=== Quick Start

Go to the link:../../../../spring-cloud-alibaba-examples/kubernetes-config-example/README.md[example] and follow the docs to run the example.
You got this!

=== Main Features

If you have experience with `spring-cloud-starter-alibaba-nacos-config`, you will find out that the usage is very similar. `spring-cloud-starter-alibaba-kubernetes-config` has provided all the core features of `spring-cloud-starter-alibaba-nacos-config`, and provides more easier-to-use configurations, better performance and more in line with cloud-native.

==== Dynamic update configuration(ConfigMap/Secret)

You don't need to restart the application when the configuration is updated, and the application can dynamically update the configurations.

NOTE: Spring Cloud provides the capability of dynamically refreshing the Environment at runtime, which mainly dynamically updates the properties of two types of beans: `@ConfigurationProperties` and `@RefreshScope` beans.

*Best Practices: use `@ConfigurationProperties` to organize your configurations!*

Related configuration:

[source,yaml]
----
spring:
cloud:
k8s:
config:
refreshable: false # global default config, default value is false
config-maps:
- name: my-configmap
refreshable: true # my-configmap will detect config change and refresh
secrets:
- name: my-secret # my-secret will NOT detect config change and refresh
----

==== Configuration priority

If there are same configurations in both local `application.yml` and ConfigMaps/Secret, you can choose which configuration to use first.

Related configuration:

[source,yaml]
----
spring:
cloud:
k8s:
config:
preference: remote # Global default config, default value is remote, means remote config will override local config
config-maps:
- name: my-configmap
preference: local
----

==== Multiple configuration file formats

Supports configuration files in `yaml`, `properties`, `json` and key-value pair.

NOTE: Secret only supports key-value pair!

Example:

ConfigMap:

[source,yaml]
----
apiVersion: v1
kind: ConfigMap
metadata:
name: my-configmap
data:
blacklist.yml: |
blacklist:
user-ids:
- 1
- 2
----

Secret:

[source,yaml]
----
apiVersion: v1
kind: Secret
metadata:
name: my-secret
stringData:
blacklist.user-ids[0]: 1
blacklist.user-ids[1]: 2
----

The two configurations above convey the same meaning.

==== Abnormal operation protection

If config was deleted by mistake, you don't want your application to crash, right? `spring-cloud-starter-alibaba-kubernetes-config` provides a mechanism to protect the application from abnormal operation, such as deleting the configuration by mistake.

Related configuration:

[source,yaml]
----
spring:
cloud:
k8s:
config:
refresh-on-deleted: false # when detect the config was deleted, the application will not trigger a refresh. Default value is false.
----

If your configuration is not synchronized across environments, and you have the `import-config` configuration in the `dev` environment but not in the `prod` environment (it is possible that you forgot to synchronize to `prod`), you may want to have a mechanism to help you find this problem and provide fail-fast ability to prevent the application from starting.

Related configuration:

[source,yaml]
----
spring:
cloud:
k8s:
config:
fail-on-missing-config: true # application will fail to start if the configs not found. Default value is true.
----

=== Core Configurations

[source,yaml]
----
spring:
cloud:
k8s:
config:
enabled: true
namespace: default # The namespace where the configuration is located (global configuration). If inside the Kubernetes cluster, it defaults to the namespace where the current pod is located; if outside the Kubernetes cluster, it defaults to the namespace of the current context.
preference: remote
refreshable: false
refresh-on-delete: false
fail-on-missing-config: true
config-maps:
- name: my-configmap
preference: remote
refreshable: true
secrets:
- name: my-secret
namespace: secret-namespace
----
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
## Spring Cloud Starter Alibaba Kubernetes Config Example

[English](README.md) | [中文](README-zh.md)

这个例子演示了使用 `spring-cloud-starter-alibaba-kubernetes-config` 来实现一个动态黑名单功能。

### 步骤

1. Apply [deployments.yaml](./deployments.yaml) 文件

确保在 `kubernetes-config-example` 目录。

```shell
kubectl apply -f deployments.yaml
```

2. 启动程序

3. 访问应用

```shell
curl localhost:8080/echo -H 'x-user-id:1'
```

可以看到用户 `1` 已经被 block 了,可以查看 [deployments.yaml](./deployments.yaml) 得知 blocked 的用户 id。

4. 修改 [deployments.yaml](./deployments.yaml) 文件中的 `blacklist` 配置。

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: configmap-01
namespace: default
data:
blacklist.yml: |
blacklist:
user-ids:
- 2
```

再次 apply

```shell
kubectl apply -f deployments.yaml
```

5. 再次访问应用

```shell
curl localhost:8080/echo -H 'x-user-id:1'
```

可以看到用户 `1` 不再被 block,现在只有用户 `2` 被 block。

6. 删除资源

确保在 `kubernetes-config-example` 目录。

```shell
kubectl delete -f deployments.yaml
```