@@ -7,16 +7,24 @@ This example demonstrates how to use NGINX Gateway Fabric to route traffic to ex
77In this example, we will:
88
991 . Deploy NGINX Gateway Fabric with DNS resolver configuration
10- 2 . Create an ExternalName service pointing to an external API
11- 3 . Configure HTTP and TLS routes to route traffic to this external service
12- 4 . Test both HTTP and TLS routing functionality
10+ 2 . Create an ExternalName service pointing to an external API (httpbin.org)
11+ 3 . Deploy an internal service (coffee) to demonstrate mixed routing
12+ 4 . Configure an HTTPRoute that routes to both external and internal services
13+ 5 . (Optional) Configure BackendTLSPolicy for HTTPS connections to external services
14+ 6 . Test HTTP routing with both external and internal services
15+ 7 . (Optional) Test HTTPS backend connections and TLS passthrough
1316
1417## Running the Example
1518
1619## 1. Deploy NGINX Gateway Fabric
1720
18211 . Follow the [ installation instructions] ( https://docs.nginx.com/nginx-gateway-fabric/install/ ) to deploy NGINX Gateway Fabric.
1922
23+ ** Note** : To use BackendTLSPolicy or TLSRoute for HTTPS connections to external services, you must:
24+
25+ - Install NGINX Gateway Fabric with ` enableExperimental=true `
26+ - Install the experimental Gateway APIs on the cluster
27+
2028## 2. Deploy the Gateway with DNS Resolver
2129
2230Create the Gateway and NginxProxy configuration that enables DNS resolution for ExternalName services:
@@ -30,30 +38,64 @@ This creates:
3038- A Gateway with HTTP and TLS listeners
3139- An NginxProxy resource with DNS resolver configuration
3240
33- ## 3. Deploy ExternalName Services
41+ ## 3. Deploy Services
3442
35- Create the ExternalName service that points to external APIs :
43+ Create the ExternalName service and internal service :
3644
3745``` shell
38- kubectl apply -f external-service .yaml
46+ kubectl apply -f cafe .yaml
3947```
4048
41- This creates an ExternalName service which points to ` httpbin.org ` with both HTTP and HTTPS ports
49+ This creates:
50+
51+ - An ExternalName service which points to ` httpbin.org ` with both HTTP and HTTPS ports
52+ - A coffee deployment and service for internal routing
4253
4354## 4. Configure Routing
4455
45- Create the HTTPRoute and TLSRoute that route traffic to the external service :
56+ Create the HTTPRoute and TLSRoute that route traffic to the services :
4657
4758``` shell
4859kubectl apply -f route.yaml
4960```
5061
5162This creates:
5263
53- - An HTTPRoute that routes HTTP traffic to the httpbin service
54- - A TLSRoute that routes TLS traffic to the httpbin service
64+ - An HTTPRoute with two paths:
65+ - ` /external/* ` - Routes to the ExternalName service (httpbin.org) with a URLRewrite filter that strips the ` /external ` prefix
66+ - ` /coffee ` - Routes to the internal coffee service
67+ - A TLSRoute for TLS passthrough to the external httpbin service (commented out by default)
68+
69+ ## 5. (Optional) Configure HTTPS Backend
70+
71+ If your external service requires HTTPS connections (like ` https://httpbin.org ` ), you need to:
72+
73+ 1 . Update the HTTPRoute to use port 443 for the httpbin service in ` route.yaml ` :
74+
75+ ``` yaml
76+ backendRefs :
77+ - name : httpbin
78+ port : 443 # Change from 80 to 443
79+ ` ` `
5580
56- ## 5. Test the Configuration
81+ 2. Create a BackendTLSPolicy:
82+
83+ ` ` ` shell
84+ kubectl apply -f backendtlspolicy.yaml
85+ ```
86+
87+ This configures NGINX Gateway Fabric to:
88+
89+ - Establish TLS connections to the backend service
90+ - Verify the backend's TLS certificate using system CA certificates
91+ - Match the certificate's hostname against the external service hostname
92+
93+ ** Note** : BackendTLSPolicy is different from TLSRoute:
94+
95+ - ** BackendTLSPolicy** : NGF terminates client TLS/HTTP and establishes HTTPS to the backend. Allows HTTP-level routing (paths, headers, etc.)
96+ - ** TLSRoute** : TLS passthrough where the client establishes TLS directly with the backend. No HTTP-level routing possible.
97+
98+ ## 6. Test the Configuration
5799
58100Wait for the Gateway to be ready:
59101
@@ -66,43 +108,106 @@ Save the public IP address and ports of the NGINX Service into shell variables:
66108``` text
67109GW_IP=XXX.YYY.ZZZ.III
68110GW_PORT_HTTP=<port number>
69- GW_PORT_HTTPS=<port number>
70111```
71112
72- Test the httpbin service via HTTP:
113+ Test the ExternalName service (httpbin.org) via HTTP:
73114
74115``` shell
75- curl --resolve httpbin .example.com:$GW_PORT_HTTP :$GW_IP http://httpbin .example.com:$GW_PORT_HTTP /get
116+ curl --resolve cafe .example.com:$GW_PORT_HTTP :$GW_IP http://cafe .example.com:$GW_PORT_HTTP /external /get
76117```
77118
78- Test the httpbin service via TLS passthrough:
79-
80- ``` shell
81- curl -k --resolve httpbin.example.com:$GW_PORT_HTTPS :$GW_IP https://httpbin.example.com:$GW_PORT_HTTPS /get
82- ```
83-
84- You should see a JSON response from httpbin.org showing request details e.g.
119+ You should see a JSON response from httpbin.org. Notice the ` Host ` header is correctly set to ` httpbin.org ` :
85120
86121``` json
87122{
88123 "args" : {},
89124 "headers" : {
90125 "Accept" : " */*" ,
91- "Host" : " httpbin.example.com " ,
126+ "Host" : " httpbin.org " ,
92127 "User-Agent" : " curl/8.7.1" ,
93- "X-Amzn-Trace-Id" : " Root=1-68a49086-1e1dabb51155e05c1ebc1f63"
128+ "X-Amzn-Trace-Id" : " Root=1-6901e342-2ce43cf518ee439d4e4d4867" ,
129+ "X-Forwarded-Host" : " cafe.example.com"
94130 },
95131 "origin" : " xxx.xxx.xxx.xx" ,
96- "url" : " https ://httpbin .example.com/get"
132+ "url" : " http ://cafe .example.com/get"
97133}
98134```
99135
136+ Test the internal coffee service:
137+
138+ ``` shell
139+ curl --resolve cafe.example.com:$GW_PORT_HTTP :$GW_IP http://cafe.example.com:$GW_PORT_HTTP /coffee
140+ ```
141+
142+ You should see a response from the coffee service:
143+
144+ ``` text
145+ Server address: 10.244.0.7:8080
146+ Server name: coffee-<pod-id>
147+ Date: ...
148+ URI: /coffee
149+ Request ID: ...
150+ ```
151+
152+ You can also test other httpbin.org endpoints:
153+
154+ ``` shell
155+ # Test /anything endpoint
156+ curl --resolve cafe.example.com:$GW_PORT_HTTP :$GW_IP http://cafe.example.com:$GW_PORT_HTTP /external/anything
157+
158+ # Test /headers endpoint
159+ curl --resolve cafe.example.com:$GW_PORT_HTTP :$GW_IP http://cafe.example.com:$GW_PORT_HTTP /external/headers
160+ ```
161+
162+ ### Testing HTTPS Backend (Optional)
163+
164+ If you configured BackendTLSPolicy in step 5, NGF will establish HTTPS connections to the external service. The client connection remains HTTP, but the backend connection uses HTTPS:
165+
166+ ``` shell
167+ curl --resolve cafe.example.com:$GW_PORT_HTTP :$GW_IP http://cafe.example.com:$GW_PORT_HTTP /external/get
168+ ```
169+
170+ The response will show the request was successfully proxied to ` https://httpbin.org ` with proper TLS verification.
171+
172+ ### Testing TLS Passthrough (Optional)
173+
174+ To test TLS passthrough, first uncomment the TLSRoute section in ` route.yaml ` and reapply:
175+
176+ ``` shell
177+ kubectl apply -f route.yaml
178+ ```
179+
180+ Then save the HTTPS port:
181+
182+ ``` text
183+ GW_PORT_HTTPS=<port number>
184+ ```
185+
186+ Test the httpbin service via TLS passthrough:
187+
188+ ``` shell
189+ curl -k --resolve httpbin.example.com:$GW_PORT_HTTPS :$GW_IP https://httpbin.example.com:$GW_PORT_HTTPS /get
190+ ```
191+
192+ You should see a JSON response from httpbin.org via HTTPS.
193+
194+ ## How It Works
195+
196+ This example demonstrates key features for routing to external services:
197+
198+ 1 . ** DNS Resolution** : The NginxProxy resource configures DNS resolvers (8.8.8.8, 1.1.1.1) so NGINX can resolve external hostnames
199+ 2 . ** Host Header Handling** : NGF automatically detects ExternalName services and sets the ` Host ` header to the external hostname (` httpbin.org ` ) instead of the Gateway hostname (` cafe.example.com ` ), ensuring external services receive the correct Host header
200+ 3 . ** URL Rewriting** : The URLRewrite filter strips the ` /external ` prefix before proxying to httpbin.org, so ` /external/get ` becomes ` /get ` on the external service
201+ 4 . ** Mixed Routing** : The same HTTPRoute can route to both ExternalName services and internal Kubernetes services seamlessly
202+ 5 . ** HTTPS Backends** : BackendTLSPolicy enables secure HTTPS connections to external services while allowing HTTP-level routing based on paths, headers, etc.
203+ 6 . ** TLS Passthrough** : The TLSRoute allows direct TLS connections to external services without termination at the Gateway (no HTTP-level routing)
204+
100205## Cleanup
101206
102207Remove all resources created in this example:
103208
104209``` shell
105210kubectl delete -f route.yaml
106- kubectl delete -f external-service .yaml
211+ kubectl delete -f cafe .yaml
107212kubectl delete -f gateway.yaml
108213```
0 commit comments