[id='con-configuring-vc-gateways-{context}']
= Configuring virtual cluster gateways

[role="_abstract"]

Clients connect to a virtual cluster gateway.
Each gateway provides a bootstrap address for the initial connection.
The gateway also facilitates communication between clients and proxied brokers.
This can be implemented in two ways:

Port Identifies Node:: The gateway binds separate ports—one for each broker as well as an additional one for the bootstrap address.
Clients make connections to the different port numbers to interact with each broker.
SNI Host Identifies Node:: The gateway assigns a unique hostname to each broker.
Clients make connections to these distinct hostnames to interact with the respective brokers.
The gateway uses SNI (Server Name Indication) to identify the target broker for the client's connection.

IMPORTANT: You must make sure that the gateway's bootstrap address and generated broker addresses are resolvable and routable by the Kafka Client. You must also make sure firewall rules permit traffic to required port numbers.

== Port Identifies Node

In the Port Identifies Node scheme, the virtual cluster opens a separate port for each proxied broker in addition to
a separate port for the bootstrap.

By default, this scheme assumes that the target cluster comprises three nodes with broker ids 0..2. 
If this is inadequate, additional configuration can be provided describing the broker topology of the target broker.

This scheme can be used with both plain and TLS downstream connections.

This scheme works best with straightforward configurations where the target cluster uses a known minimum broker ID and uses stable sets of broker IDs. 
For more complex cases, it is recommended to use the SNI Host Identifies Node scheme.

IMPORTANT: When using this scheme, you have the responsibility to avoid port number collision. Ensure that each gateway has its own range of port numbers and these do not overlap with the range used by another gateway, or the gateway of another virtual cluster.

[id='con-configuring-vc-gateways-port-identifies-node-{context}']
.Example Port Identifies Node configuration

[source,yaml]
----
# ...
virtualClusters:
  - name: my-cluster-proxy
    # ...
    gateways:
    - name: mygateway
      portIdentifiesNode:
        bootstrapAddress: localhost:9192 # <1>
    # ...
# ...
----
<1> The bootstrap address used by Kafka clients.

With the example configuration above, the gateway exposes a target cluster of up to three brokers with node ids `0`, `1`, `2`.
The advertised address is defaulted to that of the bootstrap host name. 
Port numbers are assigned sequentially beginning at bootstrap port number + 1.

The gateway exposes the following three broker addresses:

|===
|Node Id|Broker Address

|0
|localhost:9193

|1
|localhost:9194

|2
|localhost:9195
|===

.Example Port Identifies Node configuration with customized broker address

[source,yaml]
----
# ...
virtualClusters:
  - name: my-cluster-proxy
    # ...
    gateways:
    - name: mygateway
      portIdentifiesNode:
        bootstrapAddress: localhost:9192 # <1>
        advertisedBrokerAddressPattern: mycluster.example.com # <2>
        brokerStartPort: 9200 # <3>
    # ...
# ...
----
<1> The bootstrap address used by Kafka clients.
<2> (Optional) The advertised broker address pattern used to form broker addresses. If not defined, it defaults to the hostname part of the bootstrap address.
<3> (Optional) The starting number for the broker port range. Defaults to the port of the bootstrap address plus 1.

With the example configuration above, the gateway exposes a target cluster of up to three brokers with node ids `0`, `1`, `2`.
The advertised broker address is defined as `mycluster.example.com`.  
Port numbers are assigned sequentially beginning at `9200`.

The gateway exposes the following three broker addresses:

|===
|Node Id|Broker Address

|0
|mycluster.example.com:9200

|1
|mycluster.example.com:9201

|2
|mycluster.example.com:9203
|===

.Example Port Identifies Node configuration with customized node ranges

[source,yaml]
----
# ...
virtualClusters:
  - name: my-cluster-proxy
    # ...
    gateways:
    - name: mygateway
      portIdentifiesNode:
        bootstrapAddress: localhost:9192 # <1>
        advertisedBrokerAddressPattern: mycluster.example.com # <2>
        nodeIdRanges: # <3>
        - name: mixed
          start: 1
          end: 3
        - name: brokers
          start: 100
          end: 103

    # ...
# ...
----
<1> The bootstrap address used by Kafka clients.
<2> (Optional) The advertised broker address pattern used to form broker addresses. If not defined, it defaults to the hostname part of the bootstrap address.
<3> (Optional) One or more node id ranges.  If omitted, it defaults to a single range of node IDs 0..2 (inclusive).

