From 0ad811837c5a6867fe619d460d47595b287ac99c Mon Sep 17 00:00:00 2001 From: Dan Heath <76443935+Dan-Heath@users.noreply.github.com> Date: Mon, 11 Aug 2025 15:30:30 -0400 Subject: [PATCH 1/6] docs: Clarify use of `public_cluster_addr` for load balancing --- website/content/docs/configuration/controller.mdx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/website/content/docs/configuration/controller.mdx b/website/content/docs/configuration/controller.mdx index f4c4f3cb68..34388809f8 100644 --- a/website/content/docs/configuration/controller.mdx +++ b/website/content/docs/configuration/controller.mdx @@ -74,12 +74,16 @@ description will be read. [ParseDuration()](https://golang.org/pkg/time/#ParseDuration) method. - `public_cluster_addr` - Specifies the public host or IP address (and - optionally port) at which the controller can be reached _by workers_. This will - be used by workers after initial connection to controllers via the worker's - `initial_upstreams` block. This defaults to the address of the listener marked for - `cluster` purpose. It is used if there is a load balancer in front of multiple Boundary controllers. This is also especially useful for cloud environments that do not + optionally port) at which the controller can be reached **by workers**. Workers use this value after making the initial connection to controllers via the worker's + `initial_upstreams` block. The default value is the address of the listener marked for the + `cluster` purpose. + + You can use this attribute if you want to put a load balancer in front of multiple Boundary controllers to ensure that the workers know the addresses of the controllers to perform client-side load balancing. + This setting is also especially useful for cloud environments that do not bind a publicly accessible IP to a NIC on the host directly, such as an Amazon - EIP. This value can be a direct address string, can refer to a file on disk (file://) + EIP. + + This value can be a direct address string, can refer to a file on disk (file://) from which an address will be read; an env var (env://) from which the address will be read; or a [go-sockaddr template](https://godoc.org/github.com/hashicorp/go-sockaddr/template). Note that the address should not include the protocol prefixes like `http://` or `https://`. From 549dd74da7f9dd5dc7163bcaca0d76bf51ffd632 Mon Sep 17 00:00:00 2001 From: Dan Heath <76443935+Dan-Heath@users.noreply.github.com> Date: Mon, 11 Aug 2025 15:49:12 -0400 Subject: [PATCH 2/6] docs: Include example --- website/content/docs/configuration/controller.mdx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website/content/docs/configuration/controller.mdx b/website/content/docs/configuration/controller.mdx index 34388809f8..5750e79dca 100644 --- a/website/content/docs/configuration/controller.mdx +++ b/website/content/docs/configuration/controller.mdx @@ -79,6 +79,9 @@ description will be read. `cluster` purpose. You can use this attribute if you want to put a load balancer in front of multiple Boundary controllers to ensure that the workers know the addresses of the controllers to perform client-side load balancing. + For example, you could have a TCP load balancer that points to any of your controller's `cluster` listener for the worker's initial ingress. + Then the controller gives the worker the `public_cluster_addr` and the worker updates its client-side load balancing configuration to reach out to the set of cluster addresses. + This setting is also especially useful for cloud environments that do not bind a publicly accessible IP to a NIC on the host directly, such as an Amazon EIP. From fd8a0dd8413b19a69dbc82b28cdd0ca4e919408a Mon Sep 17 00:00:00 2001 From: Dan Heath <76443935+Dan-Heath@users.noreply.github.com> Date: Mon, 11 Aug 2025 15:50:21 -0400 Subject: [PATCH 3/6] docs: Word choice --- website/content/docs/configuration/controller.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/content/docs/configuration/controller.mdx b/website/content/docs/configuration/controller.mdx index 5750e79dca..03ede93ba0 100644 --- a/website/content/docs/configuration/controller.mdx +++ b/website/content/docs/configuration/controller.mdx @@ -80,7 +80,7 @@ description will be read. You can use this attribute if you want to put a load balancer in front of multiple Boundary controllers to ensure that the workers know the addresses of the controllers to perform client-side load balancing. For example, you could have a TCP load balancer that points to any of your controller's `cluster` listener for the worker's initial ingress. - Then the controller gives the worker the `public_cluster_addr` and the worker updates its client-side load balancing configuration to reach out to the set of cluster addresses. + Then the controller gives the worker the `public_cluster_addr` and the worker updates its client-side load balancing configuration to connect to the set of cluster addresses. This setting is also especially useful for cloud environments that do not bind a publicly accessible IP to a NIC on the host directly, such as an Amazon From cc86c8061be12caf7b41f0c988dce32490a3b35b Mon Sep 17 00:00:00 2001 From: Dan Heath <76443935+Dan-Heath@users.noreply.github.com> Date: Mon, 11 Aug 2025 15:52:28 -0400 Subject: [PATCH 4/6] docs: Revise example --- website/content/docs/configuration/controller.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/content/docs/configuration/controller.mdx b/website/content/docs/configuration/controller.mdx index 03ede93ba0..d28de38721 100644 --- a/website/content/docs/configuration/controller.mdx +++ b/website/content/docs/configuration/controller.mdx @@ -79,7 +79,7 @@ description will be read. `cluster` purpose. You can use this attribute if you want to put a load balancer in front of multiple Boundary controllers to ensure that the workers know the addresses of the controllers to perform client-side load balancing. - For example, you could have a TCP load balancer that points to any of your controller's `cluster` listener for the worker's initial ingress. + For example, you could have a TCP load balancer that points to a controller's `cluster` listener for the worker's initial ingress. Then the controller gives the worker the `public_cluster_addr` and the worker updates its client-side load balancing configuration to connect to the set of cluster addresses. This setting is also especially useful for cloud environments that do not From f3d8ef2d69d408764146331f7ca8504a5270ea3d Mon Sep 17 00:00:00 2001 From: Dan Heath <76443935+Dan-Heath@users.noreply.github.com> Date: Tue, 26 Aug 2025 10:50:51 -0400 Subject: [PATCH 5/6] docs: Adding new section for load balancing --- .../content/docs/configuration/controller.mdx | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/website/content/docs/configuration/controller.mdx b/website/content/docs/configuration/controller.mdx index d28de38721..ceaaf6199e 100644 --- a/website/content/docs/configuration/controller.mdx +++ b/website/content/docs/configuration/controller.mdx @@ -224,6 +224,26 @@ kms "aead" { Boundary supports many kinds of KMS integrations. For a complete guide to all available KMS types, see our [KMS documentation](/boundary/docs/configuration/kms). +## Load balancing + +You can configure controllers to work with a load balancer. + +1. Configure a load balancer or reverse proxy in TCP mode to point directly to each controller's `cluster` address or use a round robin configuration. +1. Configure each controller's `initial_upstreams` attribute with the address of the load balancer. +The load balancer's address should not be any of the `public_cluster_addr` or `cluster` listener addresses. +1. Configure the `public_cluster_addr` attribute for each controller to be an address that the worker can use to directly connect to the controller after the initial connection through the load balancer. + + In that initial connection, the worker is given the current set of controller addresses, sourced from each controller's `public_cluster_addr` if available, or that controller's `cluster` listener address, if it is not. + +Alternatively, if you want to use a load balancer or reverse proxy for the `public_cluster_addr` addresses, it must be in TCP mode, and it it must only proxy from each controller's `public_cluster_addr` to that controller's `cluster` lisetner. +If you attemmpt to load balance across these addresses, it will result in connectivity issues and a failure of the built=in client-side load balancing. + +You can use direct connections to `cluster` listener addresses and can make use of `public_cluster_addr` along with the workers' `initial_upstreams` attribute without any load balancer/proxy at all, as long as the workers can connect directly. +The load balancer/proxy is only useful if you: + +- Want to have a more dynamic set of controller addresses so that you can add or remove controllers without having to update each worker's `initial_upstreams` attribute as they change. +- Want to have a TCP proxy in front of each `public_cluster_addr` or `cluster` listener address for other reasons, which is supported as long as you do not round robin or load balance and are willing to keep the `initial_upstreams` values in sync. + ## Complete configuration example ```hcl From a4380c53cc3b5a7a0aec224884a9a5579711016e Mon Sep 17 00:00:00 2001 From: Dan Heath <76443935+Dan-Heath@users.noreply.github.com> Date: Wed, 27 Aug 2025 14:52:38 -0400 Subject: [PATCH 6/6] docs: Revise procedure --- .../content/docs/configuration/controller.mdx | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/website/content/docs/configuration/controller.mdx b/website/content/docs/configuration/controller.mdx index ceaaf6199e..a5e69f675f 100644 --- a/website/content/docs/configuration/controller.mdx +++ b/website/content/docs/configuration/controller.mdx @@ -226,23 +226,28 @@ KMS types, see our [KMS documentation](/boundary/docs/configuration/kms). ## Load balancing -You can configure controllers to work with a load balancer. +Boundary does not require a load balancer or reverse proxy, as long as workers can directly connect to the controller. +You can connect controllers directly to `cluster` listener addresses using the `public_cluster_addr` along with the workers' `initial_upstreams` attribute. -1. Configure a load balancer or reverse proxy in TCP mode to point directly to each controller's `cluster` address or use a round robin configuration. -1. Configure each controller's `initial_upstreams` attribute with the address of the load balancer. -The load balancer's address should not be any of the `public_cluster_addr` or `cluster` listener addresses. -1. Configure the `public_cluster_addr` attribute for each controller to be an address that the worker can use to directly connect to the controller after the initial connection through the load balancer. +However, a load balancer or reverse proxy may be useful if you want to have a: + +- Dynamic set of controller addresses so that you can add or remove controllers without having to update each worker's `initial_upstreams` attribute as they change. +- TCP proxy in front of each `public_cluster_addr` or `cluster` listener address for other reasons. +The TCP proxy is supported as long as you do not round robin or load balance and you keep the `initial_upstreams` values in sync. - In that initial connection, the worker is given the current set of controller addresses, sourced from each controller's `public_cluster_addr` if available, or that controller's `cluster` listener address, if it is not. +Refer to the following steps for the recommended method for configuring a load balancer to work with Boundary. -Alternatively, if you want to use a load balancer or reverse proxy for the `public_cluster_addr` addresses, it must be in TCP mode, and it it must only proxy from each controller's `public_cluster_addr` to that controller's `cluster` lisetner. -If you attemmpt to load balance across these addresses, it will result in connectivity issues and a failure of the built=in client-side load balancing. +1. Configure a load balancer or reverse proxy in TCP mode to point directly to each controller's `cluster` address or configure a round robin configuration in which the controllers point to each other. +1. Configure each controller's `initial_upstreams` attribute with the address of the load balancer. +The load balancer's address should not be the same as any of the `public_cluster_addr` or `cluster` listener addresses. +1. Configure each controller's `public_cluster_addr` attribute to be an address that the worker can use to directly connect to the controller after the worker makes the initial connection through the load balancer. -You can use direct connections to `cluster` listener addresses and can make use of `public_cluster_addr` along with the workers' `initial_upstreams` attribute without any load balancer/proxy at all, as long as the workers can connect directly. -The load balancer/proxy is only useful if you: + In that initial connection, the worker obtains the current set of controller addresses from each controller's `public_cluster_addr`, if it is available. + If you did not configure a `public_cluster_addr`, the worker user the controller's `cluster` listener address. -- Want to have a more dynamic set of controller addresses so that you can add or remove controllers without having to update each worker's `initial_upstreams` attribute as they change. -- Want to have a TCP proxy in front of each `public_cluster_addr` or `cluster` listener address for other reasons, which is supported as long as you do not round robin or load balance and are willing to keep the `initial_upstreams` values in sync. +Alternatively, you can use a load balancer or reverse proxy for the `public_cluster_addr` addresses. +The load balancer or reverse proxy must be in TCP mode, and it it must only proxy from each controller's `public_cluster_addr` to that controller's `cluster` lisetner. +If you attemmpt to load balance across these addresses, it will result in connectivity issues and a failure of the built-in client-side load balancing. ## Complete configuration example