Per-try timeout
Set separate timeouts for retries.
About per-try timeouts
The per-retry timeout allows you to set a timeout for retried requests. If the timeout expires, Envoy cancels the retry attempt and immediately retries on another upstream host.
By default, Envoy has a default overall request timeout of 15 seconds. A request timeout represents the time Envoy waits for the entire request to complete, including retries. Without a per-try timeout, retries might take longer than the overall request timeout, and therefore might not be executed as the request times out before the retry attempts can be performed. You can configure a larger request timeout to account for this case. However, you can also define timeouts for each retry so that you can protect against slow retry attempts from consuming the entire request timeout.
Note that if you configured a global request timeout, the per-try timeout must be less than the global request timeout.
Per-try timeouts can be configured on an HTTPRoute directly. To enable per-try timeouts on a Gateway listener level, use a GlooTrafficPolicy instead.
The steps in this section use the Envoy-based kgateway data plane. The steps do not work with the agentgateway data plane.
Before you begin
Follow the Get started guide to install Gloo Gateway.
Follow the Sample app guide to create a gateway proxy with an HTTP listener and deploy the httpbin sample app.
Get the external address of the gateway and save it in an environment variable.
Set up per-retry timeouts
Install the experimental Kubernetes Gateway API CRDs.
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.0/experimental-install.yamlConfigure the per-retry timeout. You can apply the timeout to an HTTPRoute, or Gateway listener.
Send a request to the httpbin app along the
retry.exampledomain. Verify that theX-Envoy-Expected-Rq-Timeout-Msheader is set to the 5 second timeout that you configured.Example output:
... { "args": {}, "headers": { "Accept": [ "*/*" ], "Host": [ "retry.example" ], "User-Agent": [ "curl/8.7.1" ], "X-Envoy-Expected-Rq-Timeout-Ms": [ "5000" ], "X-Envoy-External-Address": [ "127.0.0.1" ], "X-Forwarded-For": [ "10.244.0.55" ], "X-Forwarded-Proto": [ "http" ], "X-Request-Id": [ "9178dc39-297f-438a-8bd9-4e8203c06b59" ] },Verify that the gateway proxy is configured with the per-try timeout.
Port-forward the gateway proxy on port 19000.
kubectl port-forward deployment/http -n gloo-system 19000Get the configuration of your gateway proxy as a config dump.
curl -X POST 127.0.0.1:19000/config_dump\?include_eds > gateway-config.jsonOpen the config dump and find the route configuration for the
kube_default_reviews_9080Envoy cluster on thelistener~8080~retry_examplevirtual host. Verify that the retry policy is set as you configured it.Example
jqcommand:jq '.configs[] | select(."@type" == "type.googleapis.com/envoy.admin.v3.RoutesConfigDump") | .dynamic_route_configs[].route_config.virtual_hosts[] | select(.routes[].route.cluster == "kube_httpbin_httpbin_8000")' gateway-config.jsonExample output:
"routes": [ { "match": { "prefix": "/" }, "route": { "cluster": "kube_httpbin_httpbin_8000", "timeout": "5s", "retry_policy": { "retry_on": "cancelled,connect-failure,refused-stream,retriable-headers,retriable-status-codes,unavailable", "num_retries": 3, "per_try_timeout": "5s", "retry_back_off": { "base_interval": "1s" } }, "cluster_not_found_response_code": "INTERNAL_SERVER_ERROR" }, "name": "listener~8080~retry_example-route-0-httproute-retry-httpbin-0-0-matcher-0" } ]
Cleanup
You can remove the resources that you created in this guide.
kubectl delete GlooTrafficPolicy retry -n httpbin
kubectl delete GlooTrafficPolicy retry -n gloo-system
kubectl delete httproute retry -n httpbin