HTTP
To learn more about what local rate limiting is and the differences between local and global rate limiting, see About local rate limiting.
Before you begin
-
Follow the Get started guide to install K8sGateway, set up a gateway resource, 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 gloo-system gloo-proxy-http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") echo $INGRESS_GW_ADDRESS
kubectl port-forward deployment/gloo-proxy-http -n gloo-system 8080:8080
Apply local rate limit settings to Layer 4 traffic
-
Create an HttpListenerOption resource with your local rate limit settings.
kubectl apply -f- <<EOF apiVersion: gateway.solo.io/v1 kind: HttpListenerOption metadata: name: local-ratelimit namespace: gloo-system spec: targetRefs: - group: gateway.networking.k8s.io kind: Gateway name: http options: networkLocalRatelimit: maxTokens: 1 tokensPerFill: 1 fillInterval: 100s EOF
-
Send a request to the httpbin app. Verify that your request succeeds and a 200 HTTP response code is returned.
curl -vik http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: www.example.com:8080"
curl -vik localhost:8080/status/200 -H "host: www.example.com"
Example output:
... * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK HTTP/1.1 200 OK < content-type: application/xml content-type: application/xml ...
-
Send another request to the httpbin app. Note that this time the request is denied immediately. Because the gateway is configured with only 1 token that is refilled every 100 seconds, the token was assigned to the connection of the first request. No tokens were available to be assigned to the second request. Because the request is rejected on Layer 4, no HTTP response code or message is returned.
curl -vik http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: www.example.com:8080"
curl -vik localhost:8080/status/200 -H "host: www.example.com"
Example output:
* Recv failure: Connection reset by peer * Closing connection 0 curl: (56) Recv failure: Connection reset by peer
Apply local rate limit settings to Layer 7 traffic
-
Change the local rate limiting settings in the HttpListenerOption resource to apply to Layer 7 traffic instead of Layer 4 traffic by using the
httpLocalRatelimit
option. The following example configures the gateway with a token bucket with a maximum of 1 token that is refilled every 100 seconds. To verify that your rate limiting settings are working as expected and to simplify troubleshooting, setenableXRatelimitHeaders: true
. This option adds rate limiting headers to your response that indicate the local rate limiting settings that are applied, the number of tokens that are left in the bucket, and the number of seconds until the token bucket is refilled. For more information, see the Envoy documentation.kubectl apply -f- <<EOF apiVersion: gateway.solo.io/v1 kind: HttpListenerOption metadata: name: local-ratelimit namespace: gloo-system spec: targetRefs: - group: gateway.networking.k8s.io kind: Gateway name: http options: httpLocalRatelimit: defaultLimit: maxTokens: 1 tokensPerFill: 1 fillInterval: 100s enableXRatelimitHeaders: true EOF
-
Send a request to the httpbin app. Verify that your request succeeds and a 200 HTTP response code is returned. In addition, review the
x-ratelimit-*
headers that are returned. Thex-ratelimit-limit
header represents the token limit that is set on the gateway. To check how many tokens are available for subsequent requests, review thex-ratelimit-remaining
header. Use thex-ratelimit-reset
header to view how many seconds are left until the token bucket is refilled.curl -vik http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: www.example.com:8080"
curl -vik localhost:8080/status/200 -H "host: www.example.com"
Example output:
... * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK HTTP/1.1 200 OK < x-ratelimit-limit: 1 x-ratelimit-limit: 1 < x-ratelimit-remaining: 0 x-ratelimit-remaining: 0 < x-ratelimit-reset: 95 x-ratelimit-reset: 95 ...
-
Send another request to the httpbin app. Note that this time the request is denied with a 429 HTTP response code and a
local_rate_limited
message in your CLI output. Because the gateway is configured with only 1 token that is refilled every 100 seconds, the token was assigned to the connection of the first request. No tokens were available to be assigned to the second request. If you wait for 100 seconds, the token bucket is refilled and a new connection can be accepted by the gateway.curl -vik http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: www.example.com:8080"
curl -vik localhost:8080/status/200 -H "host: www.example.com"
Example output:
... * Mark bundle as not supporting multiuse < HTTP/1.1 429 Too Many Requests HTTP/1.1 429 Too Many Requests < x-ratelimit-limit: 1 x-ratelimit-limit: 1 < x-ratelimit-remaining: 0 x-ratelimit-remaining: 0 < x-ratelimit-reset: 79 x-ratelimit-reset: 79 ... Connection #0 to host 34.XXX.XX.XXX left intact local_rate_limited
Cleanup
You can remove the resources that you created in this guide.kubectl delete httplisteneroption local-ratelimit -n gloo-system