From 25b0ab998daee1c10d748d6fd60a7878964007e3 Mon Sep 17 00:00:00 2001 From: JakeSCahill Date: Mon, 13 Jul 2026 14:48:41 +0100 Subject: [PATCH 01/14] docs: add Gateway API TLSRoute external access guide (beta, 26.2) New page for the per-listener type: tlsroute external access mode from operator PR #1615: bootstrap and per-broker TLSRoutes, SNI routing through a user-managed Gateway, hostTemplate semantics, migration from NodePort/LoadBalancer, validation rules, and troubleshooting. Facts verified against redpanda-operator main (8b034ee69): values schema, rendered resource names, advertisedPort default 443, fail-closed validation messages, and cert SAN handling. --- modules/ROOT/nav.adoc | 1 + .../kubernetes/networking/external/index.adoc | 2 +- .../networking/external/k-gateway-api.adoc | 255 ++++++++++++++++++ 3 files changed, 257 insertions(+), 1 deletion(-) create mode 100644 modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc diff --git a/modules/ROOT/nav.adoc b/modules/ROOT/nav.adoc index 089097e22c..527b6b1f2f 100644 --- a/modules/ROOT/nav.adoc +++ b/modules/ROOT/nav.adoc @@ -131,6 +131,7 @@ ***** xref:manage:kubernetes/networking/external/k-nodeport.adoc[Use a NodePort Service] ***** xref:manage:kubernetes/networking/external/k-loadbalancer.adoc[Use LoadBalancer Services] ***** xref:manage:kubernetes/networking/external/k-custom-services.adoc[Use Custom Services] +***** xref:manage:kubernetes/networking/external/k-gateway-api.adoc[Use Gateway API] *** xref:manage:kubernetes/security/index.adoc[Security] **** xref:manage:kubernetes/security/tls/index.adoc[TLS Encryption] ***** xref:manage:kubernetes/security/tls/k-cert-manager.adoc[Use cert-manager] diff --git a/modules/manage/pages/kubernetes/networking/external/index.adoc b/modules/manage/pages/kubernetes/networking/external/index.adoc index c197e41841..d88042bbf7 100644 --- a/modules/manage/pages/kubernetes/networking/external/index.adoc +++ b/modules/manage/pages/kubernetes/networking/external/index.adoc @@ -5,4 +5,4 @@ :page-categories: Management, Networking :env-kubernetes: true -Setting up external access to your Redpanda cluster allows applications running outside the Kubernetes cluster to communicate with Redpanda. To make the Redpanda brokers externally accessible, the Pods must be exposed through Kubernetes Services. \ No newline at end of file +Setting up external access to your Redpanda cluster allows applications running outside the Kubernetes cluster to communicate with Redpanda. To make the Redpanda brokers externally accessible, the Pods must be exposed through Kubernetes Services, or routed through a Gateway with xref:manage:kubernetes/networking/external/k-gateway-api.adoc[Gateway API TLSRoutes] (beta). \ No newline at end of file diff --git a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc new file mode 100644 index 0000000000..b07fa318e9 --- /dev/null +++ b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc @@ -0,0 +1,255 @@ += Configure External Access through Gateway API +:description: Use Gateway API TLSRoutes to expose your Redpanda cluster through a Gateway, without NodePort or LoadBalancer Services. +:page-beta: true +:tags: ["Kubernetes", "Helm configuration"] +:page-categories: Management, Networking +:env-kubernetes: true + +Expose your Redpanda cluster to external clients through a single https://gateway-api.sigs.k8s.io/[Gateway API^] entry point instead of NodePort or LoadBalancer Services. Clients connect to one static Gateway address, and the Gateway routes each connection to the right broker using TLS Server Name Indication (SNI), so you avoid per-broker LoadBalancers and node port management. + +This feature is in beta. The configuration surface (`external.gateway` and the per-listener `type` field) may change before general availability. Beta features are not recommended for production environments. To give feedback, reach out to the Redpanda team in https://redpanda.com/slack[Redpanda Community Slack^]. + +== How it works + +You bring your own Gateway: deploy a Gateway API implementation that supports `TLSRoute` in passthrough mode, and create a Gateway resource with a TLS passthrough listener. Redpanda then creates the routing configuration for you: + +* **A bootstrap TLSRoute and Service**: Clients make their first connection to a single hostname, such as `redpanda.example.com`. The bootstrap Service targets all brokers, so initial connections are spread across the cluster. +* **A TLSRoute and Service per broker**: After the initial connection, Kafka clients reconnect to individual brokers using the per-broker hostnames that the brokers advertise, such as `redpanda-0-broker.example.com`. The Gateway routes each connection to the right broker by matching the SNI hostname. + +The Gateway does not terminate TLS. Connections pass through to the brokers, which present their own certificates. All traffic enters through the Gateway's listener port, and brokers advertise that port (`443` by default) to clients. + +Each external listener opts in independently with `type: tlsroute`, so you can migrate from NodePort or LoadBalancer Services one listener at a time: listeners without `type: tlsroute` keep using the conventional Service, and listeners with it are excluded from that Service. + +== Prerequisites + +* Redpanda Helm chart or Redpanda Operator from the 26.2 release line or later. + +* The https://gateway-api.sigs.k8s.io/[Gateway API^] CRDs, version 1.5 or later, installed in your Kubernetes cluster. Redpanda creates `TLSRoute` resources from the GA `gateway.networking.k8s.io/v1` API, which is available in Gateway API 1.5. + +* A Gateway controller that supports `TLSRoute` with TLS passthrough, such as Envoy Gateway or Istio, and a deployed `Gateway` resource with a TLS listener in `Passthrough` mode. Redpanda does not create the Gateway. + +* TLS enabled on every listener that you route through the Gateway. The Gateway routes connections by SNI, which requires TLS. If you use xref:manage:kubernetes/security/tls/k-cert-manager.adoc[cert-manager-managed certificates], Redpanda automatically adds the bootstrap and per-broker hostnames to the certificate's Subject Alternative Names (SANs). + +* Control over DNS for your chosen hostnames. The bootstrap hostname and all per-broker hostnames must resolve to the Gateway's external address. + +* Install xref:get-started:rpk-install.adoc[rpk] on your local machine so that you can test connections from outside Kubernetes. + +== Configure Redpanda listeners for the Gateway + +. Enable gateway mode and reference your Gateway. ++ +[tabs] +====== +Operator:: ++ +-- +.`redpanda-cluster.yaml` +[,yaml] +---- +apiVersion: cluster.redpanda.com/v1alpha2 +kind: Redpanda +metadata: + name: redpanda +spec: + clusterSpec: + external: + enabled: true + gateway: + enabled: true + parentRefs: + - name: # <1> + namespace: + sectionName: # <2> + tls: + enabled: true + certs: + default: + caEnabled: true + listeners: + kafka: + external: + default: + port: 9094 + type: tlsroute # <3> + host: redpanda.example.com # <4> + hostTemplate: redpanda-$POD_ORDINAL-broker.example.com # <5> + tls: + cert: default +---- +<1> The name of the Gateway resource that you deployed. At least one `parentRefs` entry is required. +<2> Optional: The name of the TLS passthrough listener on the Gateway. +<3> Routes this listener through the Gateway and excludes it from the NodePort or LoadBalancer Service. +<4> The bootstrap hostname that clients use for their first connection. +<5> The per-broker hostname pattern. `$POD_ORDINAL` is replaced with the broker's ordinal, and `$POD_NAME` with the Pod name. Required for Kafka listeners when you run more than one broker. + +[,bash] +---- +kubectl apply -f redpanda-cluster.yaml --namespace +---- +-- +Helm:: ++ +-- +.`gateway-values.yaml` +[,yaml] +---- +external: + enabled: true + gateway: + enabled: true + parentRefs: + - name: # <1> + namespace: + sectionName: # <2> +tls: + enabled: true + certs: + default: + caEnabled: true +listeners: + kafka: + external: + default: + port: 9094 + type: tlsroute # <3> + host: redpanda.example.com # <4> + hostTemplate: redpanda-$POD_ORDINAL-broker.example.com # <5> + tls: + cert: default +---- +<1> The name of the Gateway resource that you deployed. At least one `parentRefs` entry is required. +<2> Optional: The name of the TLS passthrough listener on the Gateway. +<3> Routes this listener through the Gateway and excludes it from the NodePort or LoadBalancer Service. +<4> The bootstrap hostname that clients use for their first connection. +<5> The per-broker hostname pattern. `$POD_ORDINAL` is replaced with the broker's ordinal, and `$POD_NAME` with the Pod name. Required for Kafka listeners when you run more than one broker. + +[,bash] +---- +helm upgrade --install redpanda redpanda/redpanda \ + --namespace --create-namespace \ + --values gateway-values.yaml +---- +-- +====== ++ +By default, brokers advertise port `443` to clients. If your Gateway listens on a different port, set `external.gateway.advertisedPort`. + +. Create DNS records that resolve the bootstrap hostname and all per-broker hostnames to your Gateway's external address. A wildcard record such as `*.example.com` covers both. + +. Verify that Redpanda created the TLSRoutes and that the Gateway accepted them: ++ +[,bash] +---- +kubectl get tlsroutes --namespace +---- ++ +For a three-broker cluster named `redpanda`, expect a bootstrap route and one route per broker: ++ +---- +NAME HOSTNAMES +redpanda-kafka-default-bootstrap ["redpanda.example.com"] +redpanda-kafka-default-0 ["redpanda-0-broker.example.com"] +redpanda-kafka-default-1 ["redpanda-1-broker.example.com"] +redpanda-kafka-default-2 ["redpanda-2-broker.example.com"] +---- ++ +Check that each route's `status.parents` reports `Accepted: True` from your Gateway controller: ++ +[,bash] +---- +kubectl get tlsroute --namespace -o jsonpath='{.status.parents}' +---- + +. Test the connection from outside the Kubernetes cluster: ++ +[,bash] +---- +rpk cluster info \ + -X brokers=redpanda.example.com:443 \ + -X tls.enabled=true \ + -X tls.ca=ca.crt +---- ++ +The broker list shows the per-broker hostnames with the advertised port. + +== Route other listeners through the Gateway + +The HTTP Proxy, Admin API, and Schema Registry listeners support `type: tlsroute` with the same `host` field. For these listeners, `hostTemplate` is optional: without it, Redpanda creates only the bootstrap route, and the Gateway load-balances requests across brokers. Give each listener a unique hostname: + +[,yaml] +---- +listeners: + kafka: + external: + default: + port: 9094 + type: tlsroute + host: kafka.example.com + hostTemplate: kafka-$POD_ORDINAL.example.com + tls: + cert: default + http: + external: + default: + port: 8082 + type: tlsroute + host: proxy.example.com + tls: + cert: default + schemaRegistry: + external: + default: + port: 8081 + type: tlsroute + host: schema.example.com + tls: + cert: default +---- + +== Migrate from NodePort or LoadBalancer Services + +The per-listener `type` field lets conventional and Gateway-routed listeners coexist, so you can migrate with no downtime: + +. Add a new external listener with `type: tlsroute` on a different port, alongside your existing listener. +. Point new clients, or a subset of clients, at the bootstrap hostname and verify connectivity. +. Move the remaining clients over. +. Remove the old external listener. When no listeners use the conventional Service, remove `external.type` and the associated NodePort or LoadBalancer configuration. + +== Configuration validation + +Redpanda refuses to render configurations that would silently break connectivity: + +* A listener with `type: tlsroute` requires `external.gateway.enabled: true` with at least one `parentRefs` entry. The listener is never placed in a NodePort or LoadBalancer Service as a fallback. +* Every Gateway-routed listener requires `host`. +* A Kafka listener with more than one broker requires `hostTemplate`, because Kafka clients must reconnect to individual brokers. + +If any of these conditions fail, the Helm release or Redpanda resource fails with an error that names the listener. + +== Troubleshooting + +**Clients connect to the bootstrap hostname but fail on reconnect**: The per-broker hostnames don't resolve to the Gateway, or the broker certificates don't include them. Check your DNS records, and verify the certificate SANs: + +[,bash] +---- +kubectl get secret --namespace \ + -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -text | grep DNS +---- + +**TLSRoutes exist but `status.parents` is empty or not Accepted**: Your Gateway controller doesn't support `TLSRoute` from `gateway.networking.k8s.io/v1`, the Gateway listener isn't in `Passthrough` mode, or the route's `parentRefs` doesn't match the Gateway's name, namespace, or listener `sectionName`. + +**Connection refused or routed to the wrong broker**: Verify that your client sends SNI. Connections without SNI (for example, plain TCP tools like `nc`) cannot be routed. Test with: + +[,bash] +---- +openssl s_client -connect :443 -servername redpanda.example.com Date: Mon, 13 Jul 2026 16:27:19 +0100 Subject: [PATCH 02/14] docs: add validated prerequisites for Gateway API external access Kind validation findings: - Kubernetes 1.31+ required: Gateway API 1.5 CRDs use CEL functions (isIP) that older API servers cannot compile - Controllers watching TLSRoute v1alpha2 (Envoy Gateway <= 1.7) need the Gateway API experimental channel CRDs, which serve v1alpha2 alongside v1; the standard channel serves v1 only - New troubleshooting entry for attachedRoutes: 0 / missing route status --- .../kubernetes/networking/external/k-gateway-api.adoc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc index b07fa318e9..797b3622c9 100644 --- a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc +++ b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc @@ -24,9 +24,16 @@ Each external listener opts in independently with `type: tlsroute`, so you can m * Redpanda Helm chart or Redpanda Operator from the 26.2 release line or later. +* Kubernetes 1.31 or later. The Gateway API 1.5 CRDs use Common Expression Language (CEL) functions that older API servers cannot compile, so they fail to install on earlier Kubernetes versions. + * The https://gateway-api.sigs.k8s.io/[Gateway API^] CRDs, version 1.5 or later, installed in your Kubernetes cluster. Redpanda creates `TLSRoute` resources from the GA `gateway.networking.k8s.io/v1` API, which is available in Gateway API 1.5. * A Gateway controller that supports `TLSRoute` with TLS passthrough, such as Envoy Gateway or Istio, and a deployed `Gateway` resource with a TLS listener in `Passthrough` mode. Redpanda does not create the Gateway. ++ +[NOTE] +==== +Check which `TLSRoute` API version your Gateway controller watches. Controllers that still watch the deprecated `v1alpha2` version, which includes Envoy Gateway 1.7 and earlier, cannot see routes when the Gateway API *standard* channel CRDs are installed, because the standard channel serves `TLSRoute` only at `v1`. In that case, install the Gateway API *experimental* channel CRDs instead: they serve `v1alpha2` alongside `v1`, so both Redpanda and the controller can work with the same routes. Also install such controllers without their bundled, older Gateway API CRDs (for example, `helm install --skip-crds` for Envoy Gateway). +==== * TLS enabled on every listener that you route through the Gateway. The Gateway routes connections by SNI, which requires TLS. If you use xref:manage:kubernetes/security/tls/k-cert-manager.adoc[cert-manager-managed certificates], Redpanda automatically adds the bootstrap and per-broker hostnames to the certificate's Subject Alternative Names (SANs). @@ -235,7 +242,9 @@ kubectl get secret --namespace \ -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -text | grep DNS ---- -**TLSRoutes exist but `status.parents` is empty or not Accepted**: Your Gateway controller doesn't support `TLSRoute` from `gateway.networking.k8s.io/v1`, the Gateway listener isn't in `Passthrough` mode, or the route's `parentRefs` doesn't match the Gateway's name, namespace, or listener `sectionName`. +**TLSRoutes exist but have no `status`, and the Gateway reports `attachedRoutes: 0`**: Your Gateway controller cannot see the routes because it watches the deprecated `v1alpha2` version of `TLSRoute` and your installed Gateway API CRDs serve only `v1`. Install the Gateway API experimental channel CRDs, which serve both versions, and restart the controller. See <>. + +**TLSRoutes have a `status.parents` entry but the route is not Accepted**: The Gateway listener isn't in `Passthrough` mode, or the route's `parentRefs` doesn't match the Gateway's name, namespace, or listener `sectionName`. **Connection refused or routed to the wrong broker**: Verify that your client sends SNI. Connections without SNI (for example, plain TCP tools like `nc`) cannot be routed. Test with: From f93979def1781ce8c391dee16927ca0ee643c3f1 Mon Sep 17 00:00:00 2001 From: JakeSCahill Date: Tue, 14 Jul 2026 10:49:29 +0100 Subject: [PATCH 03/14] docs: pin Gateway API prerequisite to published operator beta version The feature ships in the published operator chart 26.2.1-beta.x (the Redpanda CR path is runnable today), but no published Redpanda Helm chart includes it yet (latest is 26.1.8). State both explicitly and note the Helm tab requires the future 26.2 chart. --- .../pages/kubernetes/networking/external/k-gateway-api.adoc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc index 797b3622c9..550fcae699 100644 --- a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc +++ b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc @@ -22,7 +22,9 @@ Each external listener opts in independently with `type: tlsroute`, so you can m == Prerequisites -* Redpanda Helm chart or Redpanda Operator from the 26.2 release line or later. +* Redpanda Operator {operator-beta-version} or later, or Redpanda Helm chart 26.2.0 or later. ++ +NOTE: During the 26.2 beta, this feature is available only through the Redpanda Operator beta releases. No published Redpanda Helm chart includes it yet. If you deploy with Helm rather than the Operator, wait for the 26.2 chart release. * Kubernetes 1.31 or later. The Gateway API 1.5 CRDs use Common Expression Language (CEL) functions that older API servers cannot compile, so they fail to install on earlier Kubernetes versions. @@ -97,6 +99,8 @@ kubectl apply -f redpanda-cluster.yaml --namespace Helm:: + -- +NOTE: Requires Redpanda Helm chart 26.2.0 or later. During the 26.2 beta, no published chart includes this feature; use the Redpanda Operator instead. + .`gateway-values.yaml` [,yaml] ---- From 323269d67d4964700ba401e6a47a5d6e5052f817 Mon Sep 17 00:00:00 2001 From: JakeSCahill Date: Tue, 14 Jul 2026 12:52:17 +0100 Subject: [PATCH 04/14] docs: add operator beta version fallbacks so the Gateway API page renders a version The prerequisite uses {operator-beta-version}; without the antora.yml fallback it renders empty when the build-time version fetch is unavailable. Same fallback values as PR #1681 (identical lines, so the eventual merge is clean). --- antora.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/antora.yml b/antora.yml index 4e2c794239..e854317b0d 100644 --- a/antora.yml +++ b/antora.yml @@ -38,7 +38,8 @@ asciidoc: latest-console-tag: 'v3.3.1' latest-release-commit: 'ebee215fdb2b8004735c6f800e532564cdcc05e1' latest-operator-version: 'v2.3.8-24.3.6' - operator-beta-tag: '' + operator-beta-version: '26.2.1-beta.3' + operator-beta-tag: 'v26.2.1-beta.3' helm-beta-tag: '' latest-redpanda-helm-chart-version: '' redpanda-beta-version: '' From 3c4a97b315313e4dbd5e2ecb15746ecfe6f536e2 Mon Sep 17 00:00:00 2001 From: JakeSCahill Date: Tue, 14 Jul 2026 12:59:06 +0100 Subject: [PATCH 05/14] docs: show how to install the beta operator in Gateway API prerequisites The prerequisite named a beta version without saying how to get it. Add the operator beta install command (beta chart version pinned via the operator-beta-version attribute) and a not-for-production note. --- .../networking/external/k-gateway-api.adoc | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc index 550fcae699..290862a782 100644 --- a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc +++ b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc @@ -24,7 +24,22 @@ Each external listener opts in independently with `type: tlsroute`, so you can m * Redpanda Operator {operator-beta-version} or later, or Redpanda Helm chart 26.2.0 or later. + -NOTE: During the 26.2 beta, this feature is available only through the Redpanda Operator beta releases. No published Redpanda Helm chart includes it yet. If you deploy with Helm rather than the Operator, wait for the 26.2 chart release. +[NOTE] +==== +During the 26.2 beta, this feature is available only through the Redpanda Operator beta releases. Beta releases are not recommended for production use. Install or upgrade the operator with the beta chart version: + +[,bash,subs="attributes+"] +---- +helm repo add redpanda https://charts.redpanda.com +helm repo update +helm upgrade --install redpanda-operator redpanda/operator \ + --namespace --create-namespace \ + --version {operator-beta-version} \ + --set crds.enabled=true +---- + +No published Redpanda Helm chart includes this feature yet. If you deploy with the Helm chart rather than the Operator, wait for the 26.2 chart release. +==== * Kubernetes 1.31 or later. The Gateway API 1.5 CRDs use Common Expression Language (CEL) functions that older API servers cannot compile, so they fail to install on earlier Kubernetes versions. From b3a8479b8340fa2c30533dda1c9da4a74abc6eb5 Mon Sep 17 00:00:00 2001 From: JakeSCahill Date: Tue, 14 Jul 2026 17:17:25 +0100 Subject: [PATCH 06/14] docs: correct Gateway API TLSRoute controller and verification guidance Validated the procedure end-to-end on kind (operator 26.2.1-beta.3, Gateway API 1.5, Envoy Gateway, cert-manager) and fixed two issues: - Verification step: plain `kubectl get tlsroutes` prints only NAME/AGE, so use `-o custom-columns` to show hostnames; corrected sample output. - Controller guidance: recommend a controller that watches TLSRoute at v1 (Envoy Gateway 1.8+). Envoy Gateway 1.7 and earlier detect the CRD only at their server-preferred version, which Gateway API 1.5 makes v1, so they never attach the routes even with the experimental channel. --- .../networking/external/k-gateway-api.adoc | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc index 290862a782..305acd6e4b 100644 --- a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc +++ b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc @@ -49,7 +49,11 @@ No published Redpanda Helm chart includes this feature yet. If you deploy with t + [NOTE] ==== -Check which `TLSRoute` API version your Gateway controller watches. Controllers that still watch the deprecated `v1alpha2` version, which includes Envoy Gateway 1.7 and earlier, cannot see routes when the Gateway API *standard* channel CRDs are installed, because the standard channel serves `TLSRoute` only at `v1`. In that case, install the Gateway API *experimental* channel CRDs instead: they serve `v1alpha2` alongside `v1`, so both Redpanda and the controller can work with the same routes. Also install such controllers without their bundled, older Gateway API CRDs (for example, `helm install --skip-crds` for Envoy Gateway). +Use a controller version that watches `TLSRoute` at the GA `gateway.networking.k8s.io/v1` API, because Redpanda creates its routes at `v1`. For Envoy Gateway, this means version 1.8 or later. + +Envoy Gateway 1.7 and earlier watch the deprecated `v1alpha2` version and detect the `TLSRoute` CRD only at its server-preferred version. Because Gateway API 1.5 makes `v1` the preferred (storage) version of `TLSRoute`, these earlier controllers log `TLSRoute CRD not found, skipping TLSRoute watch` and never attach the routes, even when the *experimental* channel CRDs serve `v1alpha2` alongside `v1`. Upgrading the controller is the reliable fix; installing the experimental channel alone does not resolve it. + +Install the controller without its bundled Gateway API CRDs (for example, `helm install --skip-crds` for Envoy Gateway) so it uses your Gateway API 1.5 CRDs rather than replacing them with an older bundled version. ==== * TLS enabled on every listener that you route through the Gateway. The Gateway routes connections by SNI, which requires TLS. If you use xref:manage:kubernetes/security/tls/k-cert-manager.adoc[cert-manager-managed certificates], Redpanda automatically adds the bootstrap and per-broker hostnames to the certificate's Subject Alternative Names (SANs). @@ -166,17 +170,20 @@ By default, brokers advertise port `443` to clients. If your Gateway listens on + [,bash] ---- -kubectl get tlsroutes --namespace +kubectl get tlsroutes --namespace \ + -o custom-columns='NAME:.metadata.name,HOSTNAMES:.spec.hostnames' ---- + +NOTE: Plain `kubectl get tlsroutes` prints only the `NAME` and `AGE` columns. Use the `custom-columns` output above (or `-o yaml`) to see the hostnames. ++ For a three-broker cluster named `redpanda`, expect a bootstrap route and one route per broker: + ---- -NAME HOSTNAMES -redpanda-kafka-default-bootstrap ["redpanda.example.com"] -redpanda-kafka-default-0 ["redpanda-0-broker.example.com"] -redpanda-kafka-default-1 ["redpanda-1-broker.example.com"] -redpanda-kafka-default-2 ["redpanda-2-broker.example.com"] +NAME HOSTNAMES +redpanda-kafka-default-0 [redpanda-0-broker.example.com] +redpanda-kafka-default-1 [redpanda-1-broker.example.com] +redpanda-kafka-default-2 [redpanda-2-broker.example.com] +redpanda-kafka-default-bootstrap [redpanda.example.com] ---- + Check that each route's `status.parents` reports `Accepted: True` from your Gateway controller: @@ -261,7 +268,7 @@ kubectl get secret --namespace \ -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -text | grep DNS ---- -**TLSRoutes exist but have no `status`, and the Gateway reports `attachedRoutes: 0`**: Your Gateway controller cannot see the routes because it watches the deprecated `v1alpha2` version of `TLSRoute` and your installed Gateway API CRDs serve only `v1`. Install the Gateway API experimental channel CRDs, which serve both versions, and restart the controller. See <>. +**TLSRoutes exist but have no `status`, and the Gateway reports `attachedRoutes: 0`**: Your Gateway controller isn't watching `TLSRoute` at the `v1` API that Redpanda uses. Controllers that watch only the deprecated `v1alpha2` version, such as Envoy Gateway 1.7 and earlier, cannot attach these routes, and the controller log shows a message such as `TLSRoute CRD not found, skipping TLSRoute watch`. Upgrade to a controller version that watches `TLSRoute` at `v1` (Envoy Gateway 1.8 or later). Installing the experimental channel CRDs or restarting the controller does not help on its own. See <>. **TLSRoutes have a `status.parents` entry but the route is not Accepted**: The Gateway listener isn't in `Passthrough` mode, or the route's `parentRefs` doesn't match the Gateway's name, namespace, or listener `sectionName`. From 52b83b3928f97ea513a18545aca891fe27ae92a6 Mon Sep 17 00:00:00 2001 From: JakeSCahill Date: Mon, 20 Jul 2026 09:35:57 +0100 Subject: [PATCH 07/14] docs: reference supported Kubernetes versions in Gateway API prerequisites --- .../pages/kubernetes/networking/external/k-gateway-api.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc index 305acd6e4b..e4db8015e3 100644 --- a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc +++ b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc @@ -41,7 +41,7 @@ helm upgrade --install redpanda-operator redpanda/operator \ No published Redpanda Helm chart includes this feature yet. If you deploy with the Helm chart rather than the Operator, wait for the 26.2 chart release. ==== -* Kubernetes 1.31 or later. The Gateway API 1.5 CRDs use Common Expression Language (CEL) functions that older API servers cannot compile, so they fail to install on earlier Kubernetes versions. +* A xref:upgrade:k-compatibility.adoc#compatibility-matrix[supported Kubernetes version]. The Gateway API 1.5 CRDs use Common Expression Language (CEL) functions that API servers earlier than Kubernetes 1.31 cannot compile, so they fail to install on unsupported Kubernetes versions. * The https://gateway-api.sigs.k8s.io/[Gateway API^] CRDs, version 1.5 or later, installed in your Kubernetes cluster. Redpanda creates `TLSRoute` resources from the GA `gateway.networking.k8s.io/v1` API, which is available in Gateway API 1.5. From 905c5fb991006f2b44e755e1280393e70a9a381b Mon Sep 17 00:00:00 2001 From: JakeSCahill Date: Tue, 21 Jul 2026 10:42:25 +0100 Subject: [PATCH 08/14] docs: assume 26.2 GA; remove beta operator install framing The feature-level beta status stays (eng ships TLSRoute support as beta); the release-level beta framing goes: standard operator install with {latest-operator-version}, no beta chart pin, and the antora.yml beta fallbacks revert since no page references them. --- antora.yml | 8 +++++--- .../kubernetes/networking/external/k-gateway-api.adoc | 8 ++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/antora.yml b/antora.yml index e854317b0d..512cc4b025 100644 --- a/antora.yml +++ b/antora.yml @@ -34,12 +34,11 @@ asciidoc: # We try to fetch the latest versions from GitHub at build time # -- full-version: 26.2.1 - latest-redpanda-tag: 'v26.1.9' + latest-redpanda-tag: 'v26.1.12' latest-console-tag: 'v3.3.1' latest-release-commit: 'ebee215fdb2b8004735c6f800e532564cdcc05e1' latest-operator-version: 'v2.3.8-24.3.6' - operator-beta-version: '26.2.1-beta.3' - operator-beta-tag: 'v26.2.1-beta.3' + operator-beta-tag: '' helm-beta-tag: '' latest-redpanda-helm-chart-version: '' redpanda-beta-version: '' @@ -53,6 +52,9 @@ asciidoc: supported-rhel-recommended: '9+' supported-ubuntu-required: '20.04 LTS' supported-ubuntu-recommended: '22.04+' + # Linux package repository migration (dl.redpanda.com -> linux.pkg.redpanda.com) + legacy-repo-shutdown-date: 'September 28, 2026' + repo-dual-publish-start: 'June 1, 2026' badge-deprecated: 'image:https://img.shields.io/badge/-Deprecated-red.svg[xref=upgrade:deprecated/index.adoc]' removals-without-aliases: - page: reference/rpk/rpk-cloud/ diff --git a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc index e4db8015e3..b58cf4e0ed 100644 --- a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc +++ b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc @@ -22,11 +22,11 @@ Each external listener opts in independently with `type: tlsroute`, so you can m == Prerequisites -* Redpanda Operator {operator-beta-version} or later, or Redpanda Helm chart 26.2.0 or later. +* Redpanda Operator 26.2 or later, or Redpanda Helm chart 26.2.0 or later. + [NOTE] ==== -During the 26.2 beta, this feature is available only through the Redpanda Operator beta releases. Beta releases are not recommended for production use. Install or upgrade the operator with the beta chart version: +Install or upgrade the operator: [,bash,subs="attributes+"] ---- @@ -34,7 +34,7 @@ helm repo add redpanda https://charts.redpanda.com helm repo update helm upgrade --install redpanda-operator redpanda/operator \ --namespace --create-namespace \ - --version {operator-beta-version} \ + --version {latest-operator-version} \ --set crds.enabled=true ---- @@ -118,7 +118,7 @@ kubectl apply -f redpanda-cluster.yaml --namespace Helm:: + -- -NOTE: Requires Redpanda Helm chart 26.2.0 or later. During the 26.2 beta, no published chart includes this feature; use the Redpanda Operator instead. +NOTE: Requires Redpanda Helm chart 26.2.0 or later. .`gateway-values.yaml` [,yaml] From 5e62cae81ff2a34d12f6d5d1159d00e9de7b3b57 Mon Sep 17 00:00:00 2001 From: JakeSCahill Date: Tue, 21 Jul 2026 12:22:59 +0100 Subject: [PATCH 09/14] docs: pin operator install to 26.2.1 Same rationale as the stretch guide: previews resolve latest-operator-version to 26.1.x until GA; swap back after GA. --- .../pages/kubernetes/networking/external/k-gateway-api.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc index b58cf4e0ed..1ff4e84eb8 100644 --- a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc +++ b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc @@ -34,7 +34,7 @@ helm repo add redpanda https://charts.redpanda.com helm repo update helm upgrade --install redpanda-operator redpanda/operator \ --namespace --create-namespace \ - --version {latest-operator-version} \ + --version 26.2.1 \ --set crds.enabled=true ---- From e5752ebad21366d42b5bd065d302f057490e8c57 Mon Sep 17 00:00:00 2001 From: JakeSCahill Date: Tue, 21 Jul 2026 12:25:25 +0100 Subject: [PATCH 10/14] Revert "docs: pin operator install to 26.2.1" This reverts commit 5e62cae81ff2a34d12f6d5d1159d00e9de7b3b57. --- .../pages/kubernetes/networking/external/k-gateway-api.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc index 1ff4e84eb8..b58cf4e0ed 100644 --- a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc +++ b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc @@ -34,7 +34,7 @@ helm repo add redpanda https://charts.redpanda.com helm repo update helm upgrade --install redpanda-operator redpanda/operator \ --namespace --create-namespace \ - --version 26.2.1 \ + --version {latest-operator-version} \ --set crds.enabled=true ---- From 044c3e579bdb636928b9f0592eb84a2d0deac32f Mon Sep 17 00:00:00 2001 From: JakeSCahill Date: Wed, 22 Jul 2026 14:55:59 +0100 Subject: [PATCH 11/14] docs: add Gateway/TLSRoute examples and TLS termination workflow Address review feedback on the Gateway API guide: - Add a Deploy a Gateway section with complete GatewayClass and Gateway manifests for both TLS passthrough and TLS termination, including the cert-manager Certificate that a Terminate listener needs - Add a Choose a TLS mode section comparing passthrough and termination (encryption boundary, certificates, mTLS availability, controller support) - Show the rendered bootstrap TLSRoute and its per-broker counterparts in the verify step - Document the termination listener config (tls.enabled: false), the mode-dependent client CA, and mode-aware troubleshooting Both workflows validated end-to-end on kind v1.34.0 with Envoy Gateway 1.8.2: routes Accepted in both modes, produce/consume through the Gateway with the broker CA (passthrough) and the Gateway CA (termination). --- .../networking/external/k-gateway-api.adoc | 222 +++++++++++++++++- 1 file changed, 210 insertions(+), 12 deletions(-) diff --git a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc index b58cf4e0ed..9453e0baf9 100644 --- a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc +++ b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc @@ -11,15 +11,46 @@ This feature is in beta. The configuration surface (`external.gateway` and the p == How it works -You bring your own Gateway: deploy a Gateway API implementation that supports `TLSRoute` in passthrough mode, and create a Gateway resource with a TLS passthrough listener. Redpanda then creates the routing configuration for you: +You bring your own Gateway: deploy a Gateway API implementation that supports `TLSRoute`, and create a Gateway resource with a TLS listener (see <>). Redpanda then creates the routing configuration for you: -* **A bootstrap TLSRoute and Service**: Clients make their first connection to a single hostname, such as `redpanda.example.com`. The bootstrap Service targets all brokers, so initial connections are spread across the cluster. -* **A TLSRoute and Service per broker**: After the initial connection, Kafka clients reconnect to individual brokers using the per-broker hostnames that the brokers advertise, such as `redpanda-0-broker.example.com`. The Gateway routes each connection to the right broker by matching the SNI hostname. +* *A bootstrap TLSRoute and Service*: Clients make their first connection to a single hostname, such as `redpanda.example.com`. The bootstrap Service targets all brokers, so initial connections are spread across the cluster. +* *A TLSRoute and Service per broker*: After the initial connection, Kafka clients reconnect to individual brokers using the per-broker hostnames that the brokers advertise, such as `redpanda-0-broker.example.com`. The Gateway routes each connection to the right broker by matching the SNI hostname. -The Gateway does not terminate TLS. Connections pass through to the brokers, which present their own certificates. All traffic enters through the Gateway's listener port, and brokers advertise that port (`443` by default) to clients. +All traffic enters through the Gateway's listener port, and brokers advertise that port (`443` by default) to clients. The Gateway either forwards each TLS connection unchanged to the broker (passthrough) or decrypts it and forwards the plain connection (termination). See <>. Each external listener opts in independently with `type: tlsroute`, so you can migrate from NodePort or LoadBalancer Services one listener at a time: listeners without `type: tlsroute` keep using the conventional Service, and listeners with it are excluded from that Service. +== Choose a TLS mode + +The Gateway listener's `tls.mode` determines where TLS ends. Redpanda creates the same TLSRoutes in both modes: the difference lives in the Gateway listener and in the Redpanda listener's TLS configuration. + +[cols="1h,2,2"] +|=== +| |Passthrough (recommended) |Termination + +|How it works +|The Gateway forwards the encrypted connection to the broker, and the broker presents its own certificate to the client. +|The Gateway decrypts the connection with its own certificate and forwards unencrypted traffic to the broker. + +|Encryption +|End-to-end TLS from client to broker. +|TLS ends at the Gateway. Traffic between the Gateway and the brokers is unencrypted. + +|Certificates +|The broker certificates must include the bootstrap and per-broker hostnames. Redpanda adds these SANs automatically to xref:manage:kubernetes/security/tls/k-cert-manager.adoc[cert-manager-managed certificates]. +|One certificate on the Gateway covers all hostnames. The broker certificates are not involved. + +|Client authentication +|mTLS and SASL both work. +|mTLS is not available because the brokers never see the client's TLS session. Use SASL. + +|Gateway support +|Supported by all `TLSRoute`-capable Gateway implementations. +|Optional in the Gateway API specification, so not all implementations support it. Envoy Gateway 1.8 or later does. +|=== + +Choose passthrough unless you need to manage client-facing certificates centrally at the Gateway and can accept unencrypted traffic between the Gateway and the brokers. + == Prerequisites * Redpanda Operator 26.2 or later, or Redpanda Helm chart 26.2.0 or later. @@ -45,7 +76,7 @@ No published Redpanda Helm chart includes this feature yet. If you deploy with t * The https://gateway-api.sigs.k8s.io/[Gateway API^] CRDs, version 1.5 or later, installed in your Kubernetes cluster. Redpanda creates `TLSRoute` resources from the GA `gateway.networking.k8s.io/v1` API, which is available in Gateway API 1.5. -* A Gateway controller that supports `TLSRoute` with TLS passthrough, such as Envoy Gateway or Istio, and a deployed `Gateway` resource with a TLS listener in `Passthrough` mode. Redpanda does not create the Gateway. +* A Gateway controller that supports `TLSRoute`, such as Envoy Gateway or Istio. Redpanda does not create the Gateway resource. See <>. + [NOTE] ==== @@ -56,12 +87,128 @@ Envoy Gateway 1.7 and earlier watch the deprecated `v1alpha2` version and detect Install the controller without its bundled Gateway API CRDs (for example, `helm install --skip-crds` for Envoy Gateway) so it uses your Gateway API 1.5 CRDs rather than replacing them with an older bundled version. ==== -* TLS enabled on every listener that you route through the Gateway. The Gateway routes connections by SNI, which requires TLS. If you use xref:manage:kubernetes/security/tls/k-cert-manager.adoc[cert-manager-managed certificates], Redpanda automatically adds the bootstrap and per-broker hostnames to the certificate's Subject Alternative Names (SANs). +* TLS between clients and the Gateway. The Gateway routes connections by SNI, which requires clients to connect with TLS in both modes. With passthrough, enable TLS on every Redpanda listener that you route through the Gateway; if you use xref:manage:kubernetes/security/tls/k-cert-manager.adoc[cert-manager-managed certificates], Redpanda automatically adds the bootstrap and per-broker hostnames to the certificate's Subject Alternative Names (SANs). With termination, the Gateway presents its own certificate instead. See <>. * Control over DNS for your chosen hostnames. The bootstrap hostname and all per-broker hostnames must resolve to the Gateway's external address. * Install xref:get-started:rpk-install.adoc[rpk] on your local machine so that you can test connections from outside Kubernetes. +== Deploy a Gateway + +Redpanda attaches its TLSRoutes to a Gateway that you deploy and manage. + +. If your Gateway controller does not create a GatewayClass, create one. For example, Envoy Gateway does not ship a default GatewayClass: ++ +[,yaml] +---- +apiVersion: gateway.networking.k8s.io/v1 +kind: GatewayClass +metadata: + name: envoy +spec: + controllerName: gateway.envoyproxy.io/gatewayclass-controller +---- + +. Create a Gateway with a TLS listener in your chosen mode. See <>. ++ +[tabs] +====== +TLS passthrough:: ++ +-- +.`gateway.yaml` +[,yaml] +---- +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: redpanda-gateway + namespace: +spec: + gatewayClassName: envoy # <1> + listeners: + - name: kafka # <2> + protocol: TLS + port: 443 # <3> + tls: + mode: Passthrough # <4> + allowedRoutes: + kinds: + - kind: TLSRoute + group: gateway.networking.k8s.io +---- +<1> The name of your GatewayClass. +<2> The listener name. Reference it later in `external.gateway.parentRefs[].sectionName`. +<3> The port that clients connect to. Brokers advertise `external.gateway.advertisedPort` (`443` by default), so keep the two in sync. +<4> The Gateway forwards TLS connections to the brokers unchanged. +-- +TLS termination:: ++ +-- +The Gateway needs a certificate whose SANs cover the bootstrap hostname and all per-broker hostnames, either listed individually or through a wildcard. This example issues one with cert-manager: + +.`gateway-certificate.yaml` +[,yaml] +---- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: gateway-tls-cert + namespace: +spec: + secretName: gateway-tls-cert + dnsNames: + - redpanda.example.com # <1> + - redpanda-0-broker.example.com # <2> + - redpanda-1-broker.example.com + - redpanda-2-broker.example.com + issuerRef: + name: + kind: Issuer +---- +<1> The bootstrap hostname. +<2> One entry per broker, or a wildcard such as `*.example.com` that covers them all. + +.`gateway.yaml` +[,yaml] +---- +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: redpanda-gateway + namespace: +spec: + gatewayClassName: envoy + listeners: + - name: kafka + protocol: TLS + port: 443 + tls: + mode: Terminate # <1> + certificateRefs: + - name: gateway-tls-cert # <2> + allowedRoutes: + kinds: + - kind: TLSRoute + group: gateway.networking.k8s.io +---- +<1> The Gateway decrypts client connections and forwards unencrypted traffic to the brokers. +<2> The Secret that contains the certificate the Gateway presents to clients. +-- +====== + +. Apply the manifests and verify that the Gateway controller accepts the listener: ++ +[,bash] +---- +kubectl apply -f gateway.yaml --namespace + +kubectl get gateway redpanda-gateway --namespace \ + -o jsonpath='{range .status.listeners[*]}{.name}: {range .conditions[*]}{.type}={.status} {end}{"\n"}{end}' +---- ++ +The listener reports `Accepted=True` and `Programmed=True`. The Gateway's external address comes from your Gateway implementation, typically through a LoadBalancer Service that it provisions. + == Configure Redpanda listeners for the Gateway . Enable gateway mode and reference your Gateway. @@ -105,7 +252,7 @@ spec: cert: default ---- <1> The name of the Gateway resource that you deployed. At least one `parentRefs` entry is required. -<2> Optional: The name of the TLS passthrough listener on the Gateway. +<2> Optional: The name of the TLS listener on the Gateway. <3> Routes this listener through the Gateway and excludes it from the NodePort or LoadBalancer Service. <4> The bootstrap hostname that clients use for their first connection. <5> The per-broker hostname pattern. `$POD_ORDINAL` is replaced with the broker's ordinal, and `$POD_NAME` with the Pod name. Required for Kafka listeners when you run more than one broker. @@ -148,7 +295,7 @@ listeners: cert: default ---- <1> The name of the Gateway resource that you deployed. At least one `parentRefs` entry is required. -<2> Optional: The name of the TLS passthrough listener on the Gateway. +<2> Optional: The name of the TLS listener on the Gateway. <3> Routes this listener through the Gateway and excludes it from the NodePort or LoadBalancer Service. <4> The bootstrap hostname that clients use for their first connection. <5> The per-broker hostname pattern. `$POD_ORDINAL` is replaced with the broker's ordinal, and `$POD_NAME` with the Pod name. Required for Kafka listeners when you run more than one broker. @@ -163,6 +310,22 @@ helm upgrade --install redpanda redpanda/redpanda \ ====== + By default, brokers advertise port `443` to clients. If your Gateway listens on a different port, set `external.gateway.advertisedPort`. ++ +If your Gateway listener terminates TLS, disable TLS on the Redpanda listener instead of referencing a certificate, because connections arrive at the brokers already decrypted: ++ +[,yaml] +---- +listeners: + kafka: + external: + default: + port: 9094 + type: tlsroute + host: redpanda.example.com + hostTemplate: redpanda-$POD_ORDINAL-broker.example.com + tls: + enabled: false +---- . Create DNS records that resolve the bootstrap hostname and all per-broker hostnames to your Gateway's external address. A wildcard record such as `*.example.com` covers both. @@ -192,6 +355,36 @@ Check that each route's `status.parents` reports `Accepted: True` from your Gate ---- kubectl get tlsroute --namespace -o jsonpath='{.status.parents}' ---- ++ +.Example: what Redpanda creates for this listener +[%collapsible] +==== +Each TLSRoute attaches to your Gateway listener through `parentRefs`, matches one SNI hostname, and points at a Redpanda-created ClusterIP Service. The bootstrap route targets a Service that load-balances across all brokers (`-gateway-bootstrap`), and each per-broker route, such as `redpanda-kafka-default-0`, targets that broker's own Service (`gw--`): + +[,yaml] +---- +apiVersion: gateway.networking.k8s.io/v1 +kind: TLSRoute +metadata: + name: redpanda-kafka-default-bootstrap + namespace: +spec: + hostnames: + - redpanda.example.com # the SNI hostname that the Gateway matches + parentRefs: + - group: gateway.networking.k8s.io + kind: Gateway + name: redpanda-gateway + sectionName: kafka # the Gateway listener to attach to + rules: + - backendRefs: + - kind: Service + name: redpanda-gateway-bootstrap + port: 9094 # the Redpanda listener port, not the advertised port +---- + +The routes are identical in passthrough and termination modes. A TLSRoute describes only SNI-based routing to a backend Service; the TLS mode lives on the Gateway listener. +==== . Test the connection from outside the Kubernetes cluster: + @@ -204,6 +397,8 @@ rpk cluster info \ ---- + The broker list shows the per-broker hostnames with the advertised port. ++ +The CA to pass in `tls.ca` depends on the TLS mode: with passthrough, use the CA of the broker certificates; with termination, use the CA of the Gateway's certificate. == Route other listeners through the Gateway @@ -260,7 +455,7 @@ If any of these conditions fail, the Helm release or Redpanda resource fails wit == Troubleshooting -**Clients connect to the bootstrap hostname but fail on reconnect**: The per-broker hostnames don't resolve to the Gateway, or the broker certificates don't include them. Check your DNS records, and verify the certificate SANs: +*Clients connect to the bootstrap hostname but fail on reconnect*: The per-broker hostnames don't resolve to the Gateway, or the broker certificates don't include them. Check your DNS records, and verify the certificate SANs: [,bash] ---- @@ -268,11 +463,13 @@ kubectl get secret --namespace \ -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -text | grep DNS ---- -**TLSRoutes exist but have no `status`, and the Gateway reports `attachedRoutes: 0`**: Your Gateway controller isn't watching `TLSRoute` at the `v1` API that Redpanda uses. Controllers that watch only the deprecated `v1alpha2` version, such as Envoy Gateway 1.7 and earlier, cannot attach these routes, and the controller log shows a message such as `TLSRoute CRD not found, skipping TLSRoute watch`. Upgrade to a controller version that watches `TLSRoute` at `v1` (Envoy Gateway 1.8 or later). Installing the experimental channel CRDs or restarting the controller does not help on its own. See <>. +*TLSRoutes exist but have no `status`, and the Gateway reports `attachedRoutes: 0`*: Your Gateway controller isn't watching `TLSRoute` at the `v1` API that Redpanda uses. Controllers that watch only the deprecated `v1alpha2` version, such as Envoy Gateway 1.7 and earlier, cannot attach these routes, and the controller log shows a message such as `TLSRoute CRD not found, skipping TLSRoute watch`. Upgrade to a controller version that watches `TLSRoute` at `v1` (Envoy Gateway 1.8 or later). Installing the experimental channel CRDs or restarting the controller does not help on its own. See <>. + +*TLSRoutes have a `status.parents` entry but the route is not Accepted*: The route's `parentRefs` doesn't match the Gateway's name, namespace, or listener `sectionName`, or your Gateway controller doesn't support the listener's TLS mode for `TLSRoute`. Termination support is optional in the Gateway API specification; see <>. -**TLSRoutes have a `status.parents` entry but the route is not Accepted**: The Gateway listener isn't in `Passthrough` mode, or the route's `parentRefs` doesn't match the Gateway's name, namespace, or listener `sectionName`. +*Clients fail TLS certificate verification*: The client is validating against the wrong CA for the Gateway's TLS mode. With passthrough, clients must trust the CA of the broker certificates; with termination, they must trust the CA of the Gateway's certificate. -**Connection refused or routed to the wrong broker**: Verify that your client sends SNI. Connections without SNI (for example, plain TCP tools like `nc`) cannot be routed. Test with: +*Connection refused or routed to the wrong broker*: Verify that your client sends SNI. Connections without SNI (for example, plain TCP tools like `nc`) cannot be routed. Test with: [,bash] ---- @@ -288,3 +485,4 @@ include::shared:partial$suggested-reading.adoc[] * https://gateway-api.sigs.k8s.io/concepts/api-overview/[Gateway API overview^] * https://gateway-api.sigs.k8s.io/guides/tls/#tls-passthrough[Gateway API TLS passthrough^] +* https://gateway.envoyproxy.io/docs/tasks/security/tls-termination/[Envoy Gateway TLS termination^] From d83b0b9d0766af49165e7b617c43b7836e50343e Mon Sep 17 00:00:00 2001 From: JakeSCahill Date: Wed, 22 Jul 2026 15:06:07 +0100 Subject: [PATCH 12/14] docs: link to Gateway API and Envoy Gateway docs instead of restating details Reduce third-party maintenance burden while keeping the actionable facts: - Drop the Envoy Gateway <=1.7 CRD-detection internals; keep the version floor, the searchable log message, and the --skip-crds hint, and link to the Envoy Gateway installation guide - Reword termination support to be implementation-neutral with a link to the Envoy Gateway termination docs - Drop the CEL explanation from the Kubernetes prerequisite; link to the Gateway API versioning policy - Require a CRD release channel that includes TLSRoute (the standard channel does not ship it) and link to the release-channel docs - Make the GatewayClass step controller-neutral - Fix the Gateway API overview link, which moved under /docs/; verify all external URLs on the page resolve --- .../networking/external/k-gateway-api.adoc | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc index 9453e0baf9..10064049b8 100644 --- a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc +++ b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc @@ -46,7 +46,7 @@ The Gateway listener's `tls.mode` determines where TLS ends. Redpanda creates th |Gateway support |Supported by all `TLSRoute`-capable Gateway implementations. -|Optional in the Gateway API specification, so not all implementations support it. Envoy Gateway 1.8 or later does. +|Optional in the Gateway API specification. Requires an implementation that supports TLS termination for `TLSRoute`, such as https://gateway.envoyproxy.io/docs/tasks/security/tls-termination/[Envoy Gateway^] 1.8 or later. Check your implementation's documentation. |=== Choose passthrough unless you need to manage client-facing certificates centrally at the Gateway and can accept unencrypted traffic between the Gateway and the brokers. @@ -72,19 +72,17 @@ helm upgrade --install redpanda-operator redpanda/operator \ No published Redpanda Helm chart includes this feature yet. If you deploy with the Helm chart rather than the Operator, wait for the 26.2 chart release. ==== -* A xref:upgrade:k-compatibility.adoc#compatibility-matrix[supported Kubernetes version]. The Gateway API 1.5 CRDs use Common Expression Language (CEL) functions that API servers earlier than Kubernetes 1.31 cannot compile, so they fail to install on unsupported Kubernetes versions. +* A xref:upgrade:k-compatibility.adoc#compatibility-matrix[supported Kubernetes version]. The Gateway API 1.5 CRDs fail to install on API servers earlier than Kubernetes 1.31. For the version support policy, see the https://gateway-api.sigs.k8s.io/docs/concepts/versioning/[Gateway API versioning documentation^]. -* The https://gateway-api.sigs.k8s.io/[Gateway API^] CRDs, version 1.5 or later, installed in your Kubernetes cluster. Redpanda creates `TLSRoute` resources from the GA `gateway.networking.k8s.io/v1` API, which is available in Gateway API 1.5. +* The Gateway API CRDs, version 1.5 or later, installed from a https://gateway-api.sigs.k8s.io/docs/concepts/versioning/#release-channels[release channel^] that includes `TLSRoute`. Redpanda creates `TLSRoute` resources from the GA `gateway.networking.k8s.io/v1` API, which is available in Gateway API 1.5. For installation steps, see the https://gateway-api.sigs.k8s.io/guides/[Gateway API getting started guide^]. * A Gateway controller that supports `TLSRoute`, such as Envoy Gateway or Istio. Redpanda does not create the Gateway resource. See <>. + [NOTE] ==== -Use a controller version that watches `TLSRoute` at the GA `gateway.networking.k8s.io/v1` API, because Redpanda creates its routes at `v1`. For Envoy Gateway, this means version 1.8 or later. +Use a controller version that watches `TLSRoute` at the GA `gateway.networking.k8s.io/v1` API, because Redpanda creates its routes at `v1`. For Envoy Gateway, this means version 1.8 or later: earlier versions log `TLSRoute CRD not found, skipping TLSRoute watch` and never attach the routes. -Envoy Gateway 1.7 and earlier watch the deprecated `v1alpha2` version and detect the `TLSRoute` CRD only at its server-preferred version. Because Gateway API 1.5 makes `v1` the preferred (storage) version of `TLSRoute`, these earlier controllers log `TLSRoute CRD not found, skipping TLSRoute watch` and never attach the routes, even when the *experimental* channel CRDs serve `v1alpha2` alongside `v1`. Upgrading the controller is the reliable fix; installing the experimental channel alone does not resolve it. - -Install the controller without its bundled Gateway API CRDs (for example, `helm install --skip-crds` for Envoy Gateway) so it uses your Gateway API 1.5 CRDs rather than replacing them with an older bundled version. +If your controller bundles its own Gateway API CRDs, install it without them (for example, `helm install --skip-crds` for Envoy Gateway) so it uses your Gateway API 1.5 CRDs. For installation details, see your controller's documentation, such as the https://gateway.envoyproxy.io/docs/install/[Envoy Gateway installation guide^]. ==== * TLS between clients and the Gateway. The Gateway routes connections by SNI, which requires clients to connect with TLS in both modes. With passthrough, enable TLS on every Redpanda listener that you route through the Gateway; if you use xref:manage:kubernetes/security/tls/k-cert-manager.adoc[cert-manager-managed certificates], Redpanda automatically adds the bootstrap and per-broker hostnames to the certificate's Subject Alternative Names (SANs). With termination, the Gateway presents its own certificate instead. See <>. @@ -97,7 +95,7 @@ Install the controller without its bundled Gateway API CRDs (for example, `helm Redpanda attaches its TLSRoutes to a Gateway that you deploy and manage. -. If your Gateway controller does not create a GatewayClass, create one. For example, Envoy Gateway does not ship a default GatewayClass: +. If your Gateway controller does not create a GatewayClass, create one. Get the `controllerName` value from your controller's documentation. For example, for Envoy Gateway: + [,yaml] ---- @@ -463,7 +461,7 @@ kubectl get secret --namespace \ -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -text | grep DNS ---- -*TLSRoutes exist but have no `status`, and the Gateway reports `attachedRoutes: 0`*: Your Gateway controller isn't watching `TLSRoute` at the `v1` API that Redpanda uses. Controllers that watch only the deprecated `v1alpha2` version, such as Envoy Gateway 1.7 and earlier, cannot attach these routes, and the controller log shows a message such as `TLSRoute CRD not found, skipping TLSRoute watch`. Upgrade to a controller version that watches `TLSRoute` at `v1` (Envoy Gateway 1.8 or later). Installing the experimental channel CRDs or restarting the controller does not help on its own. See <>. +*TLSRoutes exist but have no `status`, and the Gateway reports `attachedRoutes: 0`*: Your Gateway controller isn't watching `TLSRoute` at the `v1` API that Redpanda uses, and its log shows a message such as `TLSRoute CRD not found, skipping TLSRoute watch`. Upgrade to a controller version that watches `TLSRoute` at `v1` (for Envoy Gateway, version 1.8 or later). Restarting the controller does not help on its own. See <>. *TLSRoutes have a `status.parents` entry but the route is not Accepted*: The route's `parentRefs` doesn't match the Gateway's name, namespace, or listener `sectionName`, or your Gateway controller doesn't support the listener's TLS mode for `TLSRoute`. Termination support is optional in the Gateway API specification; see <>. @@ -483,6 +481,6 @@ openssl s_client -connect :443 -servername redpanda.example.com include::shared:partial$suggested-reading.adoc[] -* https://gateway-api.sigs.k8s.io/concepts/api-overview/[Gateway API overview^] +* https://gateway-api.sigs.k8s.io/docs/concepts/api-overview/[Gateway API overview^] * https://gateway-api.sigs.k8s.io/guides/tls/#tls-passthrough[Gateway API TLS passthrough^] * https://gateway.envoyproxy.io/docs/tasks/security/tls-termination/[Envoy Gateway TLS termination^] From 18d30e29b87f485a07cd636e997dbaa8a566d162 Mon Sep 17 00:00:00 2001 From: JakeSCahill Date: Wed, 22 Jul 2026 15:21:48 +0100 Subject: [PATCH 13/14] docs: apply standards review fixes to Gateway API page - Add page-topic-type, personas, and learning objectives - Spell out SANs, CA, and GA at first use - Remove directional 'above' reference - Use the established Kafka listener hostnames in the multi-listener example - Rework a weak-verb section opener and add missing section intros - Rename Troubleshooting to Troubleshoot and link the central troubleshooting page, matching sibling pages --- .../networking/external/k-gateway-api.adoc | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc index 10064049b8..9db30d52e8 100644 --- a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc +++ b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc @@ -4,11 +4,22 @@ :tags: ["Kubernetes", "Helm configuration"] :page-categories: Management, Networking :env-kubernetes: true +:page-topic-type: how-to +:personas: platform_operator, platform_engineer +:learning-objective-1: Choose between TLS passthrough and TLS termination for Gateway-routed listeners +:learning-objective-2: Deploy a Gateway and configure Redpanda listeners to route through it +:learning-objective-3: Diagnose TLSRoute and Gateway connectivity failures Expose your Redpanda cluster to external clients through a single https://gateway-api.sigs.k8s.io/[Gateway API^] entry point instead of NodePort or LoadBalancer Services. Clients connect to one static Gateway address, and the Gateway routes each connection to the right broker using TLS Server Name Indication (SNI), so you avoid per-broker LoadBalancers and node port management. This feature is in beta. The configuration surface (`external.gateway` and the per-listener `type` field) may change before general availability. Beta features are not recommended for production environments. To give feedback, reach out to the Redpanda team in https://redpanda.com/slack[Redpanda Community Slack^]. +After reading this page, you will be able to: + +* [ ] {learning-objective-1} +* [ ] {learning-objective-2} +* [ ] {learning-objective-3} + == How it works You bring your own Gateway: deploy a Gateway API implementation that supports `TLSRoute`, and create a Gateway resource with a TLS listener (see <>). Redpanda then creates the routing configuration for you: @@ -37,7 +48,7 @@ The Gateway listener's `tls.mode` determines where TLS ends. Redpanda creates th |TLS ends at the Gateway. Traffic between the Gateway and the brokers is unencrypted. |Certificates -|The broker certificates must include the bootstrap and per-broker hostnames. Redpanda adds these SANs automatically to xref:manage:kubernetes/security/tls/k-cert-manager.adoc[cert-manager-managed certificates]. +|The broker certificates must include the bootstrap and per-broker hostnames. Redpanda adds these Subject Alternative Names (SANs) automatically to xref:manage:kubernetes/security/tls/k-cert-manager.adoc[cert-manager-managed certificates]. |One certificate on the Gateway covers all hostnames. The broker certificates are not involved. |Client authentication @@ -74,7 +85,7 @@ No published Redpanda Helm chart includes this feature yet. If you deploy with t * A xref:upgrade:k-compatibility.adoc#compatibility-matrix[supported Kubernetes version]. The Gateway API 1.5 CRDs fail to install on API servers earlier than Kubernetes 1.31. For the version support policy, see the https://gateway-api.sigs.k8s.io/docs/concepts/versioning/[Gateway API versioning documentation^]. -* The Gateway API CRDs, version 1.5 or later, installed from a https://gateway-api.sigs.k8s.io/docs/concepts/versioning/#release-channels[release channel^] that includes `TLSRoute`. Redpanda creates `TLSRoute` resources from the GA `gateway.networking.k8s.io/v1` API, which is available in Gateway API 1.5. For installation steps, see the https://gateway-api.sigs.k8s.io/guides/[Gateway API getting started guide^]. +* The Gateway API CRDs, version 1.5 or later, installed from a https://gateway-api.sigs.k8s.io/docs/concepts/versioning/#release-channels[release channel^] that includes `TLSRoute`. Redpanda creates `TLSRoute` resources from the generally available (GA) `gateway.networking.k8s.io/v1` API, which is available in Gateway API 1.5. For installation steps, see the https://gateway-api.sigs.k8s.io/guides/[Gateway API getting started guide^]. * A Gateway controller that supports `TLSRoute`, such as Envoy Gateway or Istio. Redpanda does not create the Gateway resource. See <>. + @@ -85,7 +96,7 @@ Use a controller version that watches `TLSRoute` at the GA `gateway.networking.k If your controller bundles its own Gateway API CRDs, install it without them (for example, `helm install --skip-crds` for Envoy Gateway) so it uses your Gateway API 1.5 CRDs. For installation details, see your controller's documentation, such as the https://gateway.envoyproxy.io/docs/install/[Envoy Gateway installation guide^]. ==== -* TLS between clients and the Gateway. The Gateway routes connections by SNI, which requires clients to connect with TLS in both modes. With passthrough, enable TLS on every Redpanda listener that you route through the Gateway; if you use xref:manage:kubernetes/security/tls/k-cert-manager.adoc[cert-manager-managed certificates], Redpanda automatically adds the bootstrap and per-broker hostnames to the certificate's Subject Alternative Names (SANs). With termination, the Gateway presents its own certificate instead. See <>. +* TLS between clients and the Gateway. The Gateway routes connections by SNI, which requires clients to connect with TLS in both modes. With passthrough, enable TLS on every Redpanda listener that you route through the Gateway; if you use xref:manage:kubernetes/security/tls/k-cert-manager.adoc[cert-manager-managed certificates], Redpanda automatically adds the bootstrap and per-broker hostnames to the certificate's SANs. With termination, the Gateway presents its own certificate instead. See <>. * Control over DNS for your chosen hostnames. The bootstrap hostname and all per-broker hostnames must resolve to the Gateway's external address. @@ -209,6 +220,8 @@ The listener reports `Accepted=True` and `Programmed=True`. The Gateway's extern == Configure Redpanda listeners for the Gateway +Opt each external listener into Gateway routing and point Redpanda at the Gateway you deployed. + . Enable gateway mode and reference your Gateway. + [tabs] @@ -335,7 +348,7 @@ kubectl get tlsroutes --namespace \ -o custom-columns='NAME:.metadata.name,HOSTNAMES:.spec.hostnames' ---- + -NOTE: Plain `kubectl get tlsroutes` prints only the `NAME` and `AGE` columns. Use the `custom-columns` output above (or `-o yaml`) to see the hostnames. +NOTE: Plain `kubectl get tlsroutes` prints only the `NAME` and `AGE` columns. Use this command's `custom-columns` output (or `-o yaml`) to see the hostnames. + For a three-broker cluster named `redpanda`, expect a bootstrap route and one route per broker: + @@ -396,11 +409,11 @@ rpk cluster info \ + The broker list shows the per-broker hostnames with the advertised port. + -The CA to pass in `tls.ca` depends on the TLS mode: with passthrough, use the CA of the broker certificates; with termination, use the CA of the Gateway's certificate. +The certificate authority (CA) to pass in `tls.ca` depends on the TLS mode: with passthrough, use the CA of the broker certificates; with termination, use the CA of the Gateway's certificate. == Route other listeners through the Gateway -The HTTP Proxy, Admin API, and Schema Registry listeners support `type: tlsroute` with the same `host` field. For these listeners, `hostTemplate` is optional: without it, Redpanda creates only the bootstrap route, and the Gateway load-balances requests across brokers. Give each listener a unique hostname: +You can route the HTTP Proxy, Admin API, and Schema Registry listeners through the same Gateway with `type: tlsroute` and the same `host` field. For these listeners, `hostTemplate` is optional: without it, Redpanda creates only the bootstrap route, and the Gateway load-balances requests across brokers. Give each listener a unique hostname: [,yaml] ---- @@ -410,8 +423,8 @@ listeners: default: port: 9094 type: tlsroute - host: kafka.example.com - hostTemplate: kafka-$POD_ORDINAL.example.com + host: redpanda.example.com + hostTemplate: redpanda-$POD_ORDINAL-broker.example.com tls: cert: default http: @@ -451,7 +464,9 @@ Redpanda refuses to render configurations that would silently break connectivity If any of these conditions fail, the Helm release or Redpanda resource fails with an error that names the listener. -== Troubleshooting +== Troubleshoot + +Here are some common troubleshooting scenarios and their solutions. For more troubleshooting steps, see xref:manage:kubernetes/troubleshooting/k-troubleshoot.adoc[]. *Clients connect to the bootstrap hostname but fail on reconnect*: The per-broker hostnames don't resolve to the Gateway, or the broker certificates don't include them. Check your DNS records, and verify the certificate SANs: From 2670f4302ba300ae98e1ad16e327698b3434ba14 Mon Sep 17 00:00:00 2001 From: JakeSCahill Date: Wed, 22 Jul 2026 18:03:17 +0100 Subject: [PATCH 14/14] docs: prefer separate sentences over semicolons --- .../kubernetes/networking/external/k-gateway-api.adoc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc index 9db30d52e8..d86cb63a5b 100644 --- a/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc +++ b/modules/manage/pages/kubernetes/networking/external/k-gateway-api.adoc @@ -96,7 +96,7 @@ Use a controller version that watches `TLSRoute` at the GA `gateway.networking.k If your controller bundles its own Gateway API CRDs, install it without them (for example, `helm install --skip-crds` for Envoy Gateway) so it uses your Gateway API 1.5 CRDs. For installation details, see your controller's documentation, such as the https://gateway.envoyproxy.io/docs/install/[Envoy Gateway installation guide^]. ==== -* TLS between clients and the Gateway. The Gateway routes connections by SNI, which requires clients to connect with TLS in both modes. With passthrough, enable TLS on every Redpanda listener that you route through the Gateway; if you use xref:manage:kubernetes/security/tls/k-cert-manager.adoc[cert-manager-managed certificates], Redpanda automatically adds the bootstrap and per-broker hostnames to the certificate's SANs. With termination, the Gateway presents its own certificate instead. See <>. +* TLS between clients and the Gateway. The Gateway routes connections by SNI, which requires clients to connect with TLS in both modes. With passthrough, enable TLS on every Redpanda listener that you route through the Gateway. If you use xref:manage:kubernetes/security/tls/k-cert-manager.adoc[cert-manager-managed certificates], Redpanda automatically adds the bootstrap and per-broker hostnames to the certificate's SANs. With termination, the Gateway presents its own certificate instead. See <>. * Control over DNS for your chosen hostnames. The bootstrap hostname and all per-broker hostnames must resolve to the Gateway's external address. @@ -394,7 +394,7 @@ spec: port: 9094 # the Redpanda listener port, not the advertised port ---- -The routes are identical in passthrough and termination modes. A TLSRoute describes only SNI-based routing to a backend Service; the TLS mode lives on the Gateway listener. +The routes are identical in passthrough and termination modes. A TLSRoute describes only SNI-based routing to a backend Service. The TLS mode lives on the Gateway listener. ==== . Test the connection from outside the Kubernetes cluster: @@ -409,7 +409,7 @@ rpk cluster info \ + The broker list shows the per-broker hostnames with the advertised port. + -The certificate authority (CA) to pass in `tls.ca` depends on the TLS mode: with passthrough, use the CA of the broker certificates; with termination, use the CA of the Gateway's certificate. +The certificate authority (CA) to pass in `tls.ca` depends on the TLS mode. With passthrough, use the CA of the broker certificates. With termination, use the CA of the Gateway's certificate. == Route other listeners through the Gateway @@ -478,9 +478,9 @@ kubectl get secret --namespace \ *TLSRoutes exist but have no `status`, and the Gateway reports `attachedRoutes: 0`*: Your Gateway controller isn't watching `TLSRoute` at the `v1` API that Redpanda uses, and its log shows a message such as `TLSRoute CRD not found, skipping TLSRoute watch`. Upgrade to a controller version that watches `TLSRoute` at `v1` (for Envoy Gateway, version 1.8 or later). Restarting the controller does not help on its own. See <>. -*TLSRoutes have a `status.parents` entry but the route is not Accepted*: The route's `parentRefs` doesn't match the Gateway's name, namespace, or listener `sectionName`, or your Gateway controller doesn't support the listener's TLS mode for `TLSRoute`. Termination support is optional in the Gateway API specification; see <>. +*TLSRoutes have a `status.parents` entry but the route is not Accepted*: The route's `parentRefs` doesn't match the Gateway's name, namespace, or listener `sectionName`, or your Gateway controller doesn't support the listener's TLS mode for `TLSRoute`. Termination support is optional in the Gateway API specification. See <>. -*Clients fail TLS certificate verification*: The client is validating against the wrong CA for the Gateway's TLS mode. With passthrough, clients must trust the CA of the broker certificates; with termination, they must trust the CA of the Gateway's certificate. +*Clients fail TLS certificate verification*: The client is validating against the wrong CA for the Gateway's TLS mode. With passthrough, clients must trust the CA of the broker certificates. With termination, they must trust the CA of the Gateway's certificate. *Connection refused or routed to the wrong broker*: Verify that your client sends SNI. Connections without SNI (for example, plain TCP tools like `nc`) cannot be routed. Test with: