Skip to content

Commit f833385

Browse files
authored
Merge pull request #275 from girish332/operator-gateway-api
Publish Doc on integrating envoy gateway with k8s operator
2 parents 089e8f4 + 52ce50d commit f833385

1 file changed

Lines changed: 354 additions & 0 deletions

File tree

Lines changed: 354 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,354 @@
1+
# How to integrate Envoy Gateway with TigerGraph
2+
3+
TigerGraph clusters can be exposed using the Kubernetes Gateway API with Envoy Gateway. This guide covers setting up Envoy Gateway with E2E TLS and mTLS for TigerGraph clusters.
4+
5+
- [How to integrate Envoy Gateway with TigerGraph](#how-to-integrate-envoy-gateway-with-tigergraph)
6+
- [Prerequisites](#prerequisites)
7+
- [Step 1: Install Envoy Gateway](#step-1-install-envoy-gateway)
8+
- [Step 2: Generate Certificates and Create Secrets](#step-2-generate-certificates-and-create-secrets)
9+
- [Step 3: Deploy TigerGraph with TLS](#step-3-deploy-tigergraph-with-tls)
10+
- [Step 4: Create Gateway and GatewayClass](#step-4-create-gateway-and-gatewayclass)
11+
- [Step 5: Create Backend with E2E TLS](#step-5-create-backend-with-e2e-tls)
12+
- [Step 6: Create HTTPRoute](#step-6-create-httproute)
13+
- [Step 7: Verify](#step-7-verify)
14+
- [Migrating from nginx Ingress](#migrating-from-nginx-ingress)
15+
- [Troubleshooting](#troubleshooting)
16+
17+
## Prerequisites
18+
19+
- TigerGraph 4.2.0 or later for TLS, 4.3.0 or later for mTLS
20+
- Kubernetes 1.30 or later (validated versions: 1.30 - 1.34, see [version compatibility](../01-introduction/README.md)). Minimum 1.30 is required by both the Operator and Envoy Gateway v1.6.x.
21+
- Envoy Gateway v1.6.3 or later
22+
- `kubectl`, `helm`, and `openssl` installed
23+
- A running TigerGraph cluster (see [Get Started](../02-get-started/get_started.md))
24+
25+
## Step 1: Install Envoy Gateway
26+
27+
Ensure your Envoy Gateway version is compatible with your Kubernetes version. Refer to the [Envoy Gateway compatibility matrix](https://gateway.envoyproxy.io/news/releases/matrix/) for supported combinations:
28+
29+
| Envoy Gateway | Kubernetes validated versions |
30+
| ------------- | ----------------------------- |
31+
| v1.6.x | 1.30, 1.31, 1.32, 1.33 |
32+
| v1.7.x | 1.32, 1.33, 1.34, 1.35 |
33+
34+
Install the CRDs and controller:
35+
36+
```bash
37+
# Install CRDs
38+
helm pull oci://docker.io/envoyproxy/gateway-crds-helm --version v1.6.3 --untar
39+
helm template eg-crds gateway-crds-helm \
40+
--set crds.gatewayAPI.enabled=true \
41+
--set crds.gatewayAPI.channel=experimental \
42+
--set crds.envoyGateway.enabled=true \
43+
| kubectl apply --server-side -f -
44+
45+
# Install controller
46+
helm install eg oci://docker.io/envoyproxy/gateway-helm \
47+
--version v1.6.3 \
48+
--skip-crds \
49+
-n envoy-gateway-system --create-namespace \
50+
--set config.envoyGateway.extensionApis.enableBackend=true
51+
```
52+
53+
Wait for the controller to be ready:
54+
55+
```bash
56+
kubectl wait --timeout=5m -n envoy-gateway-system \
57+
deployment/envoy-gateway --for=condition=Available
58+
```
59+
60+
> [!IMPORTANT]
61+
> Use Envoy Gateway v1.6.3 or later. Earlier versions have a [known bug](https://github.com/envoyproxy/gateway/pull/7987) with `clientCertificateRef` namespace resolution. The `enableBackend=true` flag is required for backend TLS configuration.
62+
63+
## Step 2: Generate Certificates and Create Secrets
64+
65+
Generate SSL certificates and create Kubernetes secrets as described in [Configure Nginx TLS](../03-deploy/configure-nginx-tls.md). For mTLS (TigerGraph 4.3.0+), also follow the [Configure Nginx mTLS](../03-deploy/configure-nginx-tls.md#configure-nginx-mtls) section.
66+
67+
Additionally, create a client certificate secret for the Gateway to present to TG during mTLS:
68+
69+
```bash
70+
kubectl create secret tls tg-gateway-client-cert \
71+
--cert=<client-cert-file> --key=<client-key-file> -n tigergraph
72+
```
73+
74+
> [!NOTE]
75+
> The `tg-gateway-client-cert` secret is only required for mTLS (4.3.0+). For TLS only, the server TLS secret is sufficient. If you do not need TLS at all, skip this step and Step 3.
76+
77+
## Step 3: Deploy TigerGraph with TLS
78+
79+
Configure TLS for TigerGraph's internal NGINX as described in [Configure Nginx TLS](../03-deploy/configure-nginx-tls.md). Use `nginxConfig` (recommended) or `postInitAction` if you need additional gadmin settings beyond SSL (e.g., RESTPP authentication, audit logging).
80+
81+
Deploy the cluster with `listener.type: ClusterIP` since all external routing will be handled by the Gateway API:
82+
83+
```yaml
84+
listener:
85+
type: ClusterIP
86+
nginxConfig:
87+
secretName: tg-server-tls # Server certificate for TLS
88+
clientCertSecretName: tg-ca-cert # CA certificate for mTLS verification (4.3.0+ only)
89+
```
90+
91+
> [!IMPORTANT]
92+
> When using `postInitAction`, you must restart `restpp`, `gsql`, `nginx`, and `gui` after applying the config. Restarting only `nginx` will break GUI authentication.
93+
94+
> [!NOTE]
95+
> Operator versions prior to 1.7.1 have a bug that prevents creating clusters with `listener.type: ClusterIP` directly. This has been resolved in 1.7.1. If you are on an older version, deploy with `listener.type: LoadBalancer` first, then patch to `ClusterIP`:
96+
> `kubectl patch tigergraph test-cluster -n tigergraph --type merge -p '{"spec":{"listener":{"type":"ClusterIP"}}}'`
97+
98+
Verify TLS is working before proceeding:
99+
100+
```bash
101+
kubectl exec test-cluster-0 -n tigergraph -- curl -ks https://localhost:14240/restpp/echo
102+
# Expected: {"error":false, "message":"Hello GSQL"}
103+
104+
kubectl exec test-cluster-0 -n tigergraph -- \
105+
curl -ks https://localhost:14240/api/auth/login \
106+
-H 'Content-Type: application/json' \
107+
-d '{"username":"tigergraph","password":"tigergraph"}'
108+
# Expected: {"error":false, ...}
109+
```
110+
111+
Verify the service is ClusterIP:
112+
113+
```bash
114+
kubectl get svc test-cluster-nginx-external-service -n tigergraph
115+
# TYPE should be ClusterIP, EXTERNAL-IP should be <none>
116+
```
117+
118+
## Step 4: Create Gateway and GatewayClass
119+
120+
The `GatewayClass` defines which controller handles Gateway resources. The `Gateway` defines the external entry point with HTTPS and an HTTP-to-HTTPS redirect.
121+
122+
```yaml
123+
apiVersion: gateway.networking.k8s.io/v1
124+
kind: GatewayClass
125+
metadata:
126+
name: eg
127+
spec:
128+
controllerName: gateway.envoyproxy.io/gatewayclass-controller
129+
---
130+
apiVersion: gateway.networking.k8s.io/v1
131+
kind: Gateway
132+
metadata:
133+
name: tg-gateway
134+
namespace: tigergraph
135+
spec:
136+
gatewayClassName: eg
137+
listeners:
138+
- name: https
139+
protocol: HTTPS
140+
port: 443
141+
tls:
142+
mode: Terminate
143+
certificateRefs:
144+
- kind: Secret
145+
name: tg-server-tls
146+
allowedRoutes:
147+
namespaces:
148+
from: Same
149+
- name: http
150+
protocol: HTTP
151+
port: 80
152+
allowedRoutes:
153+
namespaces:
154+
from: Same
155+
```
156+
157+
Wait for the Gateway to receive an external address:
158+
159+
```bash
160+
kubectl get gateway tg-gateway -n tigergraph -w
161+
# Wait until ADDRESS is populated and PROGRAMMED: True
162+
```
163+
164+
> [!NOTE]
165+
> On AWS, ELB DNS propagation can take 2-5 minutes.
166+
167+
## Step 5: Create Backend with E2E TLS
168+
169+
The `Backend` resource configures how Envoy connects to TG's NGINX over HTTPS.
170+
171+
### TLS Only (TigerGraph 4.2.0+)
172+
173+
```yaml
174+
apiVersion: gateway.envoyproxy.io/v1alpha1
175+
kind: Backend
176+
metadata:
177+
name: tg-backend
178+
namespace: tigergraph
179+
spec:
180+
endpoints:
181+
- fqdn:
182+
hostname: test-cluster-nginx-external-service.tigergraph.svc.cluster.local
183+
port: 14240
184+
tls:
185+
caCertificateRefs:
186+
- group: ""
187+
kind: Secret
188+
name: tg-ca-cert
189+
sni: your-domain.com
190+
```
191+
192+
### E2E mTLS (TigerGraph 4.3.0+)
193+
194+
If TG has mTLS enabled (`nginxConfig.clientCertSecretName`), the Gateway must also present a client certificate:
195+
196+
```yaml
197+
apiVersion: gateway.envoyproxy.io/v1alpha1
198+
kind: Backend
199+
metadata:
200+
name: tg-backend
201+
namespace: tigergraph
202+
spec:
203+
endpoints:
204+
- fqdn:
205+
hostname: test-cluster-nginx-external-service.tigergraph.svc.cluster.local
206+
port: 14240
207+
tls:
208+
caCertificateRefs:
209+
- group: ""
210+
kind: Secret
211+
name: tg-ca-cert
212+
clientCertificateRef:
213+
group: ""
214+
kind: Secret
215+
name: tg-gateway-client-cert
216+
sni: your-domain.com
217+
```
218+
219+
* `caCertificateRefs` — Envoy verifies TG's server certificate against this CA
220+
* `clientCertificateRef` — Envoy presents this certificate to TG's NGINX for mTLS (4.3.0+ only)
221+
* `sni` — must match the CN or SAN in the server certificate
222+
223+
> [!IMPORTANT]
224+
> All secrets must be in the same namespace as the Backend resource.
225+
226+
### Without TLS
227+
228+
If TigerGraph does not have TLS enabled, you can skip the `Backend` resource and reference the Service directly in the HTTPRoute (see Step 6).
229+
230+
## Step 6: Create HTTPRoute
231+
232+
Route HTTPS traffic to the TG backend and redirect HTTP to HTTPS:
233+
234+
### With Backend (TLS/mTLS enabled)
235+
236+
```yaml
237+
apiVersion: gateway.networking.k8s.io/v1
238+
kind: HTTPRoute
239+
metadata:
240+
name: tg-route
241+
namespace: tigergraph
242+
spec:
243+
parentRefs:
244+
- name: tg-gateway
245+
sectionName: https
246+
rules:
247+
- matches:
248+
- path:
249+
type: PathPrefix
250+
value: /
251+
backendRefs:
252+
- group: gateway.envoyproxy.io
253+
kind: Backend
254+
name: tg-backend
255+
---
256+
apiVersion: gateway.networking.k8s.io/v1
257+
kind: HTTPRoute
258+
metadata:
259+
name: tg-http-redirect
260+
namespace: tigergraph
261+
spec:
262+
parentRefs:
263+
- name: tg-gateway
264+
sectionName: http
265+
rules:
266+
- filters:
267+
- type: RequestRedirect
268+
requestRedirect:
269+
scheme: https
270+
statusCode: 301
271+
```
272+
273+
### Without TLS (plain HTTP)
274+
275+
If TigerGraph does not have TLS enabled, the HTTPRoute can reference the ClusterIP Service directly without a Backend resource:
276+
277+
```yaml
278+
apiVersion: gateway.networking.k8s.io/v1
279+
kind: HTTPRoute
280+
metadata:
281+
name: tg-route
282+
namespace: tigergraph
283+
spec:
284+
parentRefs:
285+
- name: tg-gateway
286+
rules:
287+
- matches:
288+
- path:
289+
type: PathPrefix
290+
value: /
291+
backendRefs:
292+
- name: test-cluster-nginx-external-service
293+
port: 14240
294+
```
295+
296+
## Step 7: Verify
297+
298+
```bash
299+
export GATEWAY_IP=$(kubectl get gateway tg-gateway -n tigergraph \
300+
-o jsonpath='{.status.addresses[0].value}')
301+
302+
# HTTPS works
303+
curl -k https://$GATEWAY_IP/restpp/echo
304+
# Expected: {"error":false, "message":"Hello GSQL"}
305+
306+
# HTTP redirects to HTTPS
307+
curl -v http://$GATEWAY_IP/restpp/echo 2>&1 | grep "301\|location"
308+
309+
# GUI login works through the Gateway
310+
curl -k https://$GATEWAY_IP/api/auth/login \
311+
-H 'Content-Type: application/json' \
312+
-d '{"username":"<replace-username>","password":"<replace-password>"}'
313+
```
314+
315+
## Migrating from nginx Ingress
316+
317+
For existing clusters using `listener.type: Ingress` with the nginx Ingress Controller:
318+
319+
1. Install Envoy Gateway alongside existing nginx (Step 1) — no impact to production traffic
320+
2. Create Gateway and HTTPRoute (Steps 4-6) — new routing path, not yet serving traffic
321+
3. Validate using `curl --resolve` to test through the Gateway without changing DNS
322+
4. Switch TG CR from `Ingress` to `ClusterIP` — operator deletes the Ingress resource
323+
5. Update DNS to point to the Envoy Gateway's address — traffic switches to new path
324+
6. Decommission nginx Ingress Controller once DNS has fully propagated
325+
326+
> [!NOTE]
327+
> If the existing cluster does not use TLS, skip Steps 2, 3, and 5 (Backend). The HTTPRoute can reference the ClusterIP Service directly (see "Without TLS" in Step 6).
328+
329+
## Troubleshooting
330+
331+
**Gateway has no ADDRESS:**
332+
Check Envoy Gateway controller logs and verify the GatewayClass is accepted:
333+
```bash
334+
kubectl logs -n envoy-gateway-system deployment/envoy-gateway --tail=20
335+
kubectl get gatewayclass eg
336+
```
337+
338+
**HTTPRoute not Accepted:**
339+
Verify `parentRefs.name` matches the Gateway name and the Gateway's `allowedRoutes` permits the namespace.
340+
341+
**Backend shows `InvalidBackendRef`:**
342+
Ensure `enableBackend=true` was set during Envoy Gateway installation. Check the HTTPRoute status:
343+
```bash
344+
kubectl describe httproute tg-route -n tigergraph
345+
```
346+
347+
**`clientCertificateRef` namespace error:**
348+
Upgrade to Envoy Gateway v1.6.3 or later. All secrets must be in the same namespace as the Backend.
349+
350+
**`Forbidden: Client certificate verification failed`:**
351+
The client certificate is not signed by the CA configured in `clientCertSecretName`. Verify:
352+
```bash
353+
openssl verify -CAfile ca-cert.pem client-cert.pem
354+
```

0 commit comments

Comments
 (0)