When you start your adventure with microservices, at some point you need to think about policy in your application. Istio allows you to manage your applications without making any changes in your business logic. This service mesh provides: access control systems, telemetry capturing systems, quota enforcement systems and billing systems. Mixer, the Istio component, is responsible for all these things.
Proxy calls Mixer before and after each request to perform precondition checks and report telemetry. Mixer also has reliability and scalability benefits.
Mixer manages very well different infrastructure backends because of a plug-in model. Plug-ins are known as adapters and they allows Mixer to interface to different infrastructure backends that deliver core functionality, such as logging, monitoring, quotas, ACL checking, and more.
Enable Rate Limiting
Let's try to use Mixer components in practice. For example, we have a simple application with one server and two versions of bot.
We want to set some rules like:
- the default rule is 500 requests every 1s
- 2 requests every 5s if the destination is a server
- 5 requests every 5s if the destination is server and request headers contain one called "source" with value "10.28.11.20"
- no limit if request headers contain one called "user" with value "jason"
But first we need to configure destination rules:
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: server spec: host: server subsets: - name: v1 labels: version: v1 --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: bot spec: host: bot subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2
So now we can apply our setting for rate limiting:
apiVersion: "config.istio.io/v1alpha2" kind: memquota metadata: name: handler namespace: istio-system spec: quotas: - name: requestcount.quota.istio-system maxAmount: 500 validDuration: 1s overrides: - dimensions: destination: server source: "10.28.11.20" maxAmount: 5 validDuration: 5s - dimensions: destination: server maxAmount: 2 validDuration: 5s --- apiVersion: "config.istio.io/v1alpha2" kind: quota metadata: name: requestcount namespace: istio-system spec: dimensions: source: request.headers["source"] | "unknown" destination: destination.labels["app"] | destination.service | "unknown" destinationVersion: destination.labels["version"] | "unknown" --- apiVersion: config.istio.io/v1alpha2 kind: QuotaSpec metadata: name: request-count namespace: istio-system spec: rules: - quotas: - charge: 1 quota: requestcount --- apiVersion: config.istio.io/v1alpha2 kind: QuotaSpecBinding metadata: name: request-count namespace: istio-system spec: quotaSpecs: - name: request-count namespace: istio-system services: - name: server namespace: default # - service: '*' # Uncomment this to bind *all* services to request-count --- apiVersion: config.istio.io/v1alpha2 kind: rule metadata: name: quota namespace: istio-system spec: match: match(request.headers["user"], "jason") == false actions: - handler: handler.memquota instances: - requestcount.quota
Rate limit configuration is split into 2 parts.
- Client Side
- QuotaSpec defines quota name and amount that the client should request
- QuotaSpecBinding connect QuotaSpec with one or more services
- Mixer Side
- quota instance defines how quota is dimensioned by Mixer
- memquota adapter defines memquota adapter configuration
- quota rule defines when quota instance is dispatched to the memquota adapter
This short demo shows how the route should look like after adding rate limiting:
- At the beginning we can send requests without any limits
- After this we use kubectl to add server-ratelimit.yaml
- Changes must be loaded into our application so we must wait a little bit
- Around 0:25s on demo video we can see our limits are ready
Istio includes many adapters and add-ons which let a developer clearly understand how an application works. Those are few of them:
Jaeger for tracing
Prometheus for collecting metrics and logs
Grafana for visualizing metrics
Fluentd for logging
Mixer is a powerful component of Istio. Configuration is simple and allows you to manage your rate limits. Additionally collects logs and metrics to distribute it to plug-ins. Adapters previously installed with Istio make your application looks clearly to viewing and finding bugs, traffic etc. I recommend everyone try it in your microservices.