Rate limiting in Kubernetes using NetScaler
In a Kubernetes deployment, you can rate limit the requests to the resources on the back end server or services using rate limiting feature provided by the ingress NetScaler.
NetScaler provides a Kubernetes CustomResourceDefinitions (CRDs) called the Rate limit CRD that you can use with the NetScaler Ingress Controller to configure the rate limiting configurations on the NetScalers used as Ingress devices.
Apart from rate limiting the requests to the services in a Kubernetes environment, you can use the Rate limit CRD for API security as well. The Rate limit CRD allows you to limit the REST API request to API servers or specific API endpoints on the API servers. It monitors and keeps track of the requests to the API server or endpoints against the allowed limit per time slice and hence protects from attacks such as the DDoS attack.
You can enable logging for observability with the rate limit CRD. Logs are stored on NetScaler which can be viewed by checking the logs using the shell command. The file location is based on the syslog configuration. For example, /var/logs/ns.log
.
Rate limit CRD definition
The Rate limit CRD spec is available in the NetScaler Ingress Controller GitHub repo at: ratelimit-crd.yaml. The Rate limit CRD provides attributes for the various options that are required to define the rate limit policies on the Ingress NetScaler that acts as an API gateway.
Rate limit CRD attributes
The following table lists the various attributes provided in the Rate limit CRD:
CRD attribute | Description |
---|---|
ingressclass |
Specifies the ingress class so that only the ingress controller associated with the specified ingress class processes the resource. Otherwise, all the controllers in the cluster will process this resource. |
servicename |
The list of Kubernetes services to which you want to apply the rate limit policies. |
selector_keys |
The traffic selector keys that filter the traffic to identify the API requests against which the throttling is applied and monitored. |
Note: The selector_keys is an optional attribute. You can choose to configure zero, one or more of the selector keys. If more than one selector keys are configured then it is considered as a logical AND expression. |
|
path: An array of URL path prefixes that refer to a specific API endpoint. For example, /api/v1/products/ . |
|
method: An array of HTTP methods. Allowed values are GET, PUT, POST, or DELETE. | |
header_name: HTTP header that has the unique API client or user identifier. For example, X-apikey which comes with a unique API-key that identifies the API client sending the request. |
|
per_client_ip: Allows you to monitor and apply the configured threshold to each API request received per unique client IP address. | |
req_threshold |
The maximum number of requests that are allowed in the given time slice (request rate). |
timeslice |
The time interval specified in microseconds (multiple of 10 s), during which the requests are monitored against the configured limits. If not specified it defaults to 1000 milliseconds. |
limittype |
It allows you to configure the type of throttling algorithms that you want to use to apply the limit. Supported algorithms are burst and smooth. The default is the burst mode. |
throttle_action |
It allows you to define the throttle action that needs to be taken on the traffic that is throttled for crossing the configured threshold. |
DROP: Drops the requests above the configured traffic limits. | |
RESET: Resets the connection for the requests crossing the configured limit. | |
RESPOND: Responds with the standard “429 Too many requests” response. | |
redirect_url |
This attribute is an optional attribute that is required only if throttle_action is configured with the value REDIRECT . |
logpackets |
Enables audit logs. |
logexpression |
Specifies the default-syntax expression that defines the format and content of the log message. |
loglevel |
Specifies the severity level of the log message that is generated. |
Deploy the Rate limit CRD
Perform the following to deploy the Rate limit CRD:
-
Download the CRD (ratelimit-crd.yaml).
-
Deploy the Rate limit CRD using the following command:
kubectl create -f ratelimit-crd.yaml
For example,
root@master:~# kubectl create -f ratelimit-crd.yaml customresourcedefinition.apiextensions.k8s.io/ratelimits.citrix.com created root@master:~# kubectl get crd NAME CREATED AT ratelimits.citrix.com 2019-08-27T01:06:30Z
How to write a rate-based policy configuration
After you have deployed the CRD provided by NetScaler in the Kubernetes cluster, you can define the rate-based policy configuration in a .yaml
file. In the .yaml
file, use ratelimit
in the kind
field and in the spec
section add the Rate limit CRD attributes based on your requirement for the policy configuration.
After you deploy the .yaml
file, the NetScaler Ingress Controller applies the rate-based policy configuration on the Ingress NetScaler device.
Following are some examples for rate limit policy configurations.
Limit API requests to configured API endpoint prefixes
Consider a scenario wherein you want to define a rate-based policy in NetScaler to limit the API requests to 15 requests per minute from each unique client IP address to the configured API endpoint prefixes. Create a .yaml
file called ratelimit-example1.yaml
and use the appropriate CRD attributes to define the rate-based policy as follows:
apiVersion: citrix.com/v1beta1
kind: ratelimit
metadata:
name: throttle-req-per-clientip
spec:
servicenames:
- frontend
selector_keys:
basic:
path:
- "/api/v1/products"
- "/api/v1/orders/"
per_client_ip: true
req_threshold: 15
timeslice: 60000
throttle_action: "RESPOND"
logpackets:
logexpression: "http.req.url"
loglevel: "INFORMATIONAL"
<!--NeedCopy-->
Note:
You can initiate multiple Kubernetes objects for different paths that require different rate limit configurations.
After you have defined the policy configuration, deploy the .yaml
file using the following command:
root@master:~#kubectl create -f ratelimit-example1.yaml
ratelimit.citrix.com/throttle-req-per-clientip created
The NetScaler Ingress Controller applies the policy configuration on the Ingress NetScaler device.
Limit API requests to calender APIs
Consider a scenario wherein you want to define a rate-based policy in a NetScaler to limit the API requests (GET or POST) to five requests from each API client identified using the HTTP header X-API-Key
to the calender APIs. Create a .yaml
file called ratelimit-example2.yaml
and use the appropriate CRD attributes to define the rate-based policy as follows:
apiVersion: citrix.com/v1beta1
kind: ratelimit
metadata:
name: throttle-calendarapi-perapikey
spec:
servicenames:
- frontend
selector_keys:
basic:
path:
- "/api/v1/calender"
method:
- "GET"
- "POST"
header_name: "X-API-Key"
req_threshold: 5
throttle_action: "RESPOND"
logpackets:
logexpression: "rate exceeded, you may want to configure higher limit"
loglevel: "INFORMATIONAL"
<!--NeedCopy-->
After you have defined the policy configuration, deploy the .yaml
file using the following command:
root@master:~#kubectl create -f ratelimit-example2.yaml
ratelimit.citrix.com/throttle-req-per-clientip created
The NetScaler Ingress Controller applies the policy configuration on the Ingress NetScaler device.