With the example configuration above, the gateway exposes a target cluster of up to six nodes with node ids `1..3` and `101..103`.
The advertised broker address is defined as `mycluster.example.com`. 
Port numbers are assigned sequentially beginning at `9193` (bootstrap port number + 1).

The gateway exposes the following six broker addresses:

|===
|Node Id|Broker Address

|1
|mycluster.example.com:9193

|2
|mycluster.example.com:9194

|3
|mycluster.example.com:9195

|101
|mycluster.example.com:9196

|102
|mycluster.example.com:9197

|103
|mycluster.example.com:9198

|===

The `advertisedBrokerAddressPattern` configuration parameter accepts the `$(nodeId)` replacement token, which is optional.
If included, `$(nodeId)` is replaced by the broker's https://kafka.apache.org/documentation/#brokerconfigs_node.id[`node.id`] (or https://kafka.apache.org/documentation/#brokerconfigs_broker.id[`broker.id`]) in the target cluster.

[id='con-configuring-vc-gateways-snihost-identifies-node-{context}']

== SNI Host Identifies Node

In the SNI Host Identifies Node scheme, unique broker hostnames are used to know where to route the traffic.
As this scheme relies on SNI (Server Name Indication), which is a TLS extension, TLS connections are required. It cannot be used with plain text connections.

In this scheme, you can either share the port across multiple virtual cluster gateways or assign a separate port
for each virtual cluster gateway.
However, you cannot use a port that is already assigned to a virtual cluster gateway using the Port Identifies Node scheme.

IMPORTANT: When using this scheme, you have the responsibility to make sure that DNS for bootstrap and brokers resolve
to an IP address that is routed to the proxy. Wildcard DNS is one way to achieve this.

.Example SNI Host Identifies Node configuration
[source,yaml]
----
# ...
virtualClusters:
  - name: my-cluster-proxy
    # ...
    gateways:
    - name: mygateway
      sniHostIdentifiesNode:
        bootstrapAddress: mycluster.example.com:9192 # <1>
        advertisedBrokerAddressPattern: mybroker-$(nodeId).mycluster.example.com <2>
      tls:
         key: ... <3>
    # ...
# ...
----
<1> The bootstrap address used by Kafka clients.
<2> The advertised broker address pattern used to form broker addresses. It must include the placeholder $(nodeId) which
    is substituted for the node ID.
<3> TLS configuration.

With the example configuration above, the gateway accepts all traffic on port 9192.
Any TLS connections received with the SNI of `mycluster.example.com` are routed as bootstrap. 
Any connections received with SNI matching `mybroker-$(nodeId).mycluster.example.com` are routed to the upstream broker with the same node ID.
The configuration exposes a target cluster with any number of brokers. It does not need prior knowledge of the node IDs used by the brokers.

The gateway exposes the following broker addresses:

|===
|Node Id|Broker Address

|0
|mybroker-0.mycluster.example.com:9192

|...
|...

|_n_
|mybroker-_n_.mycluster.example.com:9192

|===

Both the `advertisedBrokerAddressPattern` and `bootstrapAddress` configuration parameters accept the `$(virtualClusterName)` replacement token, 
which is optional. If included, `$(virtualClusterName)` is replaced with the name of the gateway's virtual cluster.

.Example SNI Host Identifies Node configuration with customized advertised port
[source,yaml]
----
# ...
virtualClusters:
  - name: my-cluster-proxy
    # ...
    gateways:
    - name: mygateway
      sniHostIdentifiesNode:
        bootstrapAddress: mycluster.example.com:9192 # <1>
        advertisedBrokerAddressPattern: mybroker-$(nodeId).mycluster.example.com:443 <2>
      tls:
         key: ... <3>
    # ...
# ...
----
<1> The bootstrap address used by Kafka clients.
<2> The advertised broker address pattern and port number used to form broker addresses. It must include the placeholder $(node)
    which will be substituted for the node id.
<3> TLS configuration.

With the example configuration above, Kroxylicious is instructed to listen on port 9192, but advertise brokers of this virtual cluster as
being available on port 443. This feature is useful where a network intermediary (such as another proxy or
load balancer) is port forwarding.

The gateway exposes the following broker addresses:

|===
|Node Id|Broker Address

|0
|mybroker-0.mycluster.example.com:443

|...
|...

|_n_
|mybroker-_n_.mycluster.example.com:443

|===

NOTE: Single port operation may have cost advantages when using load balancers of public clouds, as it allows
a single cloud provider load balancer to be shared across all virtual clusters.
