HTTP gateway
Set local rate limiting settings on an HTTP gateway, virtual service, or route to limit the number of incoming HTTP requests that are allowed to enter the cluster before global rate limiting and external auth policies are applied.
To learn more about what local rate limiting is and the differences between local and global rate limiting, see About local rate limiting.
On this page:
- Deploy the httpbin sample app
- Apply local rate limit settings to Layer 4 traffic
- Apply local rate limit settings to Layer 7 traffic
- Different local rate limit settings on the gateway and virtual service
- Cleanup
Deploy the httpbin sample app
To try out local rate limiting for HTTP traffic, deploy the httpbin app to your cluster.
-
Create a service account, deployment, and service to deploy and expose the httpbin app within the cluster.
kubectl apply -f- <<EOF apiVersion: v1 kind: ServiceAccount metadata: name: httpbin --- apiVersion: v1 kind: Service metadata: name: httpbin labels: app: httpbin spec: ports: - name: http port: 8000 targetPort: 80 selector: app: httpbin --- apiVersion: apps/v1 kind: Deployment metadata: name: httpbin spec: replicas: 1 selector: matchLabels: app: httpbin version: v1 template: metadata: labels: app: httpbin version: v1 spec: serviceAccountName: httpbin containers: - image: docker.io/kennethreitz/httpbin imagePullPolicy: IfNotPresent name: httpbin ports: - containerPort: 80 EOF
Example output:
serviceaccount/httpbin created service/httpbin created deployment.apps/httpbin created
-
Create a virtual service to expose the
/status/200
route for the httpbin app.kubectl apply -f- <<EOF apiVersion: gateway.solo.io/v1 kind: VirtualService metadata: name: httpbin namespace: gloo-system spec: virtualHost: domains: - '*' routes: - matchers: - prefix: /status/200 routeAction: single: upstream: name: default-httpbin-8000 namespace: gloo-system EOF
-
Send a request to the httpbin app and verify that you get back a 200 HTTP response code.
curl -vik $(glooctl proxy url)/status/200
Example output:
* Mark bundle as not supporting multiuse < HTTP/1.1 200 OK HTTP/1.1 200 OK ...
Apply local rate limit settings to Layer 4 traffic
-
Apply local rate limiting settings to Layer 4 traffic by adding the
networkLocalRatelimit
setting to thegateway-proxy
resource. The following example configures the gateway with a token bucket with a maximum of 1 token that is refilled every 100 seconds.kubectl apply -n gloo-system -f - <<EOF apiVersion: gateway.solo.io/v1 kind: Gateway metadata: name: gateway-proxy namespace: gloo-system spec: bindAddress: '::' bindPort: 8080 httpGateway: options: networkLocalRatelimit: maxTokens: 1 tokensPerFill: 1 fillInterval: 100s ssl: false useProxyProto: false EOF
-
Send a request to the httpbin app. Verify that your request succeeds and a 200 HTTP response code is returned.
curl -vik $(glooctl proxy url)/status/200
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 get assigned to the second request. Because the request is rejected on Layer 4, no HTTP response code or message is returned.
curl -vik $(glooctl proxy url)/status/200
Example output:
* Empty reply from server * Closing connection 0 curl: (52) Empty reply from server
Apply local rate limit settings to Layer 7 traffic
-
Change the local rate limiting settings in the gateway 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 -n gloo-system -f - <<EOF apiVersion: gateway.solo.io/v1 kind: Gateway metadata: name: gateway-proxy namespace: gloo-system spec: bindAddress: '::' bindPort: 8080 httpGateway: options: httpLocalRatelimit: defaultLimit: maxTokens: 1 tokensPerFill: 1 fillInterval: 100s enableXRatelimitHeaders: true ssl: false useProxyProto: false 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 $(glooctl proxy url)/status/200
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 get 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 $(glooctl proxy url)/status/200
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
Different local rate limit settings on the gateway and virtual service
-
Change the virtual service for the httpbin app to add 2 more routes. The
/status/200
and/ip
routes do not configure any local rate limiting settings and therefore share the same limit that is set on the gateway. However, the/headers
route specifies and enforces its own local rate limiting settings with a maximum number of 3 tokens in the token bucket that is refilled every 30 seconds.kubectl apply -f- <<EOF apiVersion: gateway.solo.io/v1 kind: VirtualService metadata: name: httpbin namespace: gloo-system spec: virtualHost: domains: - '*' routes: - matchers: - prefix: /status/200 routeAction: single: upstream: name: default-httpbin-8000 namespace: gloo-system - matchers: - prefix: /ip routeAction: single: upstream: name: default-httpbin-8000 namespace: gloo-system - matchers: - prefix: /headers options: ratelimit: localRatelimit: maxTokens: 3 tokensPerFill: 3 fillInterval: 30s routeAction: single: upstream: name: default-httpbin-8000 namespace: gloo-system EOF
-
Send a request to the
/status/200
route and verify that the request succeeds and you get back a 200 HTTP response code.curl -vik $(glooctl proxy url)/status/200
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: 96 x-ratelimit-reset: 96
-
Send another request to the
/status/200
route and verify that the request is now denied and that you get back a 429 HTTP response code.curl -vik $(glooctl proxy url)/status/200
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: 88 x-ratelimit-reset: 88 ... local_rate_limited
-
Send a request to the
/ip
route and verify that the request is denied and that you get back a 429 HTTP response code. Because the/status/200
and the/ip
routes do not configure local rate limiting settings, they share the same limit that is set on the gateway, which is 1 token in the token bucket that is refilled every 100 seconds.curl -vik $(glooctl proxy url)/ip
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: 84 x-ratelimit-reset: 84
-
Send a request to the
/headers
route and verify that this request succeeds with a 200 HTTP response code. Because this route specifies its own local rate limiting settings, these settings take precedence over the settings on the gateway.curl -vik $(glooctl proxy url)/headers
Example output:
< HTTP/1.1 200 OK HTTP/1.1 200 OK < x-ratelimit-limit: 3 x-ratelimit-limit: 3 < x-ratelimit-remaining: 2 x-ratelimit-remaining: 2 < x-ratelimit-reset: 6 x-ratelimit-reset: 6
-
Send 3 more requests to the
/headers
route to verify that your requests are rate limited properly.
Cleanup
You can optionally clean up the resources that you created as part of this guide.
-
Delete the httpbin app.
kubectl delete deployment httpbin kubectl delete service httpbin kubectl delete serviceaccount httpbin
-
Delete the virtual service that exposed routes for the httpbin app.
kubectl delete virtualservice httpbin -n gloo-system
-
Restore the settings in the
gateway-proxy
gateway resource.kubectl apply -n gloo-system -f - <<EOF apiVersion: gateway.solo.io/v1 kind: Gateway metadata: name: gateway-proxy namespace: gloo-system spec: bindAddress: '::' bindPort: 8080 httpGateway: {} ssl: false useProxyProto: false EOF