-
Notifications
You must be signed in to change notification settings - Fork 10
service
Declare your service
- Tell envoy mesh sidecar about your service/app
- http listening port of your service/app
- http health check path of your service/app
- Tell envoy mesh sidecar how to announce your service on the service mesh
- https listening port
- http health check path
titanSideCars:
envoy:
clusters:
local-myapp:
# Settings of your local application
port: 8080
healthChecks:
path: /delta/status
remote-myapp: # reserved keyword
# Settings of your mesh sidecar proxy
port: 9443
routes: # register your app routing path
- match:
prefix: /delta/
- Enable ratelimit side-car on a per-service basis for services that require ratelimit
# service's values.yaml
titanSideCars:
ratelimit:
enabled: true- If service intends to ratelimit on payload attributes or token claims then it must also configure and enable OPA sidecar. See here for steps
Following examples guide through various ratelimit scenarios!
Lets start with a simple example that ratelimits a matching route
titanSideCars:
ingress:
routes:
- match:
prefix: /myapp/objects
method: POST
ratelimit:
actions:
- limit: 100/minute # supported units - second, minute, hour, dayAbove configuration will limit all 'POST' requests starting with '/myapp/objects' to 100 per minute.
Lets take a slightly more complex case where we ratelimit on each unique value of a header
titanSideCars:
ingress:
routes:
- match:
prefix: /myapp/objects
method: POST
ratelimit:
actions:
- descriptors:
- key: x-product # may also say header.x-myapp-header. 'header.' is default
limit: 100/minuteIn above configuration we again target POST requests starting with /myapp/objects. But now limit will be applied independently to each unique value of the header x-product.
Header x-product with values prod1 and prod2 each will be independently allowed 100 times per minute
We can also ratelimit on an attribute from payload. Lets look at an example
titanSideCars:
ingress:
routes:
- match:
prefix: /myapp/objects
method: POST
ratelimit:
actions:
- descriptors:
- key: payload.email # 'payload.' notation references payload attributes
limit: 100/minuteAbove config will trigger ratelimit on each unique email in the payload of POST requests starting with /myapp/objects. No ratelimiting will be triggered if payload does not contain the specified attribute.
A sample payload like {"name": "foo", "email": "foo@example.com"} will trigger above ratelimit action
We can even ratelimit on a claim inside token as in following example
titanSideCars:
ingress:
routes:
- match:
prefix: /myapp/objects
method: POST
ratelimit:
actions:
- descriptors:
- key: token.jti # 'token.' notation references token claims
limit: 100/minuteWith above config in place, a token with a specfic jti claim will be ratelimited to 100 requests per minute for POST requests starting with /myapp/objects
Lets dig deeper and look at a more complex ratelimit action with multiple descriptors.
titanSideCars:
ingress:
routes:
- match:
prefix: /myapp/objects
method: POST
ratelimit:
actions:
- descriptors:
- key: x-product
eq: myprod
- key: payload.email
limit: 100/minuteIn above config, the ratelimit has a single action with multiple descriptors. For an action to trigger, all its descriptors must match the incoming request.
A POST request starting with /myapp/objects and header x-product with value myprod will be ratelimited to 100 per minute for each unique value of email attribute in payload.
The order of descriptors is immaterial. Following config will have identical effect
actions:
- descriptors:
- key: payload.email
- key: x-product
eq: myprod
limit: 100/minuteAbove may also be re-written as following with identical effect
titanSideCars:
ingress:
routes:
- match:
prefix: /myapp/objects/
method: GET
headers:
- name: x-product
exact: myprod
ratelimit:
actions:
- descriptors:
- key: payload.email
limit: 100/minuteInstead of matching 'x-product' header in the descriptor it may be matched in the route defintion itself. Route defintion is implicitly part of every ratelimit action. Hence the above config has same effect as the original.
Comparision operation inside ratelimit action is more useful when dealing with attributes from token or payload as we will see in later examples. The routes[].match only allows header comparison.
We now pick up a ratelimit config with multiple ratelimit actions
titanSideCars:
ingress:
routes:
- match:
prefix: /myapp/objects
method: POST
ratelimit:
actions:
- descriptors:
- key: payload.email
limit: 100/minute
- descriptors:
- key: payload.email
eq: foo@example.com
limit: 5/minuteAbove targets POST requests starting with /myapp/objects and has two ratelimit actions. First action sets a limit of 100 per minute on each unique email in payload. The second action sets a limit of 5 per minute if email in payload equals foo@example.com.
Hence emails bar@example.com and car@example.com will be allowed 100 times per minute each, but foo@example.com will be restricted to 5 times per minute.
When multiple actions are configured, each action is evaluated indendendently. The most constraining action gets enforced. The order of actions is immaterial. Following config wll have identical effect.
actions:
- descriptors:
- key: payload.email
eq: foo@example.com
limit: 5/minute
- descriptors:
- key: payload.email
limit: 100/minuteLets look at an example where a request matches multiple route definitions
titanSideCars:
ingress:
routes:
- match:
prefix: /myapp/objects
ratelimit:
actions:
- limit: 100/minute
- match:
prefix: /myapp/objects
method: POST
ratelimit:
actions:
- limit: 10/minuteA POST request starting with /myapp/objects will match both the first and second route. Ratelimit actions on each route will be evaluated independently and the most constraining limit will be enforced (10 per minute in this case)
Following example shows how to configure different limits for different environment without duplicating the ratelimit rules in each deployment
titanSideCars:
# can be overwritten per environment
ratelimit:
limits: # holds custom key value pairs
small: 10/hour
large: 100/minute
# configured in service's values.yaml
ingress:
routes:
- match:
prefix: /myapp/objects
method: POST
ratelimit:
actions:
- limit: small # refers to a key inside titanSideCars.ratelimit.limits
- match:
prefix: /myapp/objects
method: GET
ratelimit:
actions:
- limit: largeClick to expand!
Ratelimit sidecar settings. Merge over-writes global.titanSideCars.ratelimit
# titanSideCars.ratelimit.
enabled: bool
imageRegistry: string
imageName: string
imageTag: string
cpu:
request: string
limit: string
memory:
request: string
limit: string
ephemeralStorage:
request: string
limit: string
livenessFailureThreshold: integer
readinessFailureThreshold: integer
logLevel: string
redisUrl: string
# TODO other redis config items(bool, default true) Set to false to disable ratelimit sidecar
(string, optional) Docker image registry path used for ratelimit sidecar. Overrides titanSideCars.imageRegistry
(string, default ratelimit)
(string, default latest)
(string, default 250m)
(string, default 1)
(string, default 256Mi)
(string, default 1Gi)
(string, default 100Mi)
(string, default 500Mi)
(integer, default 50)
(integer, default 100)
(string, default INFO)
(string, required)
# titanSideCars.ingress.routes[].
match: RouteMatch
ratelimit:
enabled: bool
action: []RatelimitAction
(RouteMatch, required)
(optional)
Ratelimit policy for requests that match corresponding route definition.
If missing, the ratelimit template parser will totally skip processing of this route entry.
(bool, default true) Controls enforcement of supplied ratelimit actions
([]RatelimitAction, required) One or more ratelimit actions on request that match corresponding route definiton. Request is matched against all actions and each matching action is evaluated independently.
# titanSideCars.ingress.routes[].ratelimit.actions[].
descriptors: []RatelimitDescriptor
limit: string([]RatelimitDescriptor, optional) List of descriptors that define the attributes to ratelimit on. Corresponding route definition is an implicit descriptor. Incoming request must match all descriptors to be considered for ratelimiting. The ordering of descriptors is not relevant.
(string, required) Ratelimit value in <ratelimit-per-unit>/<unit> format. Supported units are second minute hour and day.
Example: 5/second, 50/minute, 100/hour, 10/day
Instead of supplying a hard-coded limit, limit can also refer to a key from titanSideCars.ratelimit.limits key-value pairs as in example below. This pattern allows for easy configuration of limits on a per environment basis.
Click to expand!
titanSideCars:
ratelimit:
limits:
small: 100/day
ingress:
routes:
- match: /
ratelimit:
actions:
- limit: small# titanSideCars.ingress.routes[].ratelimit.actions[].descriptors[].
key: string
# comparison operators
eq: string # equals
sw: string # starts-with
ew: string # ends-with
co: string # contains
lk: string # like
pr: bool # present
neq: string # not equals
nsw: string # not starts-with
new: string # not ends-with
nco: string # not contains
nlk: string # not like
npr: bool # not present(string, required) Attribute to rate-limit on. If no comparison operator is specified, ratelimit is performed on each unique value of the attribute. Key may refer to a header, token claim or an attribute from json payload.
A header may be referenced via header. notation. Example: header.x-request-id
A token claim may be referenced via token. notation. Example: token.sub.scope
A payload attribute may be referenced via payload. notation. Example: payload.userType
(oneof optional) Comparison operator. When specified, the ratelimit is performed on result of comparision.
For binary operators, the operator value indicates the right hand operand and should be a string.
The supported operators are
- eq/neq: Exact string match
- sw/nsw: String prefix match
- ew/new: String suffix match
- co/nco: Substring match
- lk/nlk: Regex match. Regex syntax is documented here
-
pr/npr: Unary operator. Indicates if key is present or not. Only
truevalue is used. Useprto test presence andnprto test non presence.