You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: readme.md
+21-14Lines changed: 21 additions & 14 deletions
Original file line number
Diff line number
Diff line change
@@ -31,7 +31,7 @@ This is especially problematic when using a managed Kafka service where the numb
31
31
One way to solve this is with host-based routing, also known as Server Name Indication (SNI) routing.
32
32
SNI routing allows Gateway expose a single port and route requests to individual brokers based on hostname rather than port ([see SNI routing guide in the docs](https://docs.conduktor.io/gateway/how-to/sni-routing/) for more information).
33
33
34
-
This tutorial sets up SNI routing specifically for a Kubernetes cluster that exposes Gateway to clients externally via an Ingress.
34
+
This tutorial sets up SNI routing specifically for a Kubernetes cluster that exposes Gateway to clients externally via external `LoadBalancer` service.
35
35
Kubernetes has its own networking concepts, so it is helpful to see an example for how SNI routing works for Conduktor Gateway deployed on Kubernetes specifically.
36
36
37
37
Here is an overview of what we will deploy:
@@ -44,7 +44,7 @@ Here is an overview of what we will deploy:
44
44
## Setup
45
45
46
46
To run this all locally, I will use [OrbStack](https://orbstack.dev/), a container and VM management tool for Mac only (sorry!).
47
-
I chose OrbStack specifically because this tutorial aims to show how external clients will connect via an Ingress Controller, which can otherwise be difficult to do without either running up a cloud bill or sacrificing authenticity compared to a real-world deployment.
47
+
I chose OrbStack specifically because this tutorial aims to show how external clients will connect via an external `LoadBalancer` service, which can otherwise be difficult to do without either running up a cloud bill or sacrificing authenticity compared to a real-world deployment.
48
48
OrbStack has some networking magic that makes the entire tutorial run locally without sacrificing authenticity.
49
49
50
50
1. Install homebrew at [https://brew.sh/](https://brew.sh/).
@@ -108,7 +108,7 @@ This example will use TLS (formerly known as SSL) to encrypt data in transit bet
108
108
```
109
109
> **IMPORTANT:** Notice the **Subject Alternate Names** (SAN) that allow Gateway to present various hostnames to the client. This is crucial for hostname-based routing, also known as Server Name Indication (SNI) routing. Kafka clients need to know which particular broker or brokers they need to send requests to.
110
110
111
-
OrbStack handles DNS resolution automatically for us in this example, but in general, DNS must resolve all of these names to the Ingress load balancer IP address. In this case, you would need a DNS record for `gateway.conduktor.k8s.orb.local` and CNAME aliases for each SAN all pointing to the load balancer IP.
111
+
OrbStack handles DNS resolution automatically for us in this example, but in general, DNS must resolve all of these names to the external IP address of the `LoadBalancer` service. In this case, you would need a DNS record for `gateway.conduktor.k8s.orb.local` and CNAME aliases for each SAN all pointing to the load balancer IP.
112
112
113
113
Gateway impersonates brokers by presenting various hostnames to the client -- for example, `brokermain0-gateway.conduktor.k8s.orb.local` to present to the client as the broker with id `0`. The client first needs to trust that the certificate presented by Gateway includes that hostname as a SAN, otherwise TLS handshake will fail. The client then makes its request to `brokermain0-gateway.conduktor.k8s.orb.local`. Gateway receives this request and uses the SNI headers to understand that it needs to forward the request to the Kafka broker with id `0`.
114
114
@@ -133,16 +133,14 @@ This example will use TLS (formerly known as SSL) to encrypt data in transit bet
133
133
./scripts/start.sh
134
134
```
135
135
136
-
A lot happens here:
136
+
Here is what happens:
137
137
- Create shared namespace `conduktor`
138
138
- Create kubernetes secrets for Kafka
139
139
- Create kubernetes secrets for Gateway
140
140
- Install Kafka via Bitnami's Kafka helm chart
141
141
- Install Gateway via Conduktor's helm chart
142
-
- Install `ingress-nginx` Ingress Controller
143
-
- Create Ingress for Gateway
144
142
145
-
Inspect the start script, helm values, and ingress definition.
143
+
Inspect the start scriptand helm values.
146
144
147
145
### Deploy Console (Optional).
148
146
@@ -192,7 +190,7 @@ kafka-broker-api-versions \
192
190
--command-config client.properties | grep 9092
193
191
```
194
192
195
-
**NOTE**: The above uses a bit of OrbStack magic to reach an internal service from your laptop.
193
+
**NOTE**: The above uses a bit of OrbStack networking magic to reach an internal service from your laptop.
196
194
Usually you would only be able to reach an internal service from a pod within the kubernetes cluster.
197
195
198
196
Look at the hostnames in the metadata returned by Gateway, accessed externally.
@@ -203,7 +201,7 @@ kafka-broker-api-versions \
203
201
--command-config client.properties | grep 9092
204
202
```
205
203
206
-
> **NOTE**: OrbStack allows you to reach external services using the `*.k8s.orb.local` domain via Ingress Controller.
204
+
> **NOTE**: OrbStack does some magic networking here to allow you to reach external `LoadBalancer`services using the `*.k8s.orb.local` domain.
207
205
208
206
Create a topic (going through Gateway).
209
207
@@ -253,23 +251,24 @@ Clean up kubernetes resources.
253
251
kubectl delete namespace conduktor
254
252
```
255
253
256
-
If you also want to delete the Ingress controller,
254
+
Or for convenience:
257
255
258
256
```bash
259
257
./scripts/stop.sh
260
258
```
261
259
262
260
## Takeaways
263
261
264
-
- Your Ingress Controller must support **layer 4 routing** (TCP, not HTTP) with **TLS-passthrough**.
265
-
- For AWS EKS this would mean using the Load Balancer Controller with Network Load Balancer (NLB).
262
+
- It is highly recommended to configure Conduktor Gateway with an external service of type `LoadBalancer`
263
+
- For exmaple, AWS EKS uses the Load Balancer Controller with Network Load Balancer (NLB) to expose `LoadBalancer` services.
264
+
- If you have no choice but to use an Ingress Controller, it must support **layer 4 routing** (TCP, not HTTP) with **TLS-passthrough**.
266
265
- TLS passthrough is required so that Gateway can use the SNI headers in the TLS handshake to route requests to specific brokers.
267
-
- Your client must be able to resolve all hosts advertised by Gateway to the external load balancer. In this example, OrbStack magically points all `*.k8s.orb.local`to the ingress-nginx Ingress Controller, and the Ingress we defined points these hosts to the `gateway-external` service:
266
+
- Your client must be able to resolve all hosts advertised by Gateway to the external IP address. In this example, OrbStack magically routes all `*.k8s.orb.local`into the Kubernetes cluster so you don't have to update DNS anywhere, but if you had to, you would need to make sure all of these hostnames map to the external IP of the `LoadBalancer` service:
268
267
-`gateway.conduktor.k8s.orb.local`
269
268
-`brokermain0-gateway.conduktor.k8s.orb.local`
270
269
-`brokermain1-gateway.conduktor.k8s.orb.local`
271
270
-`brokermain2-gateway.conduktor.k8s.orb.local`
272
-
-As brokers are added, any `brokermain<broker id>-gateway.conduktor.k8s.orb.local` will be routed automatically without requiring changes elsewhere in the infrastructure.
271
+
-If you use a wildcard DNS, e.g. `*.conduktor.k8s.orb.local`, then as brokers are added, any `brokermain<broker id>-gateway.conduktor.k8s.orb.local` will be routed automatically without requiring changes elsewhere in the infrastructure.
273
272
- Gateway's TLS certificate must include SANs so that it can be trusted by the client when it presents itself as different brokers.
274
273
- Alternatively, you could use a certificate with a wildcard CN, which in this case would be `CN=*.conduktor.k8s.orb.local`
275
274
- Since we are using an external load balancer, we do not need to use Gateway's internal load balancing mechanism. The external load balancer will distribute load.
0 commit comments