This is the "latest" release of Envoy Gateway, which contains the most recent commits from the main branch.
This release might not be stable.
Please refer to the /docs documentation for the most current information.
GRPC Timeouts
5 minute read
Unlike HTTPRoute, the Gateway API GRPCRoute resource does not (yet) expose a native
timeouts field — see the upstream tracking issue Support Request Timeouts for GRPCRoute.
Until that lands, Envoy Gateway lets you configure timeouts for gRPC traffic with a
BackendTrafficPolicy that targets the GRPCRoute.
The default request timeout is 15 seconds in Envoy Proxy, which will terminate long-lived
streaming RPCs. The relevant spec.timeout.http fields are:
- requestTimeout: the maximum duration for the entire response to be received from the
upstream. This bounds unary RPCs. Set it to
"0s"to disable it for streaming RPCs, which otherwise would be cut off once the timeout elapses. - maxStreamDuration: the maximum duration of a stream, measured from when the request is sent
until the response stream is fully consumed. It does not apply to non-streaming requests. Set it
to
"0s"to allow streams to run indefinitely. - streamIdleTimeout: the amount of time a stream may exist with no upstream or downstream activity. Use this to reclaim idle streams without capping a healthy long-lived stream’s total duration.
Prerequisites
Follow the steps below to install Envoy Gateway and the example manifest. Before proceeding, you should be able to query the example backend using HTTP.
Expand for instructions
Install the Gateway API CRDs and Envoy Gateway using Helm:
Gateway API CRD compatibilityThis command installs Gateway API CRDs. If your Kubernetes provider already manages compatible Gateway API CRDs for the cluster, use the provider-managed Gateway API CRD install steps instead.
helm install eg oci://docker.io/envoyproxy/gateway-helm --version v0.0.0-latest -n envoy-gateway-system --create-namespaceInstall the GatewayClass, Gateway, HTTPRoute and example app:
kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/latest/quickstart.yaml -n defaultVerify Connectivity:
Get the External IP of the Gateway:
export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}')Curl the example app through Envoy proxy:
curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/getThe above command should succeed with status code 200.
Get the name of the Envoy service created the by the example Gateway:
export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')Get the deployment of the Envoy service created the by the example Gateway:
export ENVOY_DEPLOYMENT=$(kubectl get deploy -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')Port forward to the Envoy service:
kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 8888:80 &Curl the example app through Envoy proxy:
curl --verbose --header "Host: www.example.com" http://localhost:8888/getThe above command should succeed with status code 200.
Follow the GRPC Routing task to set up a Gateway and a GRPCRoute named
yages before configuring timeouts.
Note: A GRPCRoute can have at most one BackendTrafficPolicy attached to it; a second policy
targeting the same route is rejected as Conflicted. The two examples below are therefore
alternatives that reuse the same policy name (grpc-timeouts) — pick the one that matches your
workload. Re-applying with the same metadata.name updates the existing policy rather than creating
a conflicting second one.
Unary RPCs
Set requestTimeout to bound the duration of unary RPCs. Here, unary calls that take longer than
5 seconds are terminated with a timeout.
cat <<EOF | kubectl apply -f -
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: grpc-timeouts
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: GRPCRoute
name: yages
timeout:
http:
requestTimeout: "5s"
EOF
Save and apply the following resource to your cluster:
---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: grpc-timeouts
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: GRPCRoute
name: yages
timeout:
http:
requestTimeout: "5s"
Streaming RPCs
For server-streaming, client-streaming, or bidirectional-streaming RPCs, requestTimeout would
terminate the stream once it elapses. Disable it with "0s" and, if you want an upper bound, use
maxStreamDuration (or streamIdleTimeout to reclaim only idle streams). The example below lets
streams run indefinitely while reclaiming streams that are idle for more than 1 hour.
cat <<EOF | kubectl apply -f -
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: grpc-timeouts
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: GRPCRoute
name: yages
timeout:
http:
# Disable the per-request timeout so long-lived streams are not cut off.
requestTimeout: "0s"
# Allow streams to run indefinitely; set a non-zero value to cap them.
maxStreamDuration: "0s"
# Reclaim streams with no activity for more than 1 hour.
streamIdleTimeout: "1h"
EOF
Save and apply the following resource to your cluster:
---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: grpc-timeouts
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: GRPCRoute
name: yages
timeout:
http:
# Disable the per-request timeout so long-lived streams are not cut off.
requestTimeout: "0s"
# Allow streams to run indefinitely; set a non-zero value to cap them.
maxStreamDuration: "0s"
# Reclaim streams with no activity for more than 1 hour.
streamIdleTimeout: "1h"
Verification
First confirm the policy is accepted:
kubectl get backendtrafficpolicy/grpc-timeouts -o yaml
The status should reflect Accepted=True on the targeted GRPCRoute ancestor.
Then confirm the timeout is actually programmed into the Envoy route config with egctl:
egctl config envoy-proxy route \
--labels gateway.envoyproxy.io/owning-gateway-name=eg,gateway.envoyproxy.io/owning-gateway-namespace=default \
-o yaml | grep -A2 -E 'timeout|maxStreamDuration'
For the unary example you should see the route’s timeout set to the configured
requestTimeout (e.g. timeout: 5s). For the streaming example you should see
timeout: 0s (disabled) together with maxStreamDuration on the route action.
To exercise the timeout end-to-end you need a gRPC backend that can delay or stream (the
sample yages echo server used in the GRPC Routing task returns
immediately). Against such a backend, a unary call that exceeds requestTimeout returns
gRPC status DEADLINE_EXCEEDED (HTTP 504), for example with
grpcurl:
grpcurl -plaintext -authority=grpc-example.com ${GATEWAY_HOST}:80 <your.slow.Method>
# ERROR:
# Code: DeadlineExceeded
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.