Skip to content

For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.

Page as Markdown

    

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

  1. Follow the Get started guide to install kgateway.

  2. Follow the Sample app guide to create a gateway proxy with an HTTP listener and deploy the httpbin sample app.

  3. 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.

  1. 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"}]'
  2. 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
    EOF
    Setting 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.
  3. Port-forward the gateway proxy and verify that connection_keepalive appears 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_PID

    Example 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"}]'
Was this page helpful?