mirror of https://github.com/istio/istio.io.git
44 lines
19 KiB
HTML
44 lines
19 KiB
HTML
<!DOCTYPE html><html lang="en" itemscope itemtype="https://schema.org/WebPage" style="overflow-y: scroll;"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="title" content="Enabling Rate Limits"><meta name="og:title" content="Enabling Rate Limits"><meta name="og:image" content="/v0.1/img/logo.png"/><meta name="description" content="This task shows you how to use Istio to dynamically limit the traffic to a service."><meta name="og:description" content="This task shows you how to use Istio to dynamically limit the traffic to a service."><title>Istioldie 0.1 / Enabling Rate Limits</title><script> window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date; ga('create', 'UA-98480406-2', 'auto'); ga('send', 'pageview'); </script> <script async src='https://www.google-analytics.com/analytics.js'></script><link href='https://fonts.googleapis.com/css?family=Roboto:400,100,100italic,300,300italic,400italic,500,500italic,700,700italic,900,900italic' rel='stylesheet' type='text/css'><link rel="alternate" type="application/rss+xml" title="Istio Blog RSS" href="/v0.1/feed.xml"><link rel="apple-touch-icon" href="/v0.1/favicons/apple-touch-icon.png" sizes="180x180"><link rel="icon" type="image/png" href="/v0.1/favicons/android-chrome-96x96.png" sizes="96x96" ><link rel="icon" type="image/png" href="/v0.1/favicons/favicon-32x32.png" sizes="32x32"><link rel="icon" type="image/png" href="/v0.1/favicons/favicon-16x16.png" sizes="16x16"><link rel="manifest" href="/v0.1/favicons/manifest.json"><link rel="mask-icon" href="/v0.1/favicons/safari-pinned-tab.svg" color="#2DA6B0"><meta name="msapplication-TileColor" content="#ffffff"><meta name="msapplication-TileImage" content="/v0.1/favicons/mstile-150x150.png"><link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet"><link rel="stylesheet" href="/v0.1/css/all.css"><link rel="stylesheet" href="/v0.1/css/prism.css"><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script></head><body class="language-unknown"><div class="nav-hero-container" style="z-index: 200000;"><nav id="header-nav" class="navbar navbar-inverse" role="navigation"><div class="container"><div class="row"><div class="col-md-11 nofloat center-block "><div class="navbar-header"> <button type="button" class="hamburger navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/v0.1/"><div> <img src="/v0.1/img/logo.png" alt="Istio" width="36px" height="54px"/> <span class="brand-name">Istioldie 0.1</span></div></a></div><div class="collapse navbar-collapse" id="navbar-collapse-1"><ul class="nav navbar-nav navbar-right"><li><a href="/v0.1/about/" >About</a></li><li><a href="/v0.1/docs/" class='current'>Docs</a></li><li><a href="/v0.1/blog/" >Blog</a></li><li><a href="/v0.1/community/" >Community</a></li><li><a href="/v0.1/faq/" >FAQ</a></li><li class="dropdown"> <a class="dropdown-toggle" data-toggle="dropdown" href=""> <i class='fa fa-lg fa-cog'></i> <span class="caret"></span> </a><ul class="dropdown-menu"><h6 class="dropdown-header">Other versions of this site</h6><li> <a href="https://istio.io">Current Release</a></li><li> <a href="https://preliminary.istio.io">Next Release</a></li><li> <a href="https://archive.istio.io">Older Releases</a></li></ul></li><li><form name="cse" id="searchbox_demo" class="navbar-form navbar-right" role="search"> <input type="hidden" name="cx" value="013699703217164175118:iwwf17ikgf4" /> <input type="hidden" name="ie" value="utf-8" /> <input type="hidden" name="hl" value="en" /><div class="form-group"><div class="input-group"> <input name="q" class="form-control" type="text" size="30" /><div class="input-group-addon"> <span class="btn-search glyphicon glyphicon-search"></span></div></div></div></form> <script type="text/javascript" src="https://www.google.com/cse/brand?form=searchbox_demo"></script></li></ul></div></div></div></div></nav></div><div class="container"><div class="row"><div class="col-md-11 nofloat center-block" style="margin-top: 3px;"><ul class="col-sm-10 nav nav-tabs"><li role="presentation" ><a href="/v0.1/docs/index.html">Welcome</a></li><li role="presentation" ><a href="/v0.1/docs/concepts/index.html">Concepts</a></li><li role="presentation" class='active'><a href="/v0.1/docs/tasks/index.html">Tasks</a></li><li role="presentation" ><a href="/v0.1/docs/samples/index.html">Samples</a></li><li role="presentation" ><a href="/v0.1/docs/reference/index.html">Reference</a></li></ul></div></div></div><script src="/v0.1/js/navtree.js"></script><div class="container docs"><div class="row"><div class="col-md-11 nofloat center-block"><div class="row"><div id="sidebar-container" class="col-sm-3"><ul class="doc-side-nav"><li><h5 class='doc-side-nav-title'>Tasks</h5></li><script type="text/javascript"> var docs = []; docs.push({path: [ "basic-access-control.md", ], url: "/docs/tasks/basic-access-control.html", title: "Enabling Simple Access Control", order: 90, overview: "This task shows how to use Istio to control access to a service."}); docs.push({path: [ "egress.md", ], url: "/docs/tasks/egress.html", title: "Enabling Egress Traffic", order: 40, overview: "Describes how to configure Istio to route traffic from services in the mesh to external services."}); docs.push({path: [ "fault-injection.md", ], url: "/docs/tasks/fault-injection.html", title: "Fault Injection", order: 60, overview: "This task shows how to inject delays and test the resiliency of your application."}); docs.push({path: [ "index.md", ], url: "/docs/tasks/index.html", title: "Tasks", order: 20, overview: "Tasks show you how to do a single specific targeted activity with the Istio system."}); docs.push({path: [ "ingress.md", ], url: "/docs/tasks/ingress.html", title: "Enabling Ingress Traffic", order: 30, overview: "Describes how to configure Istio to expose a service outside of the service mesh."}); docs.push({path: [ "installing-istio.md", ], url: "/docs/tasks/installing-istio.html", title: "Installing Istio", order: 10, overview: "This task shows you how to setup the Istio service mesh."}); docs.push({path: [ "integrating-services-into-istio.md", ], url: "/docs/tasks/integrating-services-into-istio.html", title: "Integrating Services into the Mesh", order: 20, overview: "This task shows you how to integrate your applications with the Istio service mesh."}); docs.push({path: [ "istio-auth.md", ], url: "/docs/tasks/istio-auth.html", title: "Testing Istio Auth", order: 100, overview: "This task shows you how to verify and test Istio-Auth."}); docs.push({path: [ "metrics-logs.md", ], url: "/docs/tasks/metrics-logs.html", title: "Collecting Metrics and Logs", order: 110, overview: "This task shows you how to configure Mixer to collect metrics and logs from Envoy instances."}); docs.push({path: [ "rate-limiting.md", ], url: "/docs/tasks/rate-limiting.html", title: "Enabling Rate Limits", order: 80, overview: "This task shows you how to use Istio to dynamically limit the traffic to a service."}); docs.push({path: [ "request-routing.md", ], url: "/docs/tasks/request-routing.html", title: "Configuring Request Routing", order: 50, overview: "This task shows you how to configure dynamic request routing based on weights and HTTP headers."}); docs.push({path: [ "request-timeouts.md", ], url: "/docs/tasks/request-timeouts.html", title: "Setting Request Timeouts", order: 70, overview: "This task shows you how to setup request timeouts in Envoy using Istio."}); docs.push({path: [ "zipkin-tracing.md", ], url: "/docs/tasks/zipkin-tracing.html", title: "Distributed Request Tracing", order: 120, overview: "How to configure the proxies to send tracing requests to Zipkin"}); genNavBarTree(docs) </script></ul></div><div id="tab-container" class="col-xs-1 tab-neg-margin pull-left"> <a id="sidebar-tab" class="glyphicon glyphicon-chevron-left" href="javascript:void 0;"></a></div><div id="content-container" class="thin-left-border col-sm-9 markdown"><div id="toc" class="toc"></div><div id="doc-content"><h1>Enabling Rate Limits</h1><p>This task shows you how to use Istio to dynamically limit the traffic to a service.</p><h2 id="before-you-begin">Before you begin</h2><ul><li><p>Setup Istio by following the instructions in the <a href="./installing-istio.html">Installation guide</a>.</p></li><li><p>Deploy the <a href="/v0.1/docs/samples/bookinfo.html">BookInfo</a> sample application.</p></li><li><p>Initialize the application version routing to direct <code>reviews</code> service requests from test user “jason” to version v2 and requests from any other user to v3.</p><pre><code class="language-bash">istioctl create -f samples/apps/bookinfo/route-rule-reviews-test-v2.yaml
|
||
istioctl create -f samples/apps/bookinfo/route-rule-reviews-v3.yaml
|
||
</code></pre><blockquote><p>Note: if you have conflicting rule that you set in previous tasks, use <code>istioctl replace</code> instead of <code>istioctl create</code>.</p></blockquote></li></ul><h2 id="rate-limits">Rate limits</h2><p>Istio enables users to rate limit traffic to a service.</p><p>Consider <code>ratings</code> as an external paid service like Rotten Tomatoes® with <code>1qps</code> free quota. Using Istio we can ensure that <code>1qps</code> is not breached.</p><ol><li><p>Point your browser at the BookInfo <code>productpage</code> (http://$GATEWAY_URL/productpage).</p><p>If you log in as user “jason”, you should see black ratings stars with each review, indicating that the <code>ratings</code> service is being called by the “v2” version of the <code>reviews</code> service.</p><p>If you log in as any other user (or logout) you should see red ratings stars with each review, indicating that the <code>ratings</code> service is being called by the “v3” version of the <code>reviews</code> service.</p></li><li><p>Configure mixer with the rate limit.</p><p>Save this as ratelimit.yaml:</p><pre><code class="language-yaml">rules:
|
||
- aspects:
|
||
- kind: quotas
|
||
params:
|
||
quotas:
|
||
- descriptorName: RequestCount
|
||
maxAmount: 1
|
||
expiration: 1s
|
||
</code></pre><p>and then run the following command:</p><pre><code class="language-bash">istioctl mixer rule create global ratings.default.svc.cluster.local -f ratelimit.yaml
|
||
</code></pre><p><code>istioctl</code> sets configuration for <code>subject=ratings.default.svc.cluster.local</code></p></li><li><p>Generate load on the <code>productpage</code> with the following command:</p><pre><code class="language-bash">while true; do curl -s -o /dev/null http://$GATEWAY_URL/productpage; done
|
||
</code></pre></li><li><p>Refresh the <code>productpage</code> in your browser.</p><p>While the load generator is running (i.e., generating more than 1 req/s), the traffic generated by your browser will be rate limited. Notice that if you log in as user “jason” or any other user, the <code>reviews</code> service is unable to access the <code>ratings</code> service, so you stop seeing stars, red or black.</p></li></ol><h2 id="conditional-rate-limits">Conditional rate limits</h2><p>In the previous example we applied a rate limit to the <code>ratings</code> service without regard to any other attributes. It is possible to conditionally apply rate limits based on attributes like the source of the traffic.</p><p>The following configuration applies a <code>1qps</code> rate limit only to version <code>v3</code> of <code>reviews</code>.</p><ol><li><p>Configure mixer with the conditional rate limit.</p><p>Save this as ratelimit-conditional.yaml:</p><pre><code class="language-yaml">rules:
|
||
- selector: source.labels["app"]=="reviews" && source.labels["version"] == "v3"
|
||
aspects:
|
||
- kind: quotas
|
||
params:
|
||
quotas:
|
||
- descriptorName: RequestCount
|
||
maxAmount: 1
|
||
expiration: 1s
|
||
</code></pre><p>and then run the following command:</p><pre><code class="language-bash">istioctl mixer rule create global ratings.default.svc.cluster.local -f ratelimit-conditional.yaml
|
||
</code></pre><p>Notice the rule is the same as the previous example, only this one uses a <code>selector</code> to apply the ratelimit only for requests from <code>reviews:v3</code>.</p></li><li><p>Generate load on the <code>productpage</code> with the following command:</p><pre><code class="language-bash">while true; do curl -s -o /dev/null http://$GATEWAY_URL/productpage; done
|
||
</code></pre></li><li><p>Refresh the <code>productpage</code> in your browser.</p><p>As in the previous example, while the load generator is running (i.e., generating more than 1 req/s), the traffic generated by your browser will be rate limited, but this time only if the request is from <code>reviews:v3</code>. Notice that this time if you log in as user “jason” (the <code>reviews:v2</code> user) you will continue to see the black ratings stars. Only the other users will stop seeing the red ratings stars while the load generator is running.</p></li></ol><h2 id="understanding-rate-limits">Understanding rate limits</h2><p>In the preceding examples we saw how Mixer applies rate limits to requests that match certain conditions.</p><p>Every distinct rate limit configuration represents a counter. If the number of requests in the last <code>expiration</code> duration exceed <code>maxAmount</code>, Mixer returns a <code>RESOURCE_EXHAUSTED</code> message to the proxy. The proxy in turn returns status <code>HTTP 429</code> to the caller.</p><p>Multiple rate limits may apply to the same request.</p><p>Mixer <code>MemQuota</code> adapter uses a sliding window of sub second resolution to enforce rate limits.</p><p>Consider the following example</p><pre><code class="language-yaml">descriptorName: RequestCount
|
||
maxAmount: 5000
|
||
expiration: 5s
|
||
labels:
|
||
label1: target.service
|
||
</code></pre><p>This defines a set of counters with a limit of <code>5000</code> per every <code>5 seconds</code>. Individual counters within the set are identified by unique keys. A key is formed on the request path by using all parameters of the configuration. Here we introduce the notion of labels that enable creation of more granular counter keys. When a request arrives at Mixer with <code>target.service=ratings</code> it forms the following counter key.</p><p><code>$aspect_id;RequestCount;maxAmount=5000;expiration=5s;label1=ratings</code></p><p>Using <code>target.service</code> in the counter key enables independent rate limits for every service. In absence of <code>target.service</code> as part of the key, the same counter location is used by all services resulting in combined rate limit of <code>5000</code> requests per <code>5 seconds</code></p><p>Mixer supports an arbitrary number of labels by defining <code>QuotaDescriptors</code>.</p><pre><code class="language-yaml">name: RequestCount
|
||
rate_limit: true
|
||
labels:
|
||
label1: 1 # STRING
|
||
</code></pre><p>Here we define <code>RequestCount</code> quota descriptor that takes 1 string label. We recommend using meaningful label names even though label names are arbitrary.</p><pre><code class="language-yaml">name: RequestCount_byService_byUser
|
||
rate_limit: true
|
||
labels:
|
||
service: 1 # STRING
|
||
user: 1 # STRING
|
||
</code></pre><p>Mixer expects <code>user,service</code> labels when the <code>RequestCount_byService_byUser</code> descriptor is used and produces the following config validation error if any labels are missing.</p><pre><code class="language-bash">* quotas: aspect validation failed: 1 error occurred:
|
||
* quotas[RequestCount_byService_byUser].labels: wrong dimensions: descriptor expects 2 labels, found 0 labels
|
||
</code></pre><h2 id="cleanup">Cleanup</h2><ul><li><p>Remove the mixer configuration rule:</p><pre><code class="language-bash">istioctl mixer rule create global ratings.default.svc.cluster.local -f samples/apps/bookinfo/mixer-rule-empty-rule.yaml
|
||
</code></pre><blockquote><p>Note: removing a rule by setting an empty rule list is a temporary workaround because <code>istioctl delete</code> does not yet support mixer rules.</p></blockquote></li><li><p>Remove the application routing rules:</p><pre><code>istioctl delete -f samples/apps/bookinfo/route-rule-reviews-test-v2.yaml
|
||
istioctl delete -f samples/apps/bookinfo/route-rule-reviews-v3.yaml
|
||
</code></pre></li></ul><h2 id="whats-next">What’s next</h2><ul><li><p>Learn more about <a href="/v0.1/docs/concepts/policy-and-control/mixer.html">Mixer</a> and <a href="/v0.1/docs/concepts/policy-and-control/mixer-config.html">Mixer Config</a>.</p></li><li><p>Discover the full <a href="/v0.1/docs/reference/config/mixer/attribute-vocabulary.html">Attribute Vocabulary</a>.</p></li><li><p>Read the reference guide to <a href="/v0.1/docs/reference/writing-config.html">Writing Config</a>.</p></li><li><p>If you are not planning to explore any follow-on tasks, refer to the <a href="/v0.1/docs/samples/bookinfo.html#cleanup">BookInfo cleanup</a> instructions to shutdown the application and cleanup the associated rules.</p></li></ul></div></div></div></div></div></div><script src="/v0.1/js/sidemenu.js"></script><footer><div class="container"><div class="row"><div class="col-md-2"></div><div class="col-md-3 col-sm-4 col-xs-12 center-block"><ul class="toggle"><p class="header">Docs</p><li><a href="/v0.1/docs/">Welcome</a></li><li><a href="/v0.1/docs/concepts">Concepts</a></li><li><a href="/v0.1/docs/tasks">Tasks</a></li><li><a href="/v0.1/docs/samples">Samples</a></li><li><a href="/v0.1/docs/reference">Reference</a></li></ul></div><hr class="footer-sections" /><div class="col-md-3 col-sm-4 col-xs-12 center-block"><ul class="toggle"><p class="header">Resources</p><li><a href="/v0.1/faq">Frequently Asked Questions</a></li><li><a href="/v0.1/troubleshooting">Troubleshooting Guide</a></li><li><a href="/v0.1/bugs">Report a Bug</a></li><li><a href="https://github.com/istio/istio.github.io/issues/new?title=Issue with _docs/tasks/rate-limiting.md">Report a Doc Issue</a></li><li><a href="https://github.com/istio/istio.github.io/edit/master/_docs/tasks/rate-limiting.md">Edit This Page on GitHub</a></li></ul></div><hr class="footer-sections" /><div class="col-md-3 col-sm-4 col-xs-12 center-block"><ul class="toggle"><p class="header">Community</p><li><a href="https://groups.google.com/forum/#!forum/istio-users" target="_blank"><span class="group">User</span></a> | <a href="https://groups.google.com/forum/#!forum/istio-dev" target="_blank">Dev Mailing Lists</a></li><li><a href="https://twitter.com/IstioMesh" target="_blank"><span class="twitter">Twitter</span></a></li><li><a href="https://github.com/istio/istio" target="_blank"><span class="github">GitHub</span></a></li></ul></div><div class="col-md-1"></div></div><div class="row"><p class="description small text-center"> Copyright © 2017 Istio Authors<br> Istio 0.1<br> Archived on 20-Jul-2017</p></div></div></footer><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.15.0/jquery.validate.min.js"></script> <script src="/v0.1/js/jquery.form.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script> <script src="/v0.1/js/slick.min.js"></script> <script src="/v0.1/js/jquery.visible.min.js"></script> <script src="/v0.1/js/common.js" type="text/javascript" charset="utf-8"></script> <script src="/v0.1/js/buttons.js"></script> <script src="/v0.1/js/search.js"></script> <script src="/v0.1/js/prism.js"></script></body></html>
|