Reputation: 616
I have a two services running in GCP app engine; let's say service A and B, and then I deployed a spring cloud gateway service to route external traffic to these two services based on path predicates. service A and B are deployed in app engine flexible. initially I had the gateway deployed in app engine flexible and it was working perfectly well. because we have some batch services which has response time of more than 10 mins (app engine standard has max-response-timeout of 10 mins), we had to decide to migrate the gateway to app engine flexible.
The gateway service is dockerized and runs in the port 8080. My app.yaml looks like this:
runtime: custom
env: flex
service: beta-gateway
env_variables:
SPRING_PROFILES_ACTIVE: "beta"
resources:
cpu: 1
memory_gb: 2
liveness_check:
path: "/actuator/health"
check_interval_sec: 30
timeout_sec: 4
failure_threshold: 2
success_threshold: 2
initial_delay_sec: 300
readiness_check:
path: "/actuator/health"
check_interval_sec: 5
timeout_sec: 4
failure_threshold: 2
success_threshold: 2
app_start_timeout_sec: 300
The service gets deployed correctly, the actuator endpoints works perfectly, I call /actuator/gateway/routes
end point and the routing config looks good (And I route it to the services A and B using the appshot dns uri; Not the best approach should use a service registry in future).
The Problem: The problem is that for any endpoint other that the actuator endpoint, the request goes in to a redirect(302) loop and eventually fails.
What I tried:
As mentioned above, I invoked the /actuator/gateway/routes end point and the routing config looks good. I enabled TRACE logging for gateway and I see that the routing is getting matched correctly to service A or B's appspot dns url.
I am not very sure if it is relevant, but I initially did a deployment with network setting specifying port binding
network:
name: default
forwarded_ports:
- 80:8080
I then learned that the binding to 8080 is done be default and removed it.
Any advice will be highly appreciated. Thank you!
Upvotes: 0
Views: 725
Reputation: 616
The issue was caused because even though the traffic from browser to the GCP app engine's load balancer is secured (HTTP), the traffic from the load balancer to the instances are http as they are internal traffic.
From this point, the gateway forwards the request to the downstream api with X-Forwarded-Proto as HTTP (rather than HTTPS), then dowsteam API, as it rightly should sends a redirect request (302) asking the client to visit the end point with a secured connection (HTTPS). On receiving the 302 status, the client/browser again sends the request and SSL termination happens at the load balancer and the loop goes on.
The fix was to:
Set the server.forward-headers-strategy
property to NATIVE
, to enable the tomcat server to handle the forward headers.
Set server.tomcat.redirect-context-root
is set to false
, to make tomcat server honour the X-Forwarded-* headers before redirecting.
Came across the below mentioned reads which explains this.
Upvotes: 0