Chapter 4. Deploying a proxy
Deploy a basic proxy instance with a single virtual cluster exposed to Kafka clients on the same OpenShift cluster.
4.1. Prerequisites Copy linkLink copied to clipboard!
- The Streams for Apache Kafka Proxy Operator is installed in the OpenShift cluster.
- A Kafka cluster is available to be proxied.
- TLS certificate generation capability is available for ingress configurations that require TLS.
- DNS management access is available for ingress configurations that require off-cluster access.
4.2. The required resources Copy linkLink copied to clipboard!
4.2.1. Proxy configuration to host virtual clusters Copy linkLink copied to clipboard!
A KafkaProxy resource represents an instance of the Streams for Apache Kafka Proxy. Conceptually, it is the top-level resource that links together KafkaProxyIngress, VirtualKafkaCluster, KafkaService, and KafkaProtocolFilter resources to form a complete working proxy.
KafkaProxy resources are referenced by KafkaProxyIngress and VirtualKafkaCluster resources to define how the proxy is exposed and what it proxies.
Example KafkaProxy configuration
kind: KafkaProxy
apiVersion: kroxylicious.io/v1alpha1
metadata:
namespace: my-proxy
name: simple
spec: {}
- 1
- An empty
speccreates a proxy with default configuration.
4.2.2. Networking configuration Copy linkLink copied to clipboard!
A KafkaProxyIngress resource defines the networking configuration that allows Kafka clients to connect to a VirtualKafkaCluster.
It is uniquely associated with a single KafkaProxy instance, but it is not uniquely associated with a VirtualKafkaCluster and can be used by multiple VirtualKafkaCluster instances.
The KafkaProxyIngress resource supports the following ingress types to configure networking access to the virtual cluster:
-
clusterIPexposes the virtual cluster to applications running inside the same OpenShift cluster as the proxy. -
loadBalancerexposes the virtual cluster to applications running outside the OpenShift cluster.
The clusterIP ingress types support both TCP (plain) and TLS connections. The loadBalancer type exclusively supports TLS.
When using TLS, you specify a TLS server certificate in the ingress configuration of the VirtualKafkaCluster resource.
When using loadBalancer, changes to your DNS may be required.
The following table summarizes the supported ingress types.
| Ingress Type | Use case | Supported Transport | Requires DNS changes? |
|---|---|---|---|
|
| On-cluster applications | TCP/TLS | No |
|
| Off-cluster applications | TLS only | Yes |
TLS is recommended when connecting applications in a production environment.
4.2.2.1. clusterIP ingress type Copy linkLink copied to clipboard!
The clusterIP ingress type exposes virtual clusters to Kafka clients running in the same OpenShift cluster as the proxy. It supports both TCP (plain) and TLS connections.
The clusterIP ingress type uses OpenShift Service resources of type ClusterIP to enable on-cluster access.
Example KafkaProxyIngress configuration for clusterIP with TCP
kind: KafkaProxyIngress
apiVersion: kroxylicious.io/v1alpha1
metadata:
namespace: my-proxy
name: cluster-ip
spec:
proxyRef:
name: simple
clusterIP:
protocol: TCP
Example KafkaProxyIngress configuration for clusterIP with TLS
kind: KafkaProxyIngress
apiVersion: kroxylicious.io/v1alpha1
metadata:
namespace: my-proxy
name: cluster-ip
spec:
proxyRef:
name: simple
clusterIP:
protocol: TLS
- 1
- Defines the connection protocol as
TLSto enable encrypted communication between clients and the proxy.
When using TLS, specify a TLS server certificate in the ingress configuration of the VirtualKafkaCluster resource using a certificateRef.
4.2.2.2. loadBalancer ingress type Copy linkLink copied to clipboard!
The loadBalancer ingress type allows applications running off-cluster to connect to the virtual cluster. TLS must be used with this ingress type.
The loadBalancer ingress type uses OpenShift Service resources of type LoadBalancer to enable off-cluster access.
When using a loadBalancer ingress, the proxy uses SNI (Server Name Indication) to match the client’s requested host name to the correct virtual cluster and broker within the proxy. This means that every virtual cluster and every broker within the virtual cluster must be uniquely identifiable within DNS. To accomplish this, the following configuration must be provided:
-
A unique
bootstrapAddress. This is the address that the clients initially use to connect to the virtual cluster. -
An
advertisedBrokerAddressPatternthat generates unique broker addresses which clients use to connect to individual brokers.
You decide how to formulate the bootstrapAddress and the advertisedBrokerAddressPattern to best fit the networking conventions of your organization.
The advertisedBrokerAddressPattern must contain the token $(nodeId). The proxy replaces this token with the broker’s node ID. This ensures that client connections are correctly routed to the intended broker.
Both bootstrapAddress and advertisedBrokerAddressPattern may contain the token $(virtualClusterName). If this is present, it is replaced by the virtual cluster’s name. This token is necessary when the KafkaProxyIngress is being shared by many virtual clusters.
One possible scheme is to use the virtual cluster’s name as a subdomain within your organisation’s domain name:
$(virtualClusterName).kafkaproxy.example.com
You can then use a further subdomain for each broker:
broker-$(nodeId).$(virtualClusterName).kafkaproxy.example.com
You can use other naming schemes, as long as each address remains unique.
Example KafkaProxyIngress configuration for loadBalancer
kind: KafkaProxyIngress
apiVersion: kroxylicious.io/v1alpha1
metadata:
namespace: my-proxy
name: load-balancer
spec:
proxyRef:
name: simple
loadBalancer:
bootstrapAddress: "$(virtualClusterName).kafkaproxy.example.com"
advertisedBrokerAddressPattern: "broker-$(nodeId).$(virtualClusterName).kafkaproxy.example.com"
When using TLS, specify a TLS server certificate in the ingress configuration of the VirtualKafkaCluster resource using a certificateRef.
You must also configure DNS so that the bootstrap and broker address resolve from the network used by the applications.
4.2.3. Configuration for proxied Kafka clusters Copy linkLink copied to clipboard!
A proxied Kafka cluster is configured in a KafkaService resource, which specifies how the proxy connects to the cluster. The Kafka cluster may or may not be running in the same OpenShift cluster as the proxy: Network connectivity is all that’s required.
This example shows a KafkaService defining how to connect to a Kafka cluster at kafka.example.com.
Example KafkaService configuration
kind: KafkaService
metadata:
# ...
spec:
bootstrapServers: kafka.example.com:9092
nodeIdRanges:
- name: brokers
start: 0
end: 5
# ...
- 1
- The
bootstrapServersproperty is a comma-separated list of addresses in<host>:<port>format. Including multiple broker addresses helps clients connect when one is unavailable. - 2
nodeIdRangesdeclares the IDs of all the broker nodes in the Kafka cluster- 3
nameis optional, but specifying it can make errors easier to diagnose.- 4
- The start of the ID range, inclusive.
- 5
- The end of the ID range, inclusive.
4.2.4. Virtual cluster configuration Copy linkLink copied to clipboard!
A VirtualKafkaCluster resource defines a logical Kafka cluster that is accessible to clients over the network.
The virtual cluster references the following resources, which must be in the same namespace:
-
A
KafkaProxyresource that the proxy is part of. -
One or more
KafkaProxyIngressresources that expose the virtual cluster to Kafka clients and provide virtual-cluster-specific configuration to the ingress (such as TLS certificates and other parameters). -
A
KafkaServiceresource that defines the backend Kafka cluster. -
Zero or more
KafkaProtocolFilterresources that apply filters to the Kafka protocol traffic passing between clients and the backend Kafka cluster.
This example shows a VirtualKafkaCluster, exposing it to Kafka clients running on the same OpenShift cluster. It uses plain TCP (as opposed to TLS) as the transport protocol.
Example VirtualKafkaCluster configuration with single clusterIP ingress
kind: VirtualKafkaCluster
apiVersion: kroxylicious.io/v1alpha1
metadata:
name: my-cluster
namespace: my-proxy
spec:
proxyRef:
name: simple
targetKafkaServiceRef:
name: my-cluster
ingresses:
- ingressRef:
name: cluster-ip
This example shows a VirtualKafkaCluster, exposing it to Kafka clients running both on and off-cluster, both using TLS. Because TLS is used, the ingress configuration must reference a TLS server certificate.
Example VirtualKafkaCluster configuration with two ingresses using TLS
kind: VirtualKafkaCluster
apiVersion: kroxylicious.io/v1alpha1
metadata:
name: my-cluster
namespace: my-proxy
spec:
proxyRef:
name: simple
targetKafkaServiceRef:
name: my-cluster
ingresses:
- ingressRef:
name: cluster-ip
certificateRef:
name: 'cluster-ip-server-cert'
kind: Secret
- ingressRef:
name: load-balancer
certificateRef:
name: 'external-server-cert'
kind: Secret
4.2.4.1. Generating TLS certificates for clusterIP ingress type Copy linkLink copied to clipboard!
When using the clusterIP ingress type with the TLS protocol, you must provide suitable TLS certificates to secure communication.
The basic steps are as follows:
- Generate a TLS server certificate that covers the service names assigned to the virtual cluster by the ingress.
-
Provide the certificate to the virtual cluster using an OpenShift
Secretof typekubernetes.io/tls.
The exact procedure for generating the certificate depends on the tooling and processes used by your organization.
The certificate must meet the following criteria:
- The certificate needs to be signed by a CA that is trusted by the on-cluster applications that connect to the virtual cluster.
- The format of the certificate must be PKCS#8 encoded PEM (Privacy Enhanced Mail). It must not be password protected.
The certificate must use SANs (Subject Alternate Names) to list all service names or use a wildcard TLS certificate that covers them all. Assuming a virtual cluster name of
my-cluster, an ingress name ofcluster-ip, and a Kafka cluster using node IDs (0-2), the following SANs must be listed in the certificate:my-cluster-cluster-ip-bootstrap.<namespace>.svc.cluster.local my-cluster-cluster-ip-0.<namespace>.svc.cluster.local my-cluster-cluster-ip-1.<namespace>.svc.cluster.local my-cluster-cluster-ip-2.<namespace>.svc.cluster.local
Create a secret for the certificate using the following command:
oc create secret tls <secret-name> --namespace <namespace> --cert=<path/to/cert/file> --key=<path/to/key/file>
<secret-name> is the name of the secret to be created, <namespace> is the name of the namespace where the proxy is to be deployed, and <path/to/cert/file> and <path/to/key/file> are the paths to the certificate and key files.
4.2.4.2. Generating TLS certificates for loadBalancer ingress type Copy linkLink copied to clipboard!
When using loadBalancer ingress type, you must provide suitable TLS certificates to secure communication.
The basic steps are as follows:
- Generate a TLS server certificate that covers the bootstrap and broker names assigned to the virtual cluster by the ingress.
-
Provide the certificate to the virtual cluster using an OpenShift
Secretof typekubernetes.io/tls.
The exact procedure for generating the certificate depends on the tooling and processes used by your organization.
The certificate must meet the following criteria:
- The certificate needs to be signed by a CA that is trusted by the off-cluster applications that connect to the virtual cluster.
- The format of the certificate must be PKCS#8 encoded PEM (Privacy Enhanced Mail). It must not be password protected.
The certificate must use SANs (Subject Alternate Names) to list the bootstrap and all the broker names or use a wildcard TLS certificate that covers them all. Assuming a
bootstrapAddressof$(virtualClusterName).kafkaproxy.example.com, anadvertisedBrokerAddressPatternofbroker-$(nodeId).$(virtualClusterName).kafkaproxy.example.com, a Kafka cluster using node IDs (0-2), and a virtual cluster name ofmy-cluster, the following SANs must be listed in the certificate:mycluster.kafkaproxy.example.com broker-0.mycluster.kafkaproxy.example.com broker-1.mycluster.kafkaproxy.example.com broker-2.mycluster.kafkaproxy.example.com
Create a secret for the certificate using the following command:
oc create secret tls <secret-name> --namespace <namespace> --cert=<path/to/cert/file> --key=<path/to/key/file>
<secret-name> is the name of the secret to be created, <namespace> is the name of the namespace where the proxy is to be deployed, and <path/to/cert/file> and <path/to/key/file> are the paths to the certificate and key files.
4.2.4.3. Configuring DNS for load balancer ingress Copy linkLink copied to clipboard!
When using the loadBalancer ingress type, you must ensure that both the bootstrapAddress and the names generated from advertisedBrokerAddressPattern resolve to the external address of the OpenShift Service underlying the load balancer on the network where the off-cluster applications run.
Prerequisites
- The Streams for Apache Kafka Proxy Operator is installed.
-
KafkaProxy,VirtualKafkaCluster, andKafkaProxyIngressresources are deployed. -
The
VirtualKafkaClusterandKafkaProxyIngressresources are configured to use aloadBalanceringress. - DNS can be configured on the network where the off-cluster applications run.
- Network traffic can to flow from the application network run to the external addresses provided by the OpenShift cluster.
Procedure
Run the following command to discover the external address being used by the load balancer:
oc get service -n <namespace> <proxy-name>-sni -o=jsonpath='{.status.loadBalancer.ingress[0]}'Replace
<namespace>with the name of the OpenShift namespace where the resources are deployed and replace<proxy-name>with the name of theKafkaProxyresource.Depending on your OpenShift environment, the command returns an IP address or a hostname. This is the external address of the load balancer.
Configure your DNS so that the bootstrap and broker names resolve to the external address.
Assuming a
bootstrapAddressof$(virtualClusterName).kafkaproxy.example.com, anadvertisedBrokerAddressPatternofbroker-$(nodeId).$(virtualClusterName).kafkaproxy.example.com, a Kafka cluster uses node IDs (0-2), and a virtual cluster name ofmy-cluster, the following DNS mappings are listed:my-cluster.kafkaproxy.example.com => <external address> broker-0.my-cluster.kafkaproxy.example.com => <external address> broker-1.my-cluster.kafkaproxy.example.com => <external address> broker-2.my-cluster.kafkaproxy.example.com => <external address>The exact steps vary by environment and network setup.
Confirm that the names resolve from the application network:
nslookup mycluster.kafkaproxy.example.com nslookup broker-0.mycluster.kafkaproxy.example.com
4.3. Filters Copy linkLink copied to clipboard!
A KafkaProtocolFilter resource represents a Streams for Apache Kafka Proxy filter. It is not uniquely associated with a VirtualKafkaCluster or KafkaProxy instance; it can be used in a number of VirtualKafkaCluster instances in the same namespace.
A KafkaProtocolFilter is similar to one of the items in a proxy configuration’s filterDefinitions:
-
The resource’s
metadata.namecorresponds directly to thenameof afilterDefinitionsitem. -
The resource’s
spec.typecorresponds directly to thetypeof afilterDefinitionsitem. -
The resource’s
spec.configTemplatecorresponds to theconfigof afilterDefinitionsitem, but is subject to interpolation by the operator.