From 655651e326f66affa4cdaef589e6175d8a3de148 Mon Sep 17 00:00:00 2001 From: buildmaster Date: Sat, 23 Dec 2023 21:33:48 +0000 Subject: [PATCH 1/2] Bumping versions --- README.adoc | 63 ++++++++++++++----- .../client/KubernetesClientUtils.java | 6 +- 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/README.adoc b/README.adoc index 776b7118..05d8ab0b 100644 --- a/README.adoc +++ b/README.adoc @@ -335,32 +335,65 @@ NOTE: `spring.application.name` has no effect as far as the name registered for ''' -Spring Cloud Kubernetes can also watch the Kubernetes service catalog for changes and update the -`DiscoveryClient` implementation accordingly. By "watch" we mean that we will publish a heartbeat event every `spring.cloud.kubernetes.discovery.catalog-services-watch-delay` -milliseconds (by default it is `30000`). The heartbeat event will contain the target references (and their namespaces of the addresses of all endpoints +Spring Cloud Kubernetes can also watch the Kubernetes service catalog for changes and update the `DiscoveryClient` implementation accordingly. In order to enable this functionality you need to add +`@EnableScheduling` on a configuration class in your application. By "watch", we mean that we will publish a heartbeat event every `spring.cloud.kubernetes.discovery.catalog-services-watch-delay` +milliseconds (by default it is `30000`). For the http discovery server this must be an environment variable set in deployment yaml: + +---- + containers: + - name: discovery-server + image: springcloud/spring-cloud-kubernetes-discoveryserver:3.0.5-SNAPSHOT + env: + - name: SPRING_CLOUD_KUBERNETES_DISCOVERY_CATALOGSERVICESWATCHDELAY + value: 3000 +---- + +The heartbeat event will contain the target references (and their namespaces of the addresses of all endpoints (for the exact details of what will get returned you can take a look inside `KubernetesCatalogWatch`). This is an implementation detail, and listeners of the heartbeat event should not rely on the details. Instead, they should see if there are differences between two subsequent heartbeats via `equals` method. We will take care to return a correct implementation that adheres to the equals contract. The endpoints will be queried in either : - - all namespaces (enabled via `spring.cloud.kubernetes.discovery.all-namespaces=true`) + - `all-namespaces` (enabled via `spring.cloud.kubernetes.discovery.all-namespaces=true`) - - specific namespaces (enabled via `spring.cloud.kubernetes.discovery.namespaces`), for example: + - `selective namespaces` (enabled via `spring.cloud.kubernetes.discovery.namespaces`), for example: + + - `one namespace` via xref:property-source-config.adoc#namespace-resolution[Namespace Resolution] if the above two paths are not taken. + +NOTE: If, for any reasons, you want to disable catalog watcher, you need to set `spring.cloud.kubernetes.discovery.catalog-services-watch.enabled=false`. For the http discovery server, this needs to be an environment variable set in deployment for example: [source] ---- -spring: - cloud: - kubernetes: - discovery: - namespaces: - - namespace-a - - namespace-b +SPRING_CLOUD_KUBERNETES_DISCOVERY_CATALOGSERVICESWATCH_ENABLED=FALSE ---- -- we will use: xref:property-source-config.adoc#namespace-resolution[Namespace Resolution] if the above two paths are not taken. +The functionality of catalog watch works for all 3 discovery clients that we support, with some caveats that you need to be aware of in case of the http client. + +- The first is that this functionality is disabled by default, and it needs to be enabled in two places: + + * in discovery server via an environment variable in the deployment manifest, for example: ++ +---- +containers: + - name: discovery-server + image: springcloud/spring-cloud-kubernetes-discoveryserver:3.0.5-SNAPSHOT + env: + - name: SPRING_CLOUD_KUBERNETES_HTTP_DISCOVERY_CATALOG_WATCHER_ENABLED + value: "TRUE" +---- ++ + +* in discovery client, via a property in your `application.properties` for example: ++ +---- +spring.cloud.kubernetes.http.discovery.catalog.watcher.enabled=true +---- ++ + +- The second point is that this is only supported since version `3.0.6` and upwards. +- Since http discovery has _two_ components : server and client, we strongly recommend to align versions between them, otherwise things might not work. +- If you decide to disable catalog watcher, you need to disable it in both server and client. + -In order to enable this functionality you need to add -`@EnableScheduling` on a configuration class in your application. By default, we use the `Endpoints`(see https://kubernetes.io/docs/concepts/services-networking/service/#endpoints) API to find out the current state of services. There is another way though, via `EndpointSlices` (https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/). Such support can be enabled via a property: `spring.cloud.kubernetes.discovery.use-endpoint-slices=true` (by default it is `false`). Of course, your cluster has to support it also. As a matter of fact, if you enable this property, but your cluster does not support it, we will fail starting the application. If you decide to enable such support, you also need proper Role/ClusterRole set-up. For example: diff --git a/spring-cloud-kubernetes-client-autoconfig/src/main/java/org/springframework/cloud/kubernetes/client/KubernetesClientUtils.java b/spring-cloud-kubernetes-client-autoconfig/src/main/java/org/springframework/cloud/kubernetes/client/KubernetesClientUtils.java index d1ecdeb8..35dff0f1 100644 --- a/spring-cloud-kubernetes-client-autoconfig/src/main/java/org/springframework/cloud/kubernetes/client/KubernetesClientUtils.java +++ b/spring-cloud-kubernetes-client-autoconfig/src/main/java/org/springframework/cloud/kubernetes/client/KubernetesClientUtils.java @@ -51,14 +51,14 @@ public final class KubernetesClientUtils { catch (Exception e) { if (e instanceof IllegalStateException illegalStateException && illegalStateException.getCause() instanceof NumberFormatException) { - LOG.info("Could not create the Kubernetes ApiClient in a cluster environment, because connection port " + - "was not provided."); + LOG.info("Could not create the Kubernetes ApiClient in a cluster environment, because connection port " + + "was not provided."); } else { LOG.info("Could not create the Kubernetes ApiClient in a cluster environment, because : ", e); } LOG.info(""" - Trying to use a "standard" configuration to create the Kubernetes ApiClient"""); + Trying to use a "standard" configuration to create the Kubernetes ApiClient"""); try { ApiClient apiClient = ClientBuilder.defaultClient(); LOG.info("Created standard API client. Unless $KUBECONFIG or $HOME/.kube/config is defined, " From e82272b165d20327eada52c235a245eb071a1e8e Mon Sep 17 00:00:00 2001 From: Chris Bono Date: Tue, 26 Dec 2023 09:29:40 -0600 Subject: [PATCH 2/2] Clarify k8s ConfigMap property source instructions (#1549) This commit updates the property-source-config.adoc to clarify the need to escape the "kubernetes:" value for the 'spring.config.import' property. Co-authored-by: Ryan Baxter --- docs/src/main/asciidoc/property-source-config.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/main/asciidoc/property-source-config.adoc b/docs/src/main/asciidoc/property-source-config.adoc index fe7e513f..c10d2942 100644 --- a/docs/src/main/asciidoc/property-source-config.adoc +++ b/docs/src/main/asciidoc/property-source-config.adoc @@ -5,7 +5,7 @@ an `application-profile.properties` or `application-profile.yaml` file that cont application or Spring Boot starters. You can override these properties by specifying system properties or environment variables. -To enable this functionality you need to set `spring.config.import=kubernetes:` in your application's configuration properties. +To enable this functionality you need to set the `spring.config.import` application configuration property to `kubernetes:` (escape with quotes when using yaml eg. `"kubernetes:"`). Currently you can not specify a ConfigMap or Secret to load using `spring.config.import`, by default Spring Cloud Kubernetes will load a ConfigMap and/or Secret based on the `spring.application.name` property. If `spring.application.name` is not set it will load a ConfigMap and/or Secret with the name `application`.