mirror of https://github.com/istio/istio.io.git
160 lines
32 KiB
HTML
160 lines
32 KiB
HTML
<!doctype html><html lang=en itemscope itemtype=https://schema.org/WebPage><head><meta charset=utf-8><meta http-equiv=x-ua-compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name=theme-color content="#466BB0"><meta name=title content="Canary Deployments using Istio"><meta name=description content="Using Istio to create autoscaled canary deployments."><meta name=author content="Frank Budinsky"><meta name=keywords content="microservices,services,mesh,traffic-management,canary"><meta property="og:title" content="Canary Deployments using Istio"><meta property="og:type" content="website"><meta property="og:description" content="Using Istio to create autoscaled canary deployments."><meta property="og:url" content="/v1.14/blog/2017/0.1-canary/"><meta property="og:image" content="https://raw.githubusercontent.com/istio/istio.io/master/static/img/istio-whitelogo-bluebackground-framed.svg"><meta property="og:image:alt" content="Istio Logo"><meta property="og:image:width" content="1024"><meta property="og:image:height" content="1024"><meta property="og:site_name" content="Istio"><meta name=twitter:card content="summary"><meta name=twitter:site content="@IstioMesh"><title>Istioldie 1.14 / Canary Deployments using Istio</title><script async src="https://www.googletagmanager.com/gtag/js?id=UA-98480406-2"></script>
|
||
<script>window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments)}gtag("js",new Date),gtag("config","UA-98480406-2")</script><link rel=alternate type=application/rss+xml title="Istio Blog" href=/v1.14/blog/feed.xml><link rel=alternate type=application/rss+xml title="Istio News" href=/v1.14/news/feed.xml><link rel=alternate type=application/rss+xml title="Istio Blog and News" href=/v1.14/feed.xml><link rel="shortcut icon" href=/v1.14/favicons/favicon.ico><link rel=apple-touch-icon href=/v1.14/favicons/apple-touch-icon-180x180.png sizes=180x180><link rel=icon type=image/png href=/v1.14/favicons/favicon-16x16.png sizes=16x16><link rel=icon type=image/png href=/v1.14/favicons/favicon-32x32.png sizes=32x32><link rel=icon type=image/png href=/v1.14/favicons/android-36x36.png sizes=36x36><link rel=icon type=image/png href=/v1.14/favicons/android-48x48.png sizes=48x48><link rel=icon type=image/png href=/v1.14/favicons/android-72x72.png sizes=72x72><link rel=icon type=image/png href=/v1.14/favicons/android-96x96.png sizes=96xW96><link rel=icon type=image/png href=/v1.14/favicons/android-144x144.png sizes=144x144><link rel=icon type=image/png href=/v1.14/favicons/android-192x192.png sizes=192x192><link rel=icon type=image/svg+xml href=/v1.14/favicons/favicon.svg><link rel=icon type=image/png href=/v1.14/favicons/favicon.png><link rel=mask-icon href=/v1.14/favicons/safari-pinned-tab.svg color=#466bb0><link rel=manifest href=/v1.14/manifest.json><meta name=apple-mobile-web-app-title content="Istio"><meta name=application-name content="Istio"><meta name=msapplication-config content="/browserconfig.xml"><meta name=msapplication-TileColor content="#466BB0"><meta name=theme-color content="#466BB0"><link rel=stylesheet href=/v1.14/css/all.css><link rel=preconnect href=https://fonts.gstatic.com><link rel=stylesheet href="https://fonts.googleapis.com/css2?family=Barlow:ital,wght@0,400;0,500;0,600;0,700;1,400;1,600&display=swap"><script src=/v1.14/js/themes_init.min.js></script></head><body class="language-unknown archive-site"><script>const branchName="release-1.14",docTitle="Canary Deployments using Istio",iconFile="/v1.14/img/icons.svg",buttonCopy="Copy to clipboard",buttonPrint="Print",buttonDownload="Download"</script><script src="https://www.google.com/cse/brand?form=search-form" defer></script>
|
||
<script src=/v1.14/js/all.min.js data-manual defer></script><header class=main-navigation><nav class="main-navigation-wrapper container-l"><div class=main-navigation-header><a id=brand href=/v1.14/ aria-label=logotype><span class=logo><svg xmlns="http://www.w3.org/2000/svg" width="128" height="60" viewBox="0 0 128 60"><path d="M58.434 48.823A.441.441.0 0158.3 48.497V22.583a.444.444.0 01.134-.326.446.446.0 01.327-.134h3.527a.447.447.0 01.325.134.447.447.0 01.134.326v25.914a.443.443.0 01-.134.326.444.444.0 01-.325.134h-3.527a.444.444.0 01-.327-.134z"/><path d="m70.969 48.477a6.556 6.556.0 01-2.818-1.955 4.338 4.338.0 01-1-2.78v-.345a.443.443.0 01.134-.326.444.444.0 01.326-.135h3.374a.444.444.0 01.326.135.445.445.0 01.134.326v.077a2.014 2.014.0 001.054 1.667 4.672 4.672.0 002.664.709 4.446 4.446.0 002.492-.633 1.862 1.862.0 00.958-1.591 1.426 1.426.0 00-.786-1.322 12.7 12.7.0 00-2.549-.939l-1.457-.46a21.526 21.526.0 01-3.3-1.227 6.57 6.57.0 01-2.262-1.783 4.435 4.435.0 01-.92-2.894 5.081 5.081.0 012.109-4.275 8.993 8.993.0 015.558-1.591 10.445 10.445.0 014.1.748 6.3 6.3.0 012.722 2.07 5 5 0 01.958 3.009.441.441.0 01-.134.326.441.441.0 01-.325.134h-3.258a.441.441.0 01-.326-.134.443.443.0 01-.134-.326 1.974 1.974.0 00-.978-1.667 4.647 4.647.0 00-2.665-.671 4.741 4.741.0 00-2.435.556 1.724 1.724.0 00-.938 1.553 1.512 1.512.0 00.9 1.4 15.875 15.875.0 003.01 1.055l.843.229a27.368 27.368.0 013.412 1.246 6.67 6.67.0 012.338 1.763 4.387 4.387.0 01.958 2.933 4.988 4.988.0 01-2.146 4.275 9.543 9.543.0 01-5.712 1.552 11.626 11.626.0 01-4.227-.709z"/><path d="m97.039 32.837a.443.443.0 01-.326.135h-3.911a.169.169.0 00-.191.192v9.239a2.951 2.951.0 00.632 2.108 2.7 2.7.0 002.013.652h1.15a.444.444.0 01.325.134.441.441.0 01.134.326v2.875a.471.471.0 01-.459.5l-1.994.039a8 8 0 01-4.524-1.035q-1.495-1.035-1.533-3.91V33.166A.17.17.0 0088.164 32.974H85.978A.441.441.0 0185.652 32.839.441.441.0 0185.518 32.513V29.83a.441.441.0 01.134-.326.444.444.0 01.326-.135h2.186a.169.169.0 00.191-.192v-4.485a.438.438.0 01.134-.326.44.44.0 01.325-.134h3.336a.443.443.0 01.325.134.442.442.0 01.135.326v4.485a.169.169.0 00.191.192h3.911a.446.446.0 01.326.135.446.446.0 01.134.326v2.683a.446.446.0 01-.133.324z"/><path d="m101.694 25.917a2.645 2.645.0 01-.767-1.955 2.65 2.65.0 01.767-1.955 2.65 2.65.0 011.955-.767 2.65 2.65.0 011.955.767 2.652 2.652.0 01.767 1.955 2.647 2.647.0 01-.767 1.955 2.646 2.646.0 01-1.955.767 2.645 2.645.0 01-1.955-.767zm-.211 22.906a.441.441.0 01-.134-.326V29.79a.444.444.0 01.134-.326.446.446.0 01.326-.134h3.527a.446.446.0 01.326.134.445.445.0 01.134.326v18.707a.443.443.0 01-.134.326.443.443.0 01-.326.134h-3.527a.443.443.0 01-.326-.134z"/><path d="m114.019 47.734a8.1 8.1.0 01-3.047-4.255 14.439 14.439.0 01-.652-4.37 14.3 14.3.0 01.614-4.371A7.869 7.869.0 01114 30.56a9.072 9.072.0 015.252-1.5 8.543 8.543.0 015.041 1.5 7.985 7.985.0 013.009 4.14 12.439 12.439.0 01.69 4.37 13.793 13.793.0 01-.651 4.37 8.255 8.255.0 01-3.028 4.275 8.475 8.475.0 01-5.1 1.553 8.754 8.754.0 01-5.194-1.534zm7.629-3.1a4.536 4.536.0 001.476-2.262 11.335 11.335.0 00.383-3.221 10.618 10.618.0 00-.383-3.22 4.169 4.169.0 00-1.457-2.243 4.066 4.066.0 00-2.531-.785 3.942 3.942.0 00-2.453.785 4.376 4.376.0 00-1.5 2.243 11.839 11.839.0 00-.383 3.22 11.84 11.84.0 00.383 3.221 4.222 4.222.0 001.476 2.262 4.075 4.075.0 002.549.8 3.8 3.8.0 002.44-.809z"/><path d="m15.105 32.057v15.565a.059.059.0 01-.049.059L.069 50.25A.06.06.0 01.005 50.167l14.987-33.47a.06.06.0 01.114.025z"/><path d="m17.631 23.087v24.6a.06.06.0 00.053.059l22.449 2.507a.06.06.0 00.061-.084L17.745.032a.06.06.0 00-.114.024z"/><path d="m39.961 52.548-24.833 7.45a.062.062.0 01-.043.0L.079 52.548a.059.059.0 01.026-.113h39.839a.06.06.0 01.017.113z"/></svg></span></a><button id=hamburger class=main-navigation-toggle aria-label="Open navigation"><svg class="icon menu-hamburger"><use xlink:href="/v1.14/img/icons.svg#menu-hamburger"/></svg></button>
|
||
<button id=menu-close class=main-navigation-toggle aria-label="Close navigation"><svg class="icon menu-close"><use xlink:href="/v1.14/img/icons.svg#menu-close"/></svg></button></div><div id=header-links class=main-navigation-links-wrapper><ul class=main-navigation-links><li class=main-navigation-links-item><a class="main-navigation-links-link has-dropdown"><span>About</span><svg class="icon dropdown-arrow"><use xlink:href="/v1.14/img/icons.svg#dropdown-arrow"/></svg></a><ul class=main-navigation-links-dropdown><li class=main-navigation-links-dropdown-item><a href=/v1.14/about/service-mesh class=main-navigation-links-link>Service mesh</a></li><li class=main-navigation-links-dropdown-item><a href=/v1.14/about/solutions class=main-navigation-links-link>Solutions</a></li><li class=main-navigation-links-dropdown-item><a href=/v1.14/about/case-studies class=main-navigation-links-link>Case studies</a></li><li class=main-navigation-links-dropdown-item><a href=/v1.14/about/ecosystem class=main-navigation-links-link>Ecosystem</a></li><li class=main-navigation-links-dropdown-item><a href=/v1.14/about/deployment class=main-navigation-links-link>Deployment</a></li><li class=main-navigation-links-dropdown-item><a href=/v1.14/about/faq class=main-navigation-links-link>FAQ</a></li></ul></li><li class=main-navigation-links-item><a href=/v1.14/blog/ class=main-navigation-links-link><span>Blog</span></a></li><li class=main-navigation-links-item><a href=/v1.14/news/ class=main-navigation-links-link><span>News</span></a></li><li class=main-navigation-links-item><a href=/v1.14/get-involved/ class=main-navigation-links-link><span>Get involved</span></a></li><li class=main-navigation-links-item><a href=/v1.14/docs/ class=main-navigation-links-link><span>Documentation</span></a></li></ul><div class=main-navigation-footer><button id=search-show class=search-show title="Search this site" aria-label=Search><svg class="icon magnifier"><use xlink:href="/v1.14/img/icons.svg#magnifier"/></svg></button>
|
||
<a href=/v1.14/docs/setup/getting-started class="btn btn--primary" id=try-istio>Try Istio</a></div></div><form id=search-form class=search name=cse role=search><input type=hidden name=cx value=002184991200833970123:iwwf17ikgf4>
|
||
<input type=hidden name=ie value=utf-8>
|
||
<input type=hidden name=hl value=en>
|
||
<input type=hidden id=search-page-url value=/search>
|
||
<input id=search-textbox class="search-textbox form-control" name=q type=search aria-label="Search this site" placeholder=Search>
|
||
<button id=search-close title="Cancel search" type=reset aria-label="Cancel search"><svg class="icon menu-close"><use xlink:href="/v1.14/img/icons.svg#menu-close"/></svg></button></form></nav></header><div class=banner-container></div><article class=post itemscope itemtype=http://schema.org/BlogPosting><div class=header-content><h1>Canary Deployments using Istio</h1><p>Using Istio to create autoscaled canary deployments.</p></div><p class=post-author>Jun 14, 2017 <span>|</span> By Frank Budinsky</p><div><div><aside class="callout tip"><div class=type><svg class="large-icon"><use xlink:href="/v1.14/img/icons.svg#callout-tip"/></svg></div><div class=content>This post was updated on May 16, 2018 to use the latest version of the traffic management model.</div></aside></div><p>One of the benefits of the <a href=/v1.14/>Istio</a> project is that it provides the control needed to deploy canary services. The idea behind
|
||
canary deployment (or rollout) is to introduce a new version of a service by first testing it using a small percentage of user
|
||
traffic, and then if all goes well, increase, possibly gradually in increments, the percentage while simultaneously phasing out
|
||
the old version. If anything goes wrong along the way, we abort and roll back to the previous version. In its simplest form,
|
||
the traffic sent to the canary version is a randomly selected percentage of requests, but in more sophisticated schemes it
|
||
can be based on the region, user, or other properties of the request.</p><p>Depending on your level of expertise in this area, you may wonder why Istio’s support for canary deployment is even needed, given that platforms like Kubernetes already provide a way to do <a href=https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#updating-a-deployment>version rollout</a> and <a href=https://kubernetes.io/docs/concepts/cluster-administration/manage-deployment/#canary-deployments>canary deployment</a>. Problem solved, right? Well, not exactly. Although doing a rollout this way works in simple cases, it’s very limited, especially in large scale cloud environments receiving lots of (and especially varying amounts of) traffic, where autoscaling is needed.</p><h2 id=canary-deployment-in-kubernetes>Canary deployment in Kubernetes</h2><p>As an example, let’s say we have a deployed service, <strong>helloworld</strong> version <strong>v1</strong>, for which we would like to test (or simply roll out) a new version, <strong>v2</strong>. Using Kubernetes, you can roll out a new version of the <strong>helloworld</strong> service by simply updating the image in the service’s corresponding <a href=https://kubernetes.io/docs/concepts/workloads/controllers/deployment/>Deployment</a> and letting the <a href=https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#updating-a-deployment>rollout</a> happen automatically. If we take particular care to ensure that there are enough <strong>v1</strong> replicas running when we start and <a href=https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#pausing-and-resuming-a-deployment>pause</a> the rollout after only one or two <strong>v2</strong> replicas have been started, we can keep the canary’s effect on the system very small. We can then observe the effect before deciding to proceed or, if necessary, <a href=https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#rolling-back-a-deployment>roll back</a>. Best of all, we can even attach a <a href=https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#scaling-a-deployment>horizontal pod autoscaler</a> to the Deployment and it will keep the replica ratios consistent if, during the rollout process, it also needs to scale replicas up or down to handle traffic load.</p><p>Although fine for what it does, this approach is only useful when we have a properly tested version that we want to deploy, i.e., more of a blue/green, a.k.a. red/black, kind of upgrade than a “dip your feet in the water” kind of canary deployment. In fact, for the latter (for example, testing a canary version that may not even be ready or intended for wider exposure), the canary deployment in Kubernetes would be done using two Deployments with <a href=https://kubernetes.io/docs/concepts/cluster-administration/manage-deployment/#using-labels-effectively>common pod labels</a>. In this case, we can’t use autoscaling anymore because it’s now being done by two independent autoscalers, one for each Deployment, so the replica ratios (percentages) may vary from the desired ratio, depending purely on load.</p><p>Whether we use one deployment or two, canary management using deployment features of container orchestration platforms like Docker, Mesos/Marathon, or Kubernetes has a fundamental problem: the use of instance scaling to manage the traffic; traffic version distribution and replica deployment are not independent in these systems. All replica pods, regardless of version, are treated the same in the <code>kube-proxy</code> round-robin pool, so the only way to manage the amount of traffic that a particular version receives is by controlling the replica ratio. Maintaining canary traffic at small percentages requires many replicas (e.g., 1% would require a minimum of 100 replicas). Even if we ignore this problem, the deployment approach is still very limited in that it only supports the simple (random percentage) canary approach. If, instead, we wanted to limit the visibility of the canary to requests based on some specific criteria, we still need another solution.</p><h2 id=enter-istio>Enter Istio</h2><p>With Istio, traffic routing and replica deployment are two completely independent functions. The number of pods implementing services are free to scale up and down based on traffic load, completely orthogonal to the control of version traffic routing. This makes managing a canary version in the presence of autoscaling a much simpler problem. Autoscalers may, in fact, respond to load variations resulting from traffic routing changes, but they are nevertheless functioning independently and no differently than when loads change for other reasons.</p><p>Istio’s <a href=/v1.14/docs/concepts/traffic-management/#routing-rules>routing rules</a> also provide other important advantages; you can easily control
|
||
fine-grained traffic percentages (e.g., route 1% of traffic without requiring 100 pods) and you can control traffic using other criteria (e.g., route traffic for specific users to the canary version). To illustrate, let’s look at deploying the <strong>helloworld</strong> service and see how simple the problem becomes.</p><p>We begin by defining the <strong>helloworld</strong> Service, just like any other Kubernetes service, something like this:</p><pre><code class=language-yaml data-expandlinks=true data-repo=istio>apiVersion: v1
|
||
kind: Service
|
||
metadata:
|
||
name: helloworld
|
||
labels:
|
||
app: helloworld
|
||
spec:
|
||
selector:
|
||
app: helloworld
|
||
...
|
||
</code></pre><p>We then add 2 Deployments, one for each version (<strong>v1</strong> and <strong>v2</strong>), both of which include the service selector’s <code>app: helloworld</code> label:</p><pre><code class=language-yaml data-expandlinks=true data-repo=istio>apiVersion: apps/v1
|
||
kind: Deployment
|
||
metadata:
|
||
name: helloworld-v1
|
||
spec:
|
||
replicas: 1
|
||
template:
|
||
metadata:
|
||
labels:
|
||
app: helloworld
|
||
version: v1
|
||
spec:
|
||
containers:
|
||
- image: helloworld-v1
|
||
...
|
||
---
|
||
apiVersion: apps/v1
|
||
kind: Deployment
|
||
metadata:
|
||
name: helloworld-v2
|
||
spec:
|
||
replicas: 1
|
||
template:
|
||
metadata:
|
||
labels:
|
||
app: helloworld
|
||
version: v2
|
||
spec:
|
||
containers:
|
||
- image: helloworld-v2
|
||
...
|
||
</code></pre><p>Note that this is exactly the same way we would do a <a href=https://kubernetes.io/docs/concepts/cluster-administration/manage-deployment/#canary-deployments>canary deployment</a> using plain Kubernetes, but in that case we would need to adjust the number of replicas of each Deployment to control the distribution of traffic. For example, to send 10% of the traffic to the canary version (<strong>v2</strong>), the replicas for <strong>v1</strong> and <strong>v2</strong> could be set to 9 and 1, respectively.</p><p>However, since we are going to deploy the service in an <a href=/v1.14/docs/setup/>Istio enabled</a> cluster, all we need to do is set a routing
|
||
rule to control the traffic distribution. For example if we want to send 10% of the traffic to the canary, we could use <code>kubectl</code>
|
||
to set a routing rule something like this:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl apply -f - <<EOF
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: VirtualService
|
||
metadata:
|
||
name: helloworld
|
||
spec:
|
||
hosts:
|
||
- helloworld
|
||
http:
|
||
- route:
|
||
- destination:
|
||
host: helloworld
|
||
subset: v1
|
||
weight: 90
|
||
- destination:
|
||
host: helloworld
|
||
subset: v2
|
||
weight: 10
|
||
---
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: DestinationRule
|
||
metadata:
|
||
name: helloworld
|
||
spec:
|
||
host: helloworld
|
||
subsets:
|
||
- name: v1
|
||
labels:
|
||
version: v1
|
||
- name: v2
|
||
labels:
|
||
version: v2
|
||
EOF
|
||
</code></pre><p>After setting this rule, Istio will ensure that only one tenth of the requests will be sent to the canary version, regardless of how many replicas of each version are running.</p><h2 id=autoscaling-the-deployments>Autoscaling the deployments</h2><p>Because we don’t need to maintain replica ratios anymore, we can safely add Kubernetes <a href=https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/>horizontal pod autoscalers</a> to manage the replicas for both version Deployments:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl autoscale deployment helloworld-v1 --cpu-percent=50 --min=1 --max=10
|
||
deployment "helloworld-v1" autoscaled
|
||
</code></pre><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl autoscale deployment helloworld-v2 --cpu-percent=50 --min=1 --max=10
|
||
deployment "helloworld-v2" autoscaled
|
||
</code></pre><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl get hpa
|
||
NAME REFERENCE TARGET CURRENT MINPODS MAXPODS AGE
|
||
Helloworld-v1 Deployment/helloworld-v1 50% 47% 1 10 17s
|
||
Helloworld-v2 Deployment/helloworld-v2 50% 40% 1 10 15s
|
||
</code></pre><p>If we now generate some load on the <strong>helloworld</strong> service, we would notice that when scaling begins, the <strong>v1</strong> autoscaler will scale up its replicas significantly higher than the <strong>v2</strong> autoscaler will for its replicas because <strong>v1</strong> pods are handling 90% of the load.</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl get pods | grep helloworld
|
||
helloworld-v1-3523621687-3q5wh 0/2 Pending 0 15m
|
||
helloworld-v1-3523621687-73642 2/2 Running 0 11m
|
||
helloworld-v1-3523621687-7hs31 2/2 Running 0 19m
|
||
helloworld-v1-3523621687-dt7n7 2/2 Running 0 50m
|
||
helloworld-v1-3523621687-gdhq9 2/2 Running 0 11m
|
||
helloworld-v1-3523621687-jxs4t 0/2 Pending 0 15m
|
||
helloworld-v1-3523621687-l8rjn 2/2 Running 0 19m
|
||
helloworld-v1-3523621687-wwddw 2/2 Running 0 15m
|
||
helloworld-v1-3523621687-xlt26 0/2 Pending 0 19m
|
||
helloworld-v2-4095161145-963wt 2/2 Running 0 50m
|
||
</code></pre><p>If we then change the routing rule to send 50% of the traffic to <strong>v2</strong>, we should, after a short delay, notice that the <strong>v1</strong> autoscaler will scale down the replicas of <strong>v1</strong> while the <strong>v2</strong> autoscaler will perform a corresponding scale up.</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl get pods | grep helloworld
|
||
helloworld-v1-3523621687-73642 2/2 Running 0 35m
|
||
helloworld-v1-3523621687-7hs31 2/2 Running 0 43m
|
||
helloworld-v1-3523621687-dt7n7 2/2 Running 0 1h
|
||
helloworld-v1-3523621687-gdhq9 2/2 Running 0 35m
|
||
helloworld-v1-3523621687-l8rjn 2/2 Running 0 43m
|
||
helloworld-v2-4095161145-57537 0/2 Pending 0 21m
|
||
helloworld-v2-4095161145-9322m 2/2 Running 0 21m
|
||
helloworld-v2-4095161145-963wt 2/2 Running 0 1h
|
||
helloworld-v2-4095161145-c3dpj 0/2 Pending 0 21m
|
||
helloworld-v2-4095161145-t2ccm 0/2 Pending 0 17m
|
||
helloworld-v2-4095161145-v3v9n 0/2 Pending 0 13m
|
||
</code></pre><p>The end result is very similar to the simple Kubernetes Deployment rollout, only now the whole process is not being orchestrated and managed in one place. Instead, we’re seeing several components doing their jobs independently, albeit in a cause and effect manner.
|
||
What’s different, however, is that if we now stop generating load, the replicas of both versions will eventually scale down to their minimum (1), regardless of what routing rule we set.</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl get pods | grep helloworld
|
||
helloworld-v1-3523621687-dt7n7 2/2 Running 0 1h
|
||
helloworld-v2-4095161145-963wt 2/2 Running 0 1h
|
||
</code></pre><h2 id=focused-canary-testing>Focused canary testing</h2><p>As mentioned above, the Istio routing rules can be used to route traffic based on specific criteria, allowing more sophisticated canary deployment scenarios. Say, for example, instead of exposing the canary to an arbitrary percentage of users, we want to try it out on internal users, maybe even just a percentage of them. The following command could be used to send 50% of traffic from users at <em>some-company-name.com</em> to the canary version, leaving all other users unaffected:</p><pre><code class=language-bash data-expandlinks=true data-repo=istio>$ kubectl apply -f - <<EOF
|
||
apiVersion: networking.istio.io/v1alpha3
|
||
kind: VirtualService
|
||
metadata:
|
||
name: helloworld
|
||
spec:
|
||
hosts:
|
||
- helloworld
|
||
http:
|
||
- match:
|
||
- headers:
|
||
cookie:
|
||
regex: "^(.*?;)?(email=[^;]*@some-company-name.com)(;.*)?$"
|
||
route:
|
||
- destination:
|
||
host: helloworld
|
||
subset: v1
|
||
weight: 50
|
||
- destination:
|
||
host: helloworld
|
||
subset: v2
|
||
weight: 50
|
||
- route:
|
||
- destination:
|
||
host: helloworld
|
||
subset: v1
|
||
EOF
|
||
</code></pre><p>As before, the autoscalers bound to the 2 version Deployments will automatically scale the replicas accordingly, but that will have no affect on the traffic distribution.</p><h2 id=summary>Summary</h2><p>In this article we’ve seen how Istio supports general scalable canary deployments, and how this differs from the basic deployment support in Kubernetes. Istio’s service mesh provides the control necessary to manage traffic distribution with complete independence from deployment scaling. This allows for a simpler, yet significantly more functional, way to do canary test and rollout.</p><p>Intelligent routing in support of canary deployment is just one of the many features of Istio that will make the production deployment of large-scale microservices-based applications much simpler. Check out <a href=/v1.14/>istio.io</a> for more information and to try it out.
|
||
The sample code used in this article can be found <a href=https://github.com/istio/istio/tree/release-1.14/samples/helloworld>here</a>.</p></div><nav class=pagenav><div class=left><a title="How Kubernetes Network Policy relates to Istio policy." href=/v1.14/blog/2017/0.1-using-network-policy/ class=next-link><svg class="icon left-arrow"><use xlink:href="/v1.14/img/icons.svg#left-arrow"/></svg>Using Network Policy with Istio</a></div><div class=right><a title="Istio Authentication 0.1 announcement." href=/v1.14/blog/2017/0.1-auth/ class=next-link>Using Istio to Improve End-to-End Security<svg class="icon right-arrow"><use xlink:href="/v1.14/img/icons.svg#right-arrow"/></svg></a></div></nav></article><footer class=footer><div class="footer-wrapper container-l"><div class="user-links footer-links"><a class=channel title="GitHub is where development takes place on Istio code" href=https://github.com/istio/community aria-label=GitHub><svg class="icon github"><use xlink:href="/v1.14/img/icons.svg#github"/></svg></a><a class=channel title="Access our team drive if you'd like to take a look at the Istio technical design documents" href=https://groups.google.com/forum/#!forum/istio-team-drive-access aria-label="team drive"><svg class="icon drive"><use xlink:href="/v1.14/img/icons.svg#drive"/></svg></a><a class=channel title="Interactively discuss issues with the Istio community on Slack" href=https://slack.istio.io aria-label=slack><svg class="icon slack"><use xlink:href="/v1.14/img/icons.svg#slack"/></svg></a><a class=channel title="Stack Overflow is where you can ask questions and find curated answers on deploying, configuring, and using Istio" href=https://stackoverflow.com/questions/tagged/istio aria-label="Stack Overflow"><svg class="icon stackoverflow"><use xlink:href="/v1.14/img/icons.svg#stackoverflow"/></svg></a><a class=channel title="Follow us on Twitter to get the latest news" href=https://twitter.com/IstioMesh aria-label=Twitter><svg class="icon twitter"><use xlink:href="/v1.14/img/icons.svg#twitter"/></svg></a></div><hr class=footer-separator role=separator><div class="info footer-info"><a class=logo href=/v1.14/ aria-label=logotype><svg xmlns="http://www.w3.org/2000/svg" width="128" height="60" viewBox="0 0 128 60"><path d="M58.434 48.823A.441.441.0 0158.3 48.497V22.583a.444.444.0 01.134-.326.446.446.0 01.327-.134h3.527a.447.447.0 01.325.134.447.447.0 01.134.326v25.914a.443.443.0 01-.134.326.444.444.0 01-.325.134h-3.527a.444.444.0 01-.327-.134z"/><path d="m70.969 48.477a6.556 6.556.0 01-2.818-1.955 4.338 4.338.0 01-1-2.78v-.345a.443.443.0 01.134-.326.444.444.0 01.326-.135h3.374a.444.444.0 01.326.135.445.445.0 01.134.326v.077a2.014 2.014.0 001.054 1.667 4.672 4.672.0 002.664.709 4.446 4.446.0 002.492-.633 1.862 1.862.0 00.958-1.591 1.426 1.426.0 00-.786-1.322 12.7 12.7.0 00-2.549-.939l-1.457-.46a21.526 21.526.0 01-3.3-1.227 6.57 6.57.0 01-2.262-1.783 4.435 4.435.0 01-.92-2.894 5.081 5.081.0 012.109-4.275 8.993 8.993.0 015.558-1.591 10.445 10.445.0 014.1.748 6.3 6.3.0 012.722 2.07 5 5 0 01.958 3.009.441.441.0 01-.134.326.441.441.0 01-.325.134h-3.258a.441.441.0 01-.326-.134.443.443.0 01-.134-.326 1.974 1.974.0 00-.978-1.667 4.647 4.647.0 00-2.665-.671 4.741 4.741.0 00-2.435.556 1.724 1.724.0 00-.938 1.553 1.512 1.512.0 00.9 1.4 15.875 15.875.0 003.01 1.055l.843.229a27.368 27.368.0 013.412 1.246 6.67 6.67.0 012.338 1.763 4.387 4.387.0 01.958 2.933 4.988 4.988.0 01-2.146 4.275 9.543 9.543.0 01-5.712 1.552 11.626 11.626.0 01-4.227-.709z"/><path d="m97.039 32.837a.443.443.0 01-.326.135h-3.911a.169.169.0 00-.191.192v9.239a2.951 2.951.0 00.632 2.108 2.7 2.7.0 002.013.652h1.15a.444.444.0 01.325.134.441.441.0 01.134.326v2.875a.471.471.0 01-.459.5l-1.994.039a8 8 0 01-4.524-1.035q-1.495-1.035-1.533-3.91V33.166A.17.17.0 0088.164 32.974H85.978A.441.441.0 0185.652 32.839.441.441.0 0185.518 32.513V29.83a.441.441.0 01.134-.326.444.444.0 01.326-.135h2.186a.169.169.0 00.191-.192v-4.485a.438.438.0 01.134-.326.44.44.0 01.325-.134h3.336a.443.443.0 01.325.134.442.442.0 01.135.326v4.485a.169.169.0 00.191.192h3.911a.446.446.0 01.326.135.446.446.0 01.134.326v2.683a.446.446.0 01-.133.324z"/><path d="m101.694 25.917a2.645 2.645.0 01-.767-1.955 2.65 2.65.0 01.767-1.955 2.65 2.65.0 011.955-.767 2.65 2.65.0 011.955.767 2.652 2.652.0 01.767 1.955 2.647 2.647.0 01-.767 1.955 2.646 2.646.0 01-1.955.767 2.645 2.645.0 01-1.955-.767zm-.211 22.906a.441.441.0 01-.134-.326V29.79a.444.444.0 01.134-.326.446.446.0 01.326-.134h3.527a.446.446.0 01.326.134.445.445.0 01.134.326v18.707a.443.443.0 01-.134.326.443.443.0 01-.326.134h-3.527a.443.443.0 01-.326-.134z"/><path d="m114.019 47.734a8.1 8.1.0 01-3.047-4.255 14.439 14.439.0 01-.652-4.37 14.3 14.3.0 01.614-4.371A7.869 7.869.0 01114 30.56a9.072 9.072.0 015.252-1.5 8.543 8.543.0 015.041 1.5 7.985 7.985.0 013.009 4.14 12.439 12.439.0 01.69 4.37 13.793 13.793.0 01-.651 4.37 8.255 8.255.0 01-3.028 4.275 8.475 8.475.0 01-5.1 1.553 8.754 8.754.0 01-5.194-1.534zm7.629-3.1a4.536 4.536.0 001.476-2.262 11.335 11.335.0 00.383-3.221 10.618 10.618.0 00-.383-3.22 4.169 4.169.0 00-1.457-2.243 4.066 4.066.0 00-2.531-.785 3.942 3.942.0 00-2.453.785 4.376 4.376.0 00-1.5 2.243 11.839 11.839.0 00-.383 3.22 11.84 11.84.0 00.383 3.221 4.222 4.222.0 001.476 2.262 4.075 4.075.0 002.549.8 3.8 3.8.0 002.44-.809z"/><path d="m15.105 32.057v15.565a.059.059.0 01-.049.059L.069 50.25A.06.06.0 01.005 50.167l14.987-33.47a.06.06.0 01.114.025z"/><path d="m17.631 23.087v24.6a.06.06.0 00.053.059l22.449 2.507a.06.06.0 00.061-.084L17.745.032a.06.06.0 00-.114.024z"/><path d="m39.961 52.548-24.833 7.45a.062.062.0 01-.043.0L.079 52.548a.059.059.0 01.026-.113h39.839a.06.06.0 01.017.113z"/></svg></a><div class=footer-languages><a tabindex=-1 lang=en id=switch-lang-en class="footer-languages-item active"><svg class="icon tick"><use xlink:href="/v1.14/img/icons.svg#tick"/></svg>English</a>
|
||
<a tabindex=-1 lang=zh id=switch-lang-zh class=footer-languages-item>中文</a></div></div><ul class=footer-policies><li class=footer-policies-item><a class=footer-policies-link href=https://policies.google.com/privacy>Privacy policy</a> |
|
||
<a class=footer-policies-link href=https://github.com/istio/istio.io/edit/release-1.14/content/en/blog/2017/0.1-canary/index.md>Edit this Page on GitHub</a></li></ul><div class=footer-base><span class=footer-base-copyright>© 2022 Istio Authors.</span>
|
||
<span class=footer-base-version>Version
|
||
Archive
|
||
1.14.3</span><ul class=footer-base-releases><li class=footer-base-releases-item><a tabindex=-1 class=footer-base-releases-link onclick='return navigateToUrlOrRoot("https://istio.io/blog/2017/0.1-canary/"),!1'>current release</a></li><li class=footer-base-releases-item><a tabindex=-1 class=footer-base-releases-link onclick='return navigateToUrlOrRoot("https://preliminary.istio.io/blog/2017/0.1-canary/"),!1'>next release</a></li><li class=footer-base-releases-item><a tabindex=-1 class=footer-base-releases-link href=https://istio.io/archive>older releases</a></li></ul></div></div></footer><div id=scroll-to-top-container aria-hidden=true><button id=scroll-to-top title="Back to top" tabindex=-1><svg class="icon top"><use xlink:href="/v1.14/img/icons.svg#top"/></svg></button></div></body></html> |