For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.
HTTP/2 keepalive
Detect half-dead HTTP/2 and gRPC upstream connections with PING-based keepalive.
About HTTP/2 keepalive
TCP keepalive operates at the OS level and detects connection loss at the network layer. However, it cannot detect connections that remain open at the TCP level, but are no longer functional at the HTTP/2 level. For example, if a cloud load balancer silently drops a long-lived connection after its idle timeout expires without sending a TCP reset, the gateway proxy has no way to know the connection is broken until it tries to use it.
For HTTP/2 and gRPC connections, you can configure HTTP/2 PING-based keepalive in a BackendConfigPolicy resource. Envoy sends periodic PING frames over the connection. If no response arrives within the configured timeout, Envoy closes the connection and the event is recorded in the http2.keepalive_timeout cluster statistic.
Before you begin
-
Follow the Get started guide to install kgateway.
-
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.
export INGRESS_GW_ADDRESS=$(kubectl get svc -n kgateway-system http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") echo $INGRESS_GW_ADDRESS
Configure HTTP/2 keepalive
HTTP/2 keepalive only applies when the gateway proxy uses HTTP/2 to connect to the backend. To enable this, set appProtocol: kubernetes.io/h2c on the Service port so that kgateway treats the upstream as an HTTP/2 backend.
-
Patch the httpbin Service to use HTTP/2 on port 8000.
kubectl patch service httpbin -n httpbin --type='json' \ -p='[{"op":"add","path":"/spec/ports/0/appProtocol","value":"kubernetes.io/h2c"}]' -
Create a BackendConfigPolicy that applies HTTP/2 keepalive settings to the httpbin service.
kubectl apply -f- <<EOF kind: BackendConfigPolicy apiVersion: gateway.kgateway.dev/v1alpha1 metadata: name: httpbin-http2-keepalive namespace: httpbin spec: targetRefs: - name: httpbin group: "" kind: Service http2ProtocolOptions: connectionKeepalive: timeout: 5s interval: 30s connectionIdleInterval: 60s EOFSetting Description timeoutHow long to wait for a PING response before closing the connection. Required. intervalHow often to send PING frames over the connection. Optional. connectionIdleIntervalHow long a connection must be idle before PING frames start. Optional. -
Port-forward the gateway proxy and verify that
connection_keepaliveappears in the httpbin cluster config.kubectl port-forward deployment/http -n kgateway-system 19000:19000 & PF_PID=$! sleep 2 curl -s "127.0.0.1:19000/config_dump?include_eds" | \ jq '.configs[] | select(.["@type"] == "type.googleapis.com/envoy.admin.v3.ClustersConfigDump") | .dynamic_active_clusters[].cluster | select(.name | contains("httpbin")) | .typed_extension_protocol_options ["envoy.extensions.upstreams.http.v3.HttpProtocolOptions"] .explicit_http_config.http2_protocol_options.connection_keepalive' kill $PF_PIDExample output:
{ "interval": "30s", "timeout": "5s", "connection_idle_interval": "60s" }
Cleanup
You can remove the resources that you created in this guide.kubectl delete backendconfigpolicy httpbin-http2-keepalive -n httpbin --ignore-not-found
kubectl patch service httpbin -n httpbin --type='json' \
-p='[{"op":"remove","path":"/spec/ports/0/appProtocol"}]'