mirror of
https://github.com/fluxcd/flagger.git
synced 2026-04-15 06:57:34 +00:00
161 lines
31 KiB
HTML
161 lines
31 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en-US">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>Deployment Strategies | Flagger</title>
|
|
<meta name="description" content="Progressive Delivery operator for Kubernetes (Canary, A/B Testing and Blue/Green deployments)">
|
|
<link rel="icon" href="/favicon.png">
|
|
<link rel="stylesheet" href="/website.css">
|
|
<meta name="keywords" content="gitops kubernetes flagger istio linkerd appmesh contour gloo nginx">
|
|
<meta name="twitter:card" content="summary_large_image">
|
|
<meta name="twitter:title" content="Flagger">
|
|
<meta name="twitter:description" content="Progressive delivery Kubernetes operator (Canary, A/B Testing and Blue/Green deployments)">
|
|
<meta name="twitter:image:src" content="https://flagger.app/flagger-overview.png">
|
|
|
|
<link rel="preload" href="/assets/css/0.styles.a0ada997.css" as="style"><link rel="preload" href="/assets/js/app.9b46ae46.js" as="script"><link rel="preload" href="/assets/js/2.ba5bf77c.js" as="script"><link rel="preload" href="/assets/js/31.fbfb336c.js" as="script"><link rel="prefetch" href="/assets/js/10.bf6f38d4.js"><link rel="prefetch" href="/assets/js/11.3af38cfe.js"><link rel="prefetch" href="/assets/js/12.eca4b89c.js"><link rel="prefetch" href="/assets/js/13.9104349a.js"><link rel="prefetch" href="/assets/js/14.a4f3d810.js"><link rel="prefetch" href="/assets/js/15.aada2caa.js"><link rel="prefetch" href="/assets/js/16.3012a10b.js"><link rel="prefetch" href="/assets/js/17.a98b6aa9.js"><link rel="prefetch" href="/assets/js/18.e5188926.js"><link rel="prefetch" href="/assets/js/19.bb9498f7.js"><link rel="prefetch" href="/assets/js/20.2b1bebf5.js"><link rel="prefetch" href="/assets/js/21.e1068843.js"><link rel="prefetch" href="/assets/js/22.1c5d14b9.js"><link rel="prefetch" href="/assets/js/23.b3dcc355.js"><link rel="prefetch" href="/assets/js/24.4f54d289.js"><link rel="prefetch" href="/assets/js/25.914acd1d.js"><link rel="prefetch" href="/assets/js/26.b2d4f402.js"><link rel="prefetch" href="/assets/js/27.ea9f1f9c.js"><link rel="prefetch" href="/assets/js/28.deae273d.js"><link rel="prefetch" href="/assets/js/29.ce4011f4.js"><link rel="prefetch" href="/assets/js/3.8b254d5d.js"><link rel="prefetch" href="/assets/js/30.edda19d9.js"><link rel="prefetch" href="/assets/js/32.591c3f2b.js"><link rel="prefetch" href="/assets/js/33.c456709f.js"><link rel="prefetch" href="/assets/js/34.5a071e36.js"><link rel="prefetch" href="/assets/js/35.fc27c09e.js"><link rel="prefetch" href="/assets/js/36.144098aa.js"><link rel="prefetch" href="/assets/js/4.26a3069c.js"><link rel="prefetch" href="/assets/js/5.0c32bdf9.js"><link rel="prefetch" href="/assets/js/6.ee5ffca3.js"><link rel="prefetch" href="/assets/js/7.6bf27a87.js"><link rel="prefetch" href="/assets/js/8.8b72a8d3.js"><link rel="prefetch" href="/assets/js/9.7919fc1d.js">
|
|
<link rel="stylesheet" href="/assets/css/0.styles.a0ada997.css">
|
|
</head>
|
|
<body>
|
|
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">Flagger</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="https://docs.flagger.app" target="_blank" rel="noopener noreferrer" class="nav-link external">
|
|
Docs
|
|
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div><div class="nav-item"><a href="https://github.com/weaveworks/flagger/blob/master/CHANGELOG.md" target="_blank" rel="noopener noreferrer" class="nav-link external">
|
|
Changelog
|
|
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <a href="https://github.com/weaveworks/flagger" target="_blank" rel="noopener noreferrer" class="repo-link">
|
|
GitHub
|
|
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="https://docs.flagger.app" target="_blank" rel="noopener noreferrer" class="nav-link external">
|
|
Docs
|
|
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div><div class="nav-item"><a href="https://github.com/weaveworks/flagger/blob/master/CHANGELOG.md" target="_blank" rel="noopener noreferrer" class="nav-link external">
|
|
Changelog
|
|
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <a href="https://github.com/weaveworks/flagger" target="_blank" rel="noopener noreferrer" class="repo-link">
|
|
GitHub
|
|
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav> <ul class="sidebar-links"><li><a href="/" class="sidebar-link">Home</a></li><li><section class="sidebar-group depth-0"><a href="/intro/" class="sidebar-heading clickable"><span>Introduction</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/intro/" class="sidebar-link">Get Started</a></li><li><a href="/intro/faq.html" class="sidebar-link">FAQ</a></li></ul></section></li><li><section class="sidebar-group depth-0"><a href="/install/flagger-install-on-kubernetes" class="sidebar-heading clickable"><span>Install</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/install/flagger-install-on-kubernetes.html" class="sidebar-link">On Kubernetes</a></li><li><a href="/install/flagger-install-on-google-cloud.html" class="sidebar-link">On GKE Istio</a></li><li><a href="/install/flagger-install-on-eks-appmesh.html" class="sidebar-link">On EKS App Mesh</a></li></ul></section></li><li><section class="sidebar-group depth-0"><a href="/usage/how-it-works" class="sidebar-heading clickable open"><span>Usage</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/usage/how-it-works.html" class="sidebar-link">How it works</a></li><li><a href="/usage/deployment-strategies.html" class="active sidebar-link">Deployment Strategies</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/usage/deployment-strategies.html#canary-release" class="sidebar-link">Canary Release</a></li><li class="sidebar-sub-header"><a href="/usage/deployment-strategies.html#a-b-testing" class="sidebar-link">A/B Testing</a></li><li class="sidebar-sub-header"><a href="/usage/deployment-strategies.html#blue-green-deployments" class="sidebar-link">Blue/Green Deployments</a></li><li class="sidebar-sub-header"><a href="/usage/deployment-strategies.html#blue-green-with-traffic-mirroring" class="sidebar-link">Blue/Green with Traffic Mirroring</a></li></ul></li><li><a href="/usage/metrics.html" class="sidebar-link">Metrics Analysis</a></li><li><a href="/usage/webhooks.html" class="sidebar-link">Webhooks</a></li><li><a href="/usage/alerting.html" class="sidebar-link">Alerting</a></li><li><a href="/usage/monitoring.html" class="sidebar-link">Monitoring</a></li></ul></section></li><li><section class="sidebar-group depth-0"><a href="/tutorials/istio-progressive-delivery" class="sidebar-heading clickable"><span>Tutorials</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/tutorials/istio-progressive-delivery.html" class="sidebar-link">Istio Canaries</a></li><li><a href="/tutorials/istio-ab-testing.html" class="sidebar-link">Istio A/B Testing</a></li><li><a href="/tutorials/linkerd-progressive-delivery.html" class="sidebar-link">Linkerd Canaries</a></li><li><a href="/tutorials/appmesh-progressive-delivery.html" class="sidebar-link">App Mesh Canaries</a></li><li><a href="/tutorials/nginx-progressive-delivery.html" class="sidebar-link">NGINX Ingress Canaries</a></li><li><a href="/tutorials/gloo-progressive-delivery.html" class="sidebar-link">Gloo Canaries</a></li><li><a href="/tutorials/contour-progressive-delivery.html" class="sidebar-link">Contour Canaries</a></li><li><a href="/tutorials/kubernetes-blue-green.html" class="sidebar-link">Kubernetes Blue/Green</a></li><li><a href="/tutorials/canary-helm-gitops.html" class="sidebar-link">Canaries with Helm charts and GitOps</a></li></ul></section></li><li><section class="sidebar-group depth-0"><a href="/dev/dev-guide" class="sidebar-heading clickable"><span>Dev</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/dev/dev-guide.html" class="sidebar-link">Development Guide</a></li><li><a href="/dev/release-guide.html" class="sidebar-link">Release Guide</a></li><li><a href="/dev/upgrade-guide.html" class="sidebar-link">Upgrade Guide</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="deployment-strategies"><a href="#deployment-strategies" aria-hidden="true" class="header-anchor">#</a> Deployment Strategies</h1> <p>Flagger can run automated application analysis, promotion and rollback for the following deployment strategies:</p> <ul><li><strong>Canary Release</strong> (progressive traffic shifting)
|
|
<ul><li>Istio, Linkerd, App Mesh, NGINX, Contour, Gloo</li></ul></li> <li><strong>A/B Testing</strong> (HTTP headers and cookies traffic routing)
|
|
<ul><li>Istio, App Mesh, NGINX, Contour</li></ul></li> <li><strong>Blue/Green</strong> (traffic switching)
|
|
<ul><li>Kubernetes CNI, Istio, Linkerd, App Mesh, NGINX, Contour, Gloo</li></ul></li> <li><strong>Blue/Green Mirroring</strong> (traffic shadowing)
|
|
<ul><li>Istio</li></ul></li></ul> <p>For Canary releases and A/B testing you'll need a Layer 7 traffic management solution like a service mesh or an ingress controller.
|
|
For Blue/Green deployments no service mesh or ingress controller is required.</p> <p>A canary analysis is triggered by changes in any of the following objects:</p> <ul><li>Deployment PodSpec (container image, command, ports, env, resources, etc)</li> <li>ConfigMaps mounted as volumes or mapped to environment variables</li> <li>Secrets mounted as volumes or mapped to environment variables</li></ul> <h2 id="canary-release"><a href="#canary-release" aria-hidden="true" class="header-anchor">#</a> Canary Release</h2> <p>Flagger implements a control loop that gradually shifts traffic to the canary while measuring key performance
|
|
indicators like HTTP requests success rate, requests average duration and pod health.
|
|
Based on analysis of the KPIs a canary is promoted or aborted.</p> <p><img src="https://raw.githubusercontent.com/weaveworks/flagger/master/docs/diagrams/flagger-canary-steps.png" alt="Flagger Canary Stages"></p> <p>The canary analysis runs periodically until it reaches the maximum traffic weight or the failed checks threshold.</p> <p>Spec:</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code> <span class="token key atrule">analysis</span><span class="token punctuation">:</span>
|
|
<span class="token comment"># schedule interval (default 60s)</span>
|
|
<span class="token key atrule">interval</span><span class="token punctuation">:</span> 1m
|
|
<span class="token comment"># max number of failed metric checks before rollback</span>
|
|
<span class="token key atrule">threshold</span><span class="token punctuation">:</span> <span class="token number">10</span>
|
|
<span class="token comment"># max traffic percentage routed to canary</span>
|
|
<span class="token comment"># percentage (0-100)</span>
|
|
<span class="token key atrule">maxWeight</span><span class="token punctuation">:</span> <span class="token number">50</span>
|
|
<span class="token comment"># canary increment step</span>
|
|
<span class="token comment"># percentage (0-100)</span>
|
|
<span class="token key atrule">stepWeight</span><span class="token punctuation">:</span> <span class="token number">2</span>
|
|
<span class="token comment"># deploy straight to production without</span>
|
|
<span class="token comment"># the metrics and webhook checks</span>
|
|
<span class="token key atrule">skipAnalysis</span><span class="token punctuation">:</span> <span class="token boolean important">false</span>
|
|
</code></pre></div><p>The above analysis, if it succeeds, will run for 25 minutes while validating the HTTP metrics and webhooks every minute.
|
|
You can determine the minimum time that it takes to validate and promote a canary deployment using this formula:</p> <div class="language- extra-class"><pre class="language-text"><code>interval * (maxWeight / stepWeight)
|
|
</code></pre></div><p>And the time it takes for a canary to be rollback when the metrics or webhook checks are failing:</p> <div class="language- extra-class"><pre class="language-text"><code>interval * threshold
|
|
</code></pre></div><p>In emergency cases, you may want to skip the analysis phase and ship changes directly to production.
|
|
At any time you can set the <code>spec.skipAnalysis: true</code>.
|
|
When skip analysis is enabled, Flagger checks if the canary deployment is healthy and
|
|
promotes it without analysing it. If an analysis is underway, Flagger cancels it and runs the promotion.</p> <p>Gated canary promotion stages:</p> <ul><li>scan for canary deployments</li> <li>check primary and canary deployment status
|
|
<ul><li>halt advancement if a rolling update is underway</li> <li>halt advancement if pods are unhealthy</li></ul></li> <li>call confirm-rollout webhooks and check results
|
|
<ul><li>halt advancement if any hook returns a non HTTP 2xx result</li></ul></li> <li>call pre-rollout webhooks and check results
|
|
<ul><li>halt advancement if any hook returns a non HTTP 2xx result</li> <li>increment the failed checks counter</li></ul></li> <li>increase canary traffic weight percentage from 0% to 2% (step weight)</li> <li>call rollout webhooks and check results</li> <li>check canary HTTP request success rate and latency
|
|
<ul><li>halt advancement if any metric is under the specified threshold</li> <li>increment the failed checks counter</li></ul></li> <li>check if the number of failed checks reached the threshold
|
|
<ul><li>route all traffic to primary</li> <li>scale to zero the canary deployment and mark it as failed</li> <li>call post-rollout webhooks</li> <li>post the analysis result to Slack</li> <li>wait for the canary deployment to be updated and start over</li></ul></li> <li>increase canary traffic weight by 2% (step weight) till it reaches 50% (max weight)
|
|
<ul><li>halt advancement if any webhook call fails</li> <li>halt advancement while canary request success rate is under the threshold</li> <li>halt advancement while canary request duration P99 is over the threshold</li> <li>halt advancement while any custom metric check fails</li> <li>halt advancement if the primary or canary deployment becomes unhealthy</li> <li>halt advancement while canary deployment is being scaled up/down by HPA</li></ul></li> <li>call confirm-promotion webhooks and check results
|
|
<ul><li>halt advancement if any hook returns a non HTTP 2xx result</li></ul></li> <li>promote canary to primary
|
|
<ul><li>copy ConfigMaps and Secrets from canary to primary</li> <li>copy canary deployment spec template over primary</li></ul></li> <li>wait for primary rolling update to finish
|
|
<ul><li>halt advancement if pods are unhealthy</li></ul></li> <li>route all traffic to primary</li> <li>scale to zero the canary deployment</li> <li>mark rollout as finished</li> <li>call post-rollout webhooks</li> <li>send notification with the canary analysis result</li> <li>wait for the canary deployment to be updated and start over</li></ul> <h2 id="a-b-testing"><a href="#a-b-testing" aria-hidden="true" class="header-anchor">#</a> A/B Testing</h2> <p>For frontend applications that require session affinity you should use HTTP headers or cookies match conditions
|
|
to ensure a set of users will stay on the same version for the whole duration of the canary analysis.</p> <p><img src="https://raw.githubusercontent.com/weaveworks/flagger/master/docs/diagrams/flagger-abtest-steps.png" alt="Flagger A/B Testing Stages"></p> <p>You can enable A/B testing by specifying the HTTP match conditions and the number of iterations.
|
|
If Flagger finds a HTTP match condition, it will ignore the <code>maxWeight</code> and <code>stepWeight</code> settings.</p> <p>Istio example:</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code> <span class="token key atrule">analysis</span><span class="token punctuation">:</span>
|
|
<span class="token comment"># schedule interval (default 60s)</span>
|
|
<span class="token key atrule">interval</span><span class="token punctuation">:</span> 1m
|
|
<span class="token comment"># total number of iterations</span>
|
|
<span class="token key atrule">iterations</span><span class="token punctuation">:</span> <span class="token number">10</span>
|
|
<span class="token comment"># max number of failed iterations before rollback</span>
|
|
<span class="token key atrule">threshold</span><span class="token punctuation">:</span> <span class="token number">2</span>
|
|
<span class="token comment"># canary match condition</span>
|
|
<span class="token key atrule">match</span><span class="token punctuation">:</span>
|
|
<span class="token punctuation">-</span> <span class="token key atrule">headers</span><span class="token punctuation">:</span>
|
|
<span class="token key atrule">x-canary</span><span class="token punctuation">:</span>
|
|
<span class="token key atrule">regex</span><span class="token punctuation">:</span> <span class="token string">".*insider.*"</span>
|
|
<span class="token punctuation">-</span> <span class="token key atrule">headers</span><span class="token punctuation">:</span>
|
|
<span class="token key atrule">cookie</span><span class="token punctuation">:</span>
|
|
<span class="token key atrule">regex</span><span class="token punctuation">:</span> <span class="token string">"^(.*?;)?(canary=always)(;.*)?$"</span>
|
|
</code></pre></div><p>The above configuration will run an analysis for ten minutes targeting the Safari users and those that have a test cookie.
|
|
You can determine the minimum time that it takes to validate and promote a canary deployment using this formula:</p> <div class="language- extra-class"><pre class="language-text"><code>interval * iterations
|
|
</code></pre></div><p>And the time it takes for a canary to be rollback when the metrics or webhook checks are failing:</p> <div class="language- extra-class"><pre class="language-text"><code>interval * threshold
|
|
</code></pre></div><p>App Mesh example:</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code> <span class="token key atrule">analysis</span><span class="token punctuation">:</span>
|
|
<span class="token key atrule">interval</span><span class="token punctuation">:</span> 1m
|
|
<span class="token key atrule">threshold</span><span class="token punctuation">:</span> <span class="token number">10</span>
|
|
<span class="token key atrule">iterations</span><span class="token punctuation">:</span> <span class="token number">2</span>
|
|
<span class="token key atrule">match</span><span class="token punctuation">:</span>
|
|
<span class="token punctuation">-</span> <span class="token key atrule">headers</span><span class="token punctuation">:</span>
|
|
<span class="token key atrule">user-agent</span><span class="token punctuation">:</span>
|
|
<span class="token key atrule">regex</span><span class="token punctuation">:</span> <span class="token string">".*Chrome.*"</span>
|
|
</code></pre></div><p>Note that App Mesh supports a single condition.</p> <p>Contour example:</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code> <span class="token key atrule">analysis</span><span class="token punctuation">:</span>
|
|
<span class="token key atrule">interval</span><span class="token punctuation">:</span> 1m
|
|
<span class="token key atrule">threshold</span><span class="token punctuation">:</span> <span class="token number">10</span>
|
|
<span class="token key atrule">iterations</span><span class="token punctuation">:</span> <span class="token number">2</span>
|
|
<span class="token key atrule">match</span><span class="token punctuation">:</span>
|
|
<span class="token punctuation">-</span> <span class="token key atrule">headers</span><span class="token punctuation">:</span>
|
|
<span class="token key atrule">user-agent</span><span class="token punctuation">:</span>
|
|
<span class="token key atrule">prefix</span><span class="token punctuation">:</span> <span class="token string">"Chrome"</span>
|
|
</code></pre></div><p>Note that Contour does not support regex, you can use prefix, suffix or exact.</p> <p>NGINX example:</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code> <span class="token key atrule">analysis</span><span class="token punctuation">:</span>
|
|
<span class="token key atrule">interval</span><span class="token punctuation">:</span> 1m
|
|
<span class="token key atrule">threshold</span><span class="token punctuation">:</span> <span class="token number">10</span>
|
|
<span class="token key atrule">iterations</span><span class="token punctuation">:</span> <span class="token number">2</span>
|
|
<span class="token key atrule">match</span><span class="token punctuation">:</span>
|
|
<span class="token punctuation">-</span> <span class="token key atrule">headers</span><span class="token punctuation">:</span>
|
|
<span class="token key atrule">x-canary</span><span class="token punctuation">:</span>
|
|
<span class="token key atrule">exact</span><span class="token punctuation">:</span> <span class="token string">"insider"</span>
|
|
<span class="token punctuation">-</span> <span class="token key atrule">headers</span><span class="token punctuation">:</span>
|
|
<span class="token key atrule">cookie</span><span class="token punctuation">:</span>
|
|
<span class="token key atrule">exact</span><span class="token punctuation">:</span> <span class="token string">"canary"</span>
|
|
</code></pre></div><p>Note that the NGINX ingress controller supports only exact matching for a single header and the cookie value is set to <code>always</code>.</p> <p>The above configurations will route users with the x-canary header or canary cookie to the canary instance during analysis:</p> <div class="language-bash extra-class"><pre class="language-bash"><code><span class="token function">curl</span> -H <span class="token string">'X-Canary: insider'</span> http://app.example.com
|
|
<span class="token function">curl</span> -b <span class="token string">'canary=always'</span> http://app.example.com
|
|
</code></pre></div><h2 id="blue-green-deployments"><a href="#blue-green-deployments" aria-hidden="true" class="header-anchor">#</a> Blue/Green Deployments</h2> <p>For applications that are not deployed on a service mesh, Flagger can orchestrate blue/green style deployments
|
|
with Kubernetes L4 networking. When using Istio you have the option to mirror traffic between blue and green.</p> <p><img src="https://raw.githubusercontent.com/weaveworks/flagger/master/docs/diagrams/flagger-bluegreen-steps.png" alt="Flagger Blue/Green Stages"></p> <p>You can use the blue/green deployment strategy by replacing <code>stepWeight/maxWeight</code> with <code>iterations</code> in the <code>canaryAnalysis</code> spec:</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code> <span class="token key atrule">analysis</span><span class="token punctuation">:</span>
|
|
<span class="token comment"># schedule interval (default 60s)</span>
|
|
<span class="token key atrule">interval</span><span class="token punctuation">:</span> 1m
|
|
<span class="token comment"># total number of iterations</span>
|
|
<span class="token key atrule">iterations</span><span class="token punctuation">:</span> <span class="token number">10</span>
|
|
<span class="token comment"># max number of failed iterations before rollback</span>
|
|
<span class="token key atrule">threshold</span><span class="token punctuation">:</span> <span class="token number">2</span>
|
|
</code></pre></div><p>With the above configuration Flagger will run conformance and load tests on the canary pods for ten minutes.
|
|
If the metrics analysis succeeds, live traffic will be switched from the old version to the new one when the
|
|
canary is promoted.</p> <p>The blue/green deployment strategy is supported for all service mesh providers.</p> <p>Blue/Green rollout steps for service mesh:</p> <ul><li>detect new revision (deployment spec, secrets or configmaps changes)</li> <li>scale up the canary (green)</li> <li>run conformance tests for the canary pods</li> <li>run load tests and metric checks for the canary pods every minute</li> <li>abort the canary release if the failure threshold is reached</li> <li>route traffic to canary</li> <li>promote canary spec over primary (blue)</li> <li>wait for primary rollout</li> <li>route traffic to primary</li> <li>scale down canary</li></ul> <p>After the analysis finishes, the traffic is routed to the canary (green) before triggering the primary (blue)
|
|
rolling update, this ensures a smooth transition to the new version avoiding dropping in-flight requests during
|
|
the Kubernetes deployment rollout.</p> <h2 id="blue-green-with-traffic-mirroring"><a href="#blue-green-with-traffic-mirroring" aria-hidden="true" class="header-anchor">#</a> Blue/Green with Traffic Mirroring</h2> <p>Traffic Mirroring is a pre-stage in a Canary (progressive traffic shifting) or
|
|
Blue/Green deployment strategy. Traffic mirroring will copy each incoming
|
|
request, sending one request to the primary and one to the canary service.
|
|
The response from the primary is sent back to the user. The response from the canary
|
|
is discarded. Metrics are collected on both requests so that the deployment will
|
|
only proceed if the canary metrics are healthy.</p> <p>Mirroring should be used for requests that are <strong>idempotent</strong> or capable of
|
|
being processed twice (once by the primary and once by the canary). Reads are
|
|
idempotent. Before using mirroring on requests that may be writes, you should
|
|
consider what will happen if a write is duplicated and handled by the primary
|
|
and canary.</p> <p>To use mirroring, set <code>spec.canaryAnalysis.mirror</code> to <code>true</code>.</p> <p>Istio example:</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code> <span class="token key atrule">analysis</span><span class="token punctuation">:</span>
|
|
<span class="token comment"># schedule interval (default 60s)</span>
|
|
<span class="token key atrule">interval</span><span class="token punctuation">:</span> 1m
|
|
<span class="token comment"># total number of iterations</span>
|
|
<span class="token key atrule">iterations</span><span class="token punctuation">:</span> <span class="token number">10</span>
|
|
<span class="token comment"># max number of failed iterations before rollback</span>
|
|
<span class="token key atrule">threshold</span><span class="token punctuation">:</span> <span class="token number">2</span>
|
|
<span class="token comment"># Traffic shadowing (compatible with Istio only)</span>
|
|
<span class="token key atrule">mirror</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
|
|
</code></pre></div><p>Mirroring rollout steps for service mesh:</p> <ul><li>detect new revision (deployment spec, secrets or configmaps changes)</li> <li>scale from zero the canary deployment</li> <li>wait for the HPA to set the canary minimum replicas</li> <li>check canary pods health</li> <li>run the acceptance tests</li> <li>abort the canary release if tests fail</li> <li>start the load tests</li> <li>mirror traffic from primary to canary</li> <li>check request success rate and request duration every minute</li> <li>abort the canary release if the failure threshold is reached</li> <li>stop traffic mirroring after the number of iterations is reached</li> <li>route live traffic to the canary pods</li> <li>promote the canary (update the primary secrets, configmaps and deployment spec)</li> <li>wait for the primary deployment rollout to finish</li> <li>wait for the HPA to set the primary minimum replicas</li> <li>check primary pods health</li> <li>switch live traffic back to primary</li> <li>scale to zero the canary</li> <li>send notification with the canary analysis result</li></ul> <p>After the analysis finishes, the traffic is routed to the canary (green) before triggering the primary (blue)
|
|
rolling update, this ensures a smooth transition to the new version avoiding dropping in-flight requests during
|
|
the Kubernetes deployment rollout.</p></div> <footer class="page-edit"><!----> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev">
|
|
←
|
|
<a href="/usage/how-it-works.html" class="prev">
|
|
How it works
|
|
</a></span> <span class="next"><a href="/usage/metrics.html">
|
|
Metrics Analysis
|
|
</a>
|
|
→
|
|
</span></p></div> </main></div><div class="global-ui"></div></div>
|
|
<script src="/assets/js/app.9b46ae46.js" defer></script><script src="/assets/js/2.ba5bf77c.js" defer></script><script src="/assets/js/31.fbfb336c.js" defer></script>
|
|
</body>
|
|
</html>
|