From e1a5c753ca8983bfbecae474837d864767002c02 Mon Sep 17 00:00:00 2001 From: Levi Ramsey Date: Fri, 7 Feb 2025 12:53:07 -0500 Subject: [PATCH] paradox --- .../docs/KubernetesApiDiscoveryDocsTest.java | 7 +++++ .../KubernetesApiServiceDiscoverySpec.scala | 9 ++++++ .../main/paradox/bootstrap/kubernetes-api.md | 10 ++++++ docs/src/main/paradox/discovery/kubernetes.md | 31 ++++++++++++++++++- 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/discovery-kubernetes-api/src/test/java/docs/KubernetesApiDiscoveryDocsTest.java b/discovery-kubernetes-api/src/test/java/docs/KubernetesApiDiscoveryDocsTest.java index eca563111..3f4739bb4 100644 --- a/discovery-kubernetes-api/src/test/java/docs/KubernetesApiDiscoveryDocsTest.java +++ b/discovery-kubernetes-api/src/test/java/docs/KubernetesApiDiscoveryDocsTest.java @@ -15,4 +15,11 @@ public void loadKubernetesApiDiscovery() { ServiceDiscovery discovery = Discovery.get(system).loadServiceDiscovery("kubernetes-api"); //#kubernetes-api-discovery } + + public void loadExternalKubernetesApiDiscovery() { + ActorSystem system = ActorSystem.create(); + //#kubernetes-api-for-client-discovery + ServiceDiscovery discovery = Discovery.get(system).loadServiceDiscovery("kubernetes-api-for-client"); + //#kubernetes-api-for-client-discovery + } } diff --git a/discovery-kubernetes-api/src/test/scala/akka/discovery/kubernetes/KubernetesApiServiceDiscoverySpec.scala b/discovery-kubernetes-api/src/test/scala/akka/discovery/kubernetes/KubernetesApiServiceDiscoverySpec.scala index 990a3c638..630f8cae6 100644 --- a/discovery-kubernetes-api/src/test/scala/akka/discovery/kubernetes/KubernetesApiServiceDiscoverySpec.scala +++ b/discovery-kubernetes-api/src/test/scala/akka/discovery/kubernetes/KubernetesApiServiceDiscoverySpec.scala @@ -388,6 +388,15 @@ class KubernetesApiServiceDiscoverySpec extends AnyWordSpec with Matchers { discovery shouldBe a[KubernetesApiServiceDiscovery] system.terminate() } + + "allow loading kubernetes-api-for-client discovery even if it is not the default" in { + val system = ActorSystem() + //#kubernetes-api-for-client-discovery + val discovery = Discovery(system).loadServiceDiscovery("kubernetes-api-for-client") + //#kubernetes-api-for-client-discovery + discovery shouldBe a[ExternalKubernetesApiServiceDiscovery] + system.terminate() + } } private def resourceAsString(name: String): String = diff --git a/docs/src/main/paradox/bootstrap/kubernetes-api.md b/docs/src/main/paradox/bootstrap/kubernetes-api.md index 96baed866..c7bd61757 100644 --- a/docs/src/main/paradox/bootstrap/kubernetes-api.md +++ b/docs/src/main/paradox/bootstrap/kubernetes-api.md @@ -26,6 +26,16 @@ The following configuration is required: @@snip [akka-cluster.yml](/integration-test/kubernetes-api/src/main/resources/application.conf) { #discovery-config } +Note that `kubernetes-api` is unsuitable as the default `akka.discovery.method`. For most cases, the most reasonable +(and most idiomatic in Kubernetes) choice for discovering other services to consume is to use DNS: + +``` +akka.discovery.method = akka-dns +``` + +In some cases, @ref:[`kubernetes-api-for-client`](../discovery/kubernetes.md#using-the-kubernetes-api-to-support-client-side-load-balancing) +may be a more suitable default `akka.discovery.method`. + The lookup needs to know which namespace to look in. By default, this will be detected by reading the namespace from the service account secret, in `/var/run/secrets/kubernetes.io/serviceaccount/namespace`, but can be overridden by setting `akka.discovery.kubernetes-api.pod-namespace` or by providing `KUBERNETES_NAMESPACE` environment variable. diff --git a/docs/src/main/paradox/discovery/kubernetes.md b/docs/src/main/paradox/discovery/kubernetes.md index 38d79b29e..926b14b29 100644 --- a/docs/src/main/paradox/discovery/kubernetes.md +++ b/docs/src/main/paradox/discovery/kubernetes.md @@ -2,7 +2,12 @@ If you want to use Kubernetes for @ref[Cluster Bootstrap](../bootstrap/index.md), please follow the @ref[Cluster Bootstrap Kubernetes API](../bootstrap/kubernetes-api.md) documentation that is tailored for that use case. -The typical way to consume a service in Kubernetes is to discover it through DNS: this will take into account liveness/readiness checks, and depending on the configuration take care of load balancing (removing the need for client-side load balancing). For this reason, for general usage the @extref:[`akka-dns`](akka:discovery/index.html#discovery-method-dns) implementation is usually a better fit for discovering services in Kubernetes. However, in some cases, such as for @ref[Cluster Bootstrap](../bootstrap/index.md), it is desirable to connect to the pods directly, bypassing any liveness/readiness checks or load balancing. For such situations we provide a discovery implementation that uses the Kubernetes API. +The typical way to consume a service in Kubernetes is to discover it through DNS: this will take into account liveness/readiness checks, and depending on the configuration take care of load balancing (removing the need for client-side load balancing). For this reason, for general usage the @extref:[`akka-dns`](akka:discovery/index.html#discovery-method-dns) implementation is usually a better fit for discovering services in Kubernetes. + +However, in some cases, such as for @ref[Cluster Bootstrap](../bootstrap/index.md), it is desirable to connect to the pods directly, bypassing any liveness/readiness checks or load balancing. For such situations we provide a discovery implementation that uses the Kubernetes API. + +In even fewer cases, it may be desirable to use the the Kubernetes API to discover other services to consume and +perform client-side load balancing. For such situations, we also provide a @ref[variant implementation, which is not suitable for use with cluster bootstrap](#using-the-kubernetes-api-to-support-client-side-load-balancing). ## Project Info @@ -127,3 +132,27 @@ Adjust as necessary. > Using Google Kubernetes Engine? Your user will need permission to grant roles. See [Google's Documentation](https://cloud.google.com/kubernetes-engine/docs/how-to/role-based-access-control#prerequisites_for_using_role-based_access_control) for more information. @@snip [akka-cluster.yml](/integration-test/kubernetes-api/kubernetes/akka-cluster.yml) { #rbac } + +### Using the Kubernetes API to support client-side load balancing + +The primary (`kubernetes-api`) discovery mechanism is intended to support use-cases like Cluster Bootstrap +(especially when, as is typical, a service is not able to serve traffic until the cluster has bootstrapped). +This intent implies that the `kubernetes-api` discovery mechanism is unsuitable for client-side load balancing. For +situations where the Kubernetes API would be preferable to DNS-based discovery (e.g. if it's impractical to +configure DNS for the Kubernetes cluster to support client-side load balancing), the `kubernetes-api-for-client` +discovery mechanism is available. Unlike `kubernetes-api`, this mechanism is suitable for use as the default discovery +mechanism (though unsuitable for use with Cluster Bootstrap): + +``` +# in application.conf, for example +akka.management.cluster.bootstrap.contact-point-discovery.discovery-method = kubernetes-api +akka.discovery.method = kubernetes-api-for-client +``` + +Or to programmatically load: + +Scala +: @@snip [KubernetesApiServiceDiscoverySpec.scala](/discovery-kubernetes-api/src/test/scala/akka/discovery/kubernetes/KubernetesApiServiceDiscoverySpec.scala) { #kubernetes-api-for-client-discovery } + +Java +: @@snip [KubernetesApiDiscoveryDocTest.java](/discovery-kubernetes-api/src/test/java/docs/KubernetesApiDiscoveryDocsTest.java) { #kubernetes-api-for-client-discovery }