Files
flagger/intro/faq.html
T
2020-08-20 06:16:09 +00:00

484 lines
65 KiB
HTML

<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Frequently asked questions | 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/15.aada2caa.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/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/31.fbfb336c.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 router-link-active open"><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="active sidebar-link">FAQ</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/intro/faq.html#deployment-strategies" class="sidebar-link">Deployment Strategies</a></li><li class="sidebar-sub-header"><a href="/intro/faq.html#kubernetes-services" class="sidebar-link">Kubernetes services</a></li><li class="sidebar-sub-header"><a href="/intro/faq.html#multiple-ports" class="sidebar-link">Multiple ports</a></li><li class="sidebar-sub-header"><a href="/intro/faq.html#label-selectors" class="sidebar-link">Label selectors</a></li><li class="sidebar-sub-header"><a href="/intro/faq.html#metrics" class="sidebar-link">Metrics</a></li><li class="sidebar-sub-header"><a href="/intro/faq.html#istio-routing" class="sidebar-link">Istio routing</a></li><li class="sidebar-sub-header"><a href="/intro/faq.html#istio-ingress-gateway" class="sidebar-link">Istio Ingress Gateway</a></li><li class="sidebar-sub-header"><a href="/intro/faq.html#istio-mutual-tls" class="sidebar-link">Istio Mutual TLS</a></li></ul></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"><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="sidebar-link">Deployment Strategies</a></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="frequently-asked-questions"><a href="#frequently-asked-questions" aria-hidden="true" class="header-anchor">#</a> Frequently asked questions</h1> <h2 id="deployment-strategies"><a href="#deployment-strategies" aria-hidden="true" class="header-anchor">#</a> Deployment Strategies</h2> <p><strong>Which deployment strategies are supported by Flagger?</strong></p> <p>Flagger implements the following deployment strategies:</p> <ul><li><a href="/usage/deployment-strategies.html#canary-release">Canary Release</a></li> <li><a href="/usage/deployment-strategies.html#a-b-testing">A/B Testing</a></li> <li><a href="/usage/deployment-strategies.html#blue-green-deployments">Blue/Green</a></li> <li><a href="/usage/deployment-strategies.html#blue-green-with-traffic-mirroring">Blue/Green Mirroring</a></li></ul> <p><strong>When should I use A/B testing instead of progressive traffic shifting?</strong></p> <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><strong>Can I use Flagger to manage applications that live outside of a service mesh?</strong></p> <p>For applications that are not deployed on a service mesh, Flagger can orchestrate Blue/Green style deployments
with Kubernetes L4 networking.</p> <p><strong>When can I use traffic mirroring?</strong></p> <p>Traffic mirroring can be used for Blue/Green deployment strategy or a pre-stage in a Canary release.
Traffic mirroring will copy each incoming request, sending one request to the primary and one to the canary service.
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).</p> <h2 id="kubernetes-services"><a href="#kubernetes-services" aria-hidden="true" class="header-anchor">#</a> Kubernetes services</h2> <p><strong>How is an application exposed inside the cluster?</strong></p> <p>Assuming the app name is podinfo you can define a canary like:</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> flagger.app/v1beta1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> Canary
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
<span class="token key atrule">name</span><span class="token punctuation">:</span> podinfo
<span class="token key atrule">namespace</span><span class="token punctuation">:</span> test
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
<span class="token key atrule">targetRef</span><span class="token punctuation">:</span>
<span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> apps/v1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> Deployment
<span class="token key atrule">name</span><span class="token punctuation">:</span> podinfo
<span class="token key atrule">service</span><span class="token punctuation">:</span>
<span class="token comment"># service name (optional)</span>
<span class="token key atrule">name</span><span class="token punctuation">:</span> podinfo
<span class="token comment"># ClusterIP port number (required)</span>
<span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">9898</span>
<span class="token comment"># container port name or number</span>
<span class="token key atrule">targetPort</span><span class="token punctuation">:</span> http
<span class="token comment"># port name can be http or grpc (default http)</span>
<span class="token key atrule">portName</span><span class="token punctuation">:</span> http
</code></pre></div><p>If the <code>service.name</code> is not specified, then <code>targetRef.name</code> is used for the apex domain and canary/primary services name prefix.
You should treat the service name as an immutable field, changing it could result in routing conflicts.</p> <p>Based on the canary spec service, Flagger generates the following Kubernetes ClusterIP service:</p> <ul><li><code>&lt;service.name&gt;.&lt;namespace&gt;.svc.cluster.local</code><br>
selector <code>app=&lt;name&gt;-primary</code></li> <li><code>&lt;service.name&gt;-primary.&lt;namespace&gt;.svc.cluster.local</code><br>
selector <code>app=&lt;name&gt;-primary</code></li> <li><code>&lt;service.name&gt;-canary.&lt;namespace&gt;.svc.cluster.local</code><br>
selector <code>app=&lt;name&gt;</code></li></ul> <p>This ensures that traffic coming from a namespace outside the mesh to <code>podinfo.test:9898</code>
will be routed to the latest stable release of your app.</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> v1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> Service
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
<span class="token key atrule">name</span><span class="token punctuation">:</span> podinfo
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
<span class="token key atrule">type</span><span class="token punctuation">:</span> ClusterIP
<span class="token key atrule">selector</span><span class="token punctuation">:</span>
<span class="token key atrule">app</span><span class="token punctuation">:</span> podinfo<span class="token punctuation">-</span>primary
<span class="token key atrule">ports</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> http
<span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">9898</span>
<span class="token key atrule">protocol</span><span class="token punctuation">:</span> TCP
<span class="token key atrule">targetPort</span><span class="token punctuation">:</span> http
<span class="token punctuation">---</span>
<span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> v1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> Service
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
<span class="token key atrule">name</span><span class="token punctuation">:</span> podinfo<span class="token punctuation">-</span>primary
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
<span class="token key atrule">type</span><span class="token punctuation">:</span> ClusterIP
<span class="token key atrule">selector</span><span class="token punctuation">:</span>
<span class="token key atrule">app</span><span class="token punctuation">:</span> podinfo<span class="token punctuation">-</span>primary
<span class="token key atrule">ports</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> http
<span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">9898</span>
<span class="token key atrule">protocol</span><span class="token punctuation">:</span> TCP
<span class="token key atrule">targetPort</span><span class="token punctuation">:</span> http
<span class="token punctuation">---</span>
<span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> v1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> Service
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
<span class="token key atrule">name</span><span class="token punctuation">:</span> podinfo<span class="token punctuation">-</span>canary
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
<span class="token key atrule">type</span><span class="token punctuation">:</span> ClusterIP
<span class="token key atrule">selector</span><span class="token punctuation">:</span>
<span class="token key atrule">app</span><span class="token punctuation">:</span> podinfo
<span class="token key atrule">ports</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> http
<span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">9898</span>
<span class="token key atrule">protocol</span><span class="token punctuation">:</span> TCP
<span class="token key atrule">targetPort</span><span class="token punctuation">:</span> http
</code></pre></div><p>The <code>podinfo-canary.test:9898</code> address is available only during the
canary analysis and can be used for conformance testing or load testing.</p> <h2 id="multiple-ports"><a href="#multiple-ports" aria-hidden="true" class="header-anchor">#</a> Multiple ports</h2> <p><strong>My application listens on multiple ports, how can I expose them inside the cluster?</strong></p> <p>If port discovery is enabled, Flagger scans the deployment spec and extracts the containers
ports excluding the port specified in the canary service and Envoy sidecar ports.
These ports will be used when generating the ClusterIP services.</p> <p>For a deployment that exposes two ports:</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> apps/v1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> Deployment
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
<span class="token key atrule">template</span><span class="token punctuation">:</span>
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
<span class="token key atrule">annotations</span><span class="token punctuation">:</span>
<span class="token key atrule">prometheus.io/scrape</span><span class="token punctuation">:</span> <span class="token string">&quot;true&quot;</span>
<span class="token key atrule">prometheus.io/port</span><span class="token punctuation">:</span> <span class="token string">&quot;9899&quot;</span>
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
<span class="token key atrule">containers</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> app
<span class="token key atrule">ports</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> <span class="token key atrule">containerPort</span><span class="token punctuation">:</span> <span class="token number">8080</span>
<span class="token punctuation">-</span> <span class="token key atrule">containerPort</span><span class="token punctuation">:</span> <span class="token number">9090</span>
</code></pre></div><p>You can enable port discovery so that Prometheus will be able to reach port <code>9090</code> over mTLS:</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> flagger.app/v1beta1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> Canary
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
<span class="token key atrule">service</span><span class="token punctuation">:</span>
<span class="token comment"># container port used for canary analysis</span>
<span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">8080</span>
<span class="token comment"># port name can be http or grpc (default http)</span>
<span class="token key atrule">portName</span><span class="token punctuation">:</span> http
<span class="token comment"># add all the other container ports</span>
<span class="token comment"># to the ClusterIP services (default false)</span>
<span class="token key atrule">portDiscovery</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
<span class="token key atrule">trafficPolicy</span><span class="token punctuation">:</span>
<span class="token key atrule">tls</span><span class="token punctuation">:</span>
<span class="token key atrule">mode</span><span class="token punctuation">:</span> ISTIO_MUTUAL
</code></pre></div><p>Both port <code>8080</code> and <code>9090</code> will be added to the ClusterIP services.</p> <h2 id="label-selectors"><a href="#label-selectors" aria-hidden="true" class="header-anchor">#</a> Label selectors</h2> <p><strong>What labels selectors are supported by Flagger?</strong></p> <p>The target deployment must have a single label selector in the format <code>app: &lt;DEPLOYMENT-NAME&gt;</code>:</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> apps/v1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> Deployment
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
<span class="token key atrule">name</span><span class="token punctuation">:</span> podinfo
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
<span class="token key atrule">selector</span><span class="token punctuation">:</span>
<span class="token key atrule">matchLabels</span><span class="token punctuation">:</span>
<span class="token key atrule">app</span><span class="token punctuation">:</span> podinfo
<span class="token key atrule">template</span><span class="token punctuation">:</span>
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
<span class="token key atrule">labels</span><span class="token punctuation">:</span>
<span class="token key atrule">app</span><span class="token punctuation">:</span> podinfo
</code></pre></div><p>Besides <code>app</code> Flagger supports <code>name</code> and <code>app.kubernetes.io/name</code> selectors. If you use a different
convention you can specify your label with the <code>-selector-labels</code> flag.</p> <p><strong>Is pod affinity and anti affinity supported?</strong></p> <p>For pod affinity to work you need to use a different label than the <code>app</code>, <code>name</code> or <code>app.kubernetes.io/name</code>.</p> <p>Anti affinity example:</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> apps/v1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> Deployment
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
<span class="token key atrule">name</span><span class="token punctuation">:</span> podinfo
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
<span class="token key atrule">selector</span><span class="token punctuation">:</span>
<span class="token key atrule">matchLabels</span><span class="token punctuation">:</span>
<span class="token key atrule">app</span><span class="token punctuation">:</span> podinfo
<span class="token key atrule">affinity</span><span class="token punctuation">:</span> podinfo
<span class="token key atrule">template</span><span class="token punctuation">:</span>
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
<span class="token key atrule">labels</span><span class="token punctuation">:</span>
<span class="token key atrule">app</span><span class="token punctuation">:</span> podinfo
<span class="token key atrule">affinity</span><span class="token punctuation">:</span> podinfo
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
<span class="token key atrule">affinity</span><span class="token punctuation">:</span>
<span class="token key atrule">podAntiAffinity</span><span class="token punctuation">:</span>
<span class="token key atrule">preferredDuringSchedulingIgnoredDuringExecution</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> <span class="token key atrule">weight</span><span class="token punctuation">:</span> <span class="token number">100</span>
<span class="token key atrule">podAffinityTerm</span><span class="token punctuation">:</span>
<span class="token key atrule">labelSelector</span><span class="token punctuation">:</span>
<span class="token key atrule">matchLabels</span><span class="token punctuation">:</span>
<span class="token key atrule">affinity</span><span class="token punctuation">:</span> podinfo
<span class="token key atrule">topologyKey</span><span class="token punctuation">:</span> kubernetes.io/hostname
</code></pre></div><h2 id="metrics"><a href="#metrics" aria-hidden="true" class="header-anchor">#</a> Metrics</h2> <p><strong>How does Flagger measures the request success rate and duration?</strong></p> <p>Flagger measures the request success rate and duration using Prometheus queries.</p> <p><strong>HTTP requests success rate percentage</strong></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 key atrule">metrics</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> request<span class="token punctuation">-</span>success<span class="token punctuation">-</span>rate
<span class="token comment"># minimum req success rate (non 5xx responses)</span>
<span class="token comment"># percentage (0-100)</span>
<span class="token key atrule">thresholdRange</span><span class="token punctuation">:</span>
<span class="token key atrule">min</span><span class="token punctuation">:</span> <span class="token number">99</span>
<span class="token key atrule">interval</span><span class="token punctuation">:</span> 1m
</code></pre></div><p>Istio query:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token function">sum</span><span class="token punctuation">(</span>
<span class="token function">rate</span><span class="token punctuation">(</span>
istio_requests_total<span class="token punctuation">{</span>
reporter<span class="token operator">=</span><span class="token string">&quot;destination&quot;</span><span class="token punctuation">,</span>
destination_workload_namespace<span class="token operator">=</span><span class="token operator">~</span><span class="token string">&quot;$namespace&quot;</span><span class="token punctuation">,</span>
destination_workload<span class="token operator">=</span><span class="token operator">~</span><span class="token string">&quot;$workload&quot;</span><span class="token punctuation">,</span>
response_code<span class="token operator">!</span><span class="token operator">~</span><span class="token string">&quot;5.*&quot;</span>
<span class="token punctuation">}</span><span class="token punctuation">[</span>$interval<span class="token punctuation">]</span>
<span class="token punctuation">)</span>
<span class="token punctuation">)</span>
<span class="token operator">/</span>
<span class="token function">sum</span><span class="token punctuation">(</span>
<span class="token function">rate</span><span class="token punctuation">(</span>
istio_requests_total<span class="token punctuation">{</span>
reporter<span class="token operator">=</span><span class="token string">&quot;destination&quot;</span><span class="token punctuation">,</span>
destination_workload_namespace<span class="token operator">=</span><span class="token operator">~</span><span class="token string">&quot;$namespace&quot;</span><span class="token punctuation">,</span>
destination_workload<span class="token operator">=</span><span class="token operator">~</span><span class="token string">&quot;$workload&quot;</span>
<span class="token punctuation">}</span><span class="token punctuation">[</span>$interval<span class="token punctuation">]</span>
<span class="token punctuation">)</span>
<span class="token punctuation">)</span>
</code></pre></div><p>Envoy query (App Mesh, Contour or Gloo):</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token function">sum</span><span class="token punctuation">(</span>
<span class="token function">rate</span><span class="token punctuation">(</span>
envoy_cluster_upstream_rq<span class="token punctuation">{</span>
kubernetes_namespace<span class="token operator">=</span><span class="token string">&quot;$namespace&quot;</span><span class="token punctuation">,</span>
kubernetes_pod_name<span class="token operator">=</span><span class="token operator">~</span><span class="token string">&quot;$workload&quot;</span><span class="token punctuation">,</span>
envoy_response_code<span class="token operator">!</span><span class="token operator">~</span><span class="token string">&quot;5.*&quot;</span>
<span class="token punctuation">}</span><span class="token punctuation">[</span>$interval<span class="token punctuation">]</span>
<span class="token punctuation">)</span>
<span class="token punctuation">)</span>
<span class="token operator">/</span>
<span class="token function">sum</span><span class="token punctuation">(</span>
<span class="token function">rate</span><span class="token punctuation">(</span>
envoy_cluster_upstream_rq<span class="token punctuation">{</span>
kubernetes_namespace<span class="token operator">=</span><span class="token string">&quot;$namespace&quot;</span><span class="token punctuation">,</span>
kubernetes_pod_name<span class="token operator">=</span><span class="token operator">~</span><span class="token string">&quot;$workload&quot;</span>
<span class="token punctuation">}</span><span class="token punctuation">[</span>$interval<span class="token punctuation">]</span>
<span class="token punctuation">)</span>
<span class="token punctuation">)</span>
</code></pre></div><p><strong>HTTP requests milliseconds duration P99</strong></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 key atrule">metrics</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> request<span class="token punctuation">-</span>duration
<span class="token comment"># maximum req duration P99</span>
<span class="token comment"># milliseconds</span>
<span class="token key atrule">thresholdRange</span><span class="token punctuation">:</span>
<span class="token key atrule">max</span><span class="token punctuation">:</span> <span class="token number">500</span>
<span class="token key atrule">interval</span><span class="token punctuation">:</span> 1m
</code></pre></div><p>Istio query:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token function">histogram_quantile</span><span class="token punctuation">(</span><span class="token number">0.99</span><span class="token punctuation">,</span>
<span class="token function">sum</span><span class="token punctuation">(</span>
<span class="token function">irate</span><span class="token punctuation">(</span>
istio_request_duration_seconds_bucket<span class="token punctuation">{</span>
reporter<span class="token operator">=</span><span class="token string">&quot;destination&quot;</span><span class="token punctuation">,</span>
destination_workload<span class="token operator">=</span><span class="token operator">~</span><span class="token string">&quot;$workload&quot;</span><span class="token punctuation">,</span>
destination_workload_namespace<span class="token operator">=</span><span class="token operator">~</span><span class="token string">&quot;$namespace&quot;</span>
<span class="token punctuation">}</span><span class="token punctuation">[</span>$interval<span class="token punctuation">]</span>
<span class="token punctuation">)</span>
<span class="token punctuation">)</span> <span class="token function">by</span> <span class="token punctuation">(</span>le<span class="token punctuation">)</span>
<span class="token punctuation">)</span>
</code></pre></div><p>Envoy query (App Mesh, Contour or Gloo):</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token function">histogram_quantile</span><span class="token punctuation">(</span><span class="token number">0.99</span><span class="token punctuation">,</span>
<span class="token function">sum</span><span class="token punctuation">(</span>
<span class="token function">irate</span><span class="token punctuation">(</span>
envoy_cluster_upstream_rq_time_bucket<span class="token punctuation">{</span>
kubernetes_pod_name<span class="token operator">=</span><span class="token operator">~</span><span class="token string">&quot;$workload&quot;</span><span class="token punctuation">,</span>
kubernetes_namespace<span class="token operator">=</span><span class="token operator">~</span><span class="token string">&quot;$namespace&quot;</span>
<span class="token punctuation">}</span><span class="token punctuation">[</span>$interval<span class="token punctuation">]</span>
<span class="token punctuation">)</span>
<span class="token punctuation">)</span> <span class="token function">by</span> <span class="token punctuation">(</span>le<span class="token punctuation">)</span>
<span class="token punctuation">)</span>
</code></pre></div><blockquote><p><strong>Note</strong> that the metric interval should be lower or equal to the control loop interval.</p></blockquote> <p><strong>Can I use custom metrics?</strong></p> <p>The analysis can be extended with metrics provided by Prometheus, Datadog and AWS CloudWatch. For more details
on how custom metrics can be used please read the <a href="/usage/metrics.html">metrics docs</a>.</p> <h2 id="istio-routing"><a href="#istio-routing" aria-hidden="true" class="header-anchor">#</a> Istio routing</h2> <p><strong>How does Flagger interact with Istio?</strong></p> <p>Flagger creates an Istio Virtual Service and Destination Rules based on the Canary service spec.
The service configuration lets you expose an app inside or outside the mesh.
You can also define traffic policies, HTTP match conditions, URI rewrite rules, CORS policies, timeout and retries.</p> <p>The following spec exposes the <code>frontend</code> workload inside the mesh on <code>frontend.test.svc.cluster.local:9898</code>
and outside the mesh on <code>frontend.example.com</code>. You'll have to specify an Istio ingress gateway for external hosts.</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> flagger.app/v1beta1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> Canary
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
<span class="token key atrule">name</span><span class="token punctuation">:</span> frontend
<span class="token key atrule">namespace</span><span class="token punctuation">:</span> test
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
<span class="token key atrule">service</span><span class="token punctuation">:</span>
<span class="token comment"># container port</span>
<span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">9898</span>
<span class="token comment"># service port name (optional, will default to &quot;http&quot;)</span>
<span class="token key atrule">portName</span><span class="token punctuation">:</span> http<span class="token punctuation">-</span>frontend
<span class="token comment"># Istio gateways (optional)</span>
<span class="token key atrule">gateways</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> public<span class="token punctuation">-</span>gateway.istio<span class="token punctuation">-</span>system.svc.cluster.local
<span class="token punctuation">-</span> mesh
<span class="token comment"># Istio virtual service host names (optional)</span>
<span class="token key atrule">hosts</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> frontend.example.com
<span class="token comment"># Istio traffic policy</span>
<span class="token key atrule">trafficPolicy</span><span class="token punctuation">:</span>
<span class="token key atrule">tls</span><span class="token punctuation">:</span>
<span class="token comment"># use ISTIO_MUTUAL when mTLS is enabled</span>
<span class="token key atrule">mode</span><span class="token punctuation">:</span> DISABLE
<span class="token comment"># HTTP match conditions (optional)</span>
<span class="token key atrule">match</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> <span class="token key atrule">uri</span><span class="token punctuation">:</span>
<span class="token key atrule">prefix</span><span class="token punctuation">:</span> /
<span class="token comment"># HTTP rewrite (optional)</span>
<span class="token key atrule">rewrite</span><span class="token punctuation">:</span>
<span class="token key atrule">uri</span><span class="token punctuation">:</span> /
<span class="token comment"># Istio retry policy (optional)</span>
<span class="token key atrule">retries</span><span class="token punctuation">:</span>
<span class="token key atrule">attempts</span><span class="token punctuation">:</span> <span class="token number">3</span>
<span class="token key atrule">perTryTimeout</span><span class="token punctuation">:</span> 1s
<span class="token key atrule">retryOn</span><span class="token punctuation">:</span> <span class="token string">&quot;gateway-error,connect-failure,refused-stream&quot;</span>
<span class="token comment"># Add headers (optional)</span>
<span class="token key atrule">headers</span><span class="token punctuation">:</span>
<span class="token key atrule">request</span><span class="token punctuation">:</span>
<span class="token key atrule">add</span><span class="token punctuation">:</span>
<span class="token key atrule">x-some-header</span><span class="token punctuation">:</span> <span class="token string">&quot;value&quot;</span>
<span class="token comment"># cross-origin resource sharing policy (optional)</span>
<span class="token key atrule">corsPolicy</span><span class="token punctuation">:</span>
<span class="token key atrule">allowOrigin</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> example.com
<span class="token key atrule">allowMethods</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> GET
<span class="token key atrule">allowCredentials</span><span class="token punctuation">:</span> <span class="token boolean important">false</span>
<span class="token key atrule">allowHeaders</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> x<span class="token punctuation">-</span>some<span class="token punctuation">-</span>header
<span class="token key atrule">maxAge</span><span class="token punctuation">:</span> 24h
</code></pre></div><p>For the above spec Flagger will generate the following virtual service:</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> networking.istio.io/v1alpha3
<span class="token key atrule">kind</span><span class="token punctuation">:</span> VirtualService
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
<span class="token key atrule">name</span><span class="token punctuation">:</span> frontend
<span class="token key atrule">namespace</span><span class="token punctuation">:</span> test
<span class="token key atrule">ownerReferences</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> <span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> flagger.app/v1beta1
<span class="token key atrule">blockOwnerDeletion</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
<span class="token key atrule">controller</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
<span class="token key atrule">kind</span><span class="token punctuation">:</span> Canary
<span class="token key atrule">name</span><span class="token punctuation">:</span> podinfo
<span class="token key atrule">uid</span><span class="token punctuation">:</span> 3a4a40dd<span class="token punctuation">-</span>3875<span class="token punctuation">-</span>11e9<span class="token punctuation">-</span>8e1d<span class="token punctuation">-</span>42010a9c0fd1
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
<span class="token key atrule">gateways</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> public<span class="token punctuation">-</span>gateway.istio<span class="token punctuation">-</span>system.svc.cluster.local
<span class="token punctuation">-</span> mesh
<span class="token key atrule">hosts</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> frontend.example.com
<span class="token punctuation">-</span> frontend
<span class="token key atrule">http</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> <span class="token key atrule">corsPolicy</span><span class="token punctuation">:</span>
<span class="token key atrule">allowHeaders</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> x<span class="token punctuation">-</span>some<span class="token punctuation">-</span>header
<span class="token key atrule">allowMethods</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> GET
<span class="token key atrule">allowOrigin</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> example.com
<span class="token key atrule">maxAge</span><span class="token punctuation">:</span> 24h
<span class="token key atrule">headers</span><span class="token punctuation">:</span>
<span class="token key atrule">request</span><span class="token punctuation">:</span>
<span class="token key atrule">add</span><span class="token punctuation">:</span>
<span class="token key atrule">x-some-header</span><span class="token punctuation">:</span> <span class="token string">&quot;value&quot;</span>
<span class="token key atrule">match</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> <span class="token key atrule">uri</span><span class="token punctuation">:</span>
<span class="token key atrule">prefix</span><span class="token punctuation">:</span> /
<span class="token key atrule">rewrite</span><span class="token punctuation">:</span>
<span class="token key atrule">uri</span><span class="token punctuation">:</span> /
<span class="token key atrule">route</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> <span class="token key atrule">destination</span><span class="token punctuation">:</span>
<span class="token key atrule">host</span><span class="token punctuation">:</span> podinfo<span class="token punctuation">-</span>primary
<span class="token key atrule">weight</span><span class="token punctuation">:</span> <span class="token number">100</span>
<span class="token punctuation">-</span> <span class="token key atrule">destination</span><span class="token punctuation">:</span>
<span class="token key atrule">host</span><span class="token punctuation">:</span> podinfo<span class="token punctuation">-</span>canary
<span class="token key atrule">weight</span><span class="token punctuation">:</span> <span class="token number">0</span>
<span class="token key atrule">retries</span><span class="token punctuation">:</span>
<span class="token key atrule">attempts</span><span class="token punctuation">:</span> <span class="token number">3</span>
<span class="token key atrule">perTryTimeout</span><span class="token punctuation">:</span> 1s
<span class="token key atrule">retryOn</span><span class="token punctuation">:</span> <span class="token string">&quot;gateway-error,connect-failure,refused-stream&quot;</span>
</code></pre></div><p>For each destination in the virtual service a rule is generated:</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> networking.istio.io/v1alpha3
<span class="token key atrule">kind</span><span class="token punctuation">:</span> DestinationRule
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
<span class="token key atrule">name</span><span class="token punctuation">:</span> frontend<span class="token punctuation">-</span>primary
<span class="token key atrule">namespace</span><span class="token punctuation">:</span> test
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
<span class="token key atrule">host</span><span class="token punctuation">:</span> frontend<span class="token punctuation">-</span>primary
<span class="token key atrule">trafficPolicy</span><span class="token punctuation">:</span>
<span class="token key atrule">tls</span><span class="token punctuation">:</span>
<span class="token key atrule">mode</span><span class="token punctuation">:</span> DISABLE
<span class="token punctuation">---</span>
<span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> networking.istio.io/v1alpha3
<span class="token key atrule">kind</span><span class="token punctuation">:</span> DestinationRule
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
<span class="token key atrule">name</span><span class="token punctuation">:</span> frontend<span class="token punctuation">-</span>canary
<span class="token key atrule">namespace</span><span class="token punctuation">:</span> test
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
<span class="token key atrule">host</span><span class="token punctuation">:</span> frontend<span class="token punctuation">-</span>canary
<span class="token key atrule">trafficPolicy</span><span class="token punctuation">:</span>
<span class="token key atrule">tls</span><span class="token punctuation">:</span>
<span class="token key atrule">mode</span><span class="token punctuation">:</span> DISABLE
</code></pre></div><p>Flagger keeps in sync the virtual service and destination rules with the canary service spec.
Any direct modification to the virtual service spec will be overwritten.</p> <p>To expose a workload inside the mesh on <code>http://backend.test.svc.cluster.local:9898</code>,
the service spec can contain only the container port and the traffic policy:</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> flagger.app/v1beta1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> Canary
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
<span class="token key atrule">name</span><span class="token punctuation">:</span> backend
<span class="token key atrule">namespace</span><span class="token punctuation">:</span> test
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
<span class="token key atrule">service</span><span class="token punctuation">:</span>
<span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">9898</span>
<span class="token key atrule">trafficPolicy</span><span class="token punctuation">:</span>
<span class="token key atrule">tls</span><span class="token punctuation">:</span>
<span class="token key atrule">mode</span><span class="token punctuation">:</span> DISABLE
</code></pre></div><p>Based on the above spec, Flagger will create several ClusterIP services like:</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> v1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> Service
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
<span class="token key atrule">name</span><span class="token punctuation">:</span> backend<span class="token punctuation">-</span>primary
<span class="token key atrule">ownerReferences</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> <span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> flagger.app/v1beta1
<span class="token key atrule">blockOwnerDeletion</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
<span class="token key atrule">controller</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
<span class="token key atrule">kind</span><span class="token punctuation">:</span> Canary
<span class="token key atrule">name</span><span class="token punctuation">:</span> backend
<span class="token key atrule">uid</span><span class="token punctuation">:</span> 2ca1a9c7<span class="token punctuation">-</span>2ef6<span class="token punctuation">-</span>11e9<span class="token punctuation">-</span>bd01<span class="token punctuation">-</span>42010a9c0145
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
<span class="token key atrule">type</span><span class="token punctuation">:</span> ClusterIP
<span class="token key atrule">ports</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> http
<span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">9898</span>
<span class="token key atrule">protocol</span><span class="token punctuation">:</span> TCP
<span class="token key atrule">targetPort</span><span class="token punctuation">:</span> <span class="token number">9898</span>
<span class="token key atrule">selector</span><span class="token punctuation">:</span>
<span class="token key atrule">app</span><span class="token punctuation">:</span> backend<span class="token punctuation">-</span>primary
</code></pre></div><p>Flagger works for user facing apps exposed outside the cluster via an ingress gateway
and for backend HTTP APIs that are accessible only from inside the mesh.</p> <h2 id="istio-ingress-gateway"><a href="#istio-ingress-gateway" aria-hidden="true" class="header-anchor">#</a> Istio Ingress Gateway</h2> <p><strong>How can I expose multiple canaries on the same external domain?</strong></p> <p>Assuming you have two apps, one that servers the main website and one that serves the REST API.
For each app you can define a canary object as:</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> flagger.app/v1beta1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> Canary
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
<span class="token key atrule">name</span><span class="token punctuation">:</span> website
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
<span class="token key atrule">service</span><span class="token punctuation">:</span>
<span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">8080</span>
<span class="token key atrule">gateways</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> public<span class="token punctuation">-</span>gateway.istio<span class="token punctuation">-</span>system.svc.cluster.local
<span class="token key atrule">hosts</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> my<span class="token punctuation">-</span>site.com
<span class="token key atrule">match</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> <span class="token key atrule">uri</span><span class="token punctuation">:</span>
<span class="token key atrule">prefix</span><span class="token punctuation">:</span> /
<span class="token key atrule">rewrite</span><span class="token punctuation">:</span>
<span class="token key atrule">uri</span><span class="token punctuation">:</span> /
<span class="token punctuation">---</span>
<span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> flagger.app/v1beta1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> Canary
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
<span class="token key atrule">name</span><span class="token punctuation">:</span> webapi
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
<span class="token key atrule">service</span><span class="token punctuation">:</span>
<span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">8080</span>
<span class="token key atrule">gateways</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> public<span class="token punctuation">-</span>gateway.istio<span class="token punctuation">-</span>system.svc.cluster.local
<span class="token key atrule">hosts</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> my<span class="token punctuation">-</span>site.com
<span class="token key atrule">match</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> <span class="token key atrule">uri</span><span class="token punctuation">:</span>
<span class="token key atrule">prefix</span><span class="token punctuation">:</span> /api
<span class="token key atrule">rewrite</span><span class="token punctuation">:</span>
<span class="token key atrule">uri</span><span class="token punctuation">:</span> /
</code></pre></div><p>Based on the above configuration, Flagger will create two virtual services bounded to the same ingress gateway and external host.
Istio Pilot will <a href="https://istio.io/help/ops/traffic-management/deploy-guidelines/#multiple-virtual-services-and-destination-rules-for-the-same-host" target="_blank" rel="noopener noreferrer">merge<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>
the two services and the website rule will be moved to the end of the list in the merged configuration.</p> <p>Note that host merging only works if the canaries are bounded to a ingress gateway other than the <code>mesh</code> gateway.</p> <h2 id="istio-mutual-tls"><a href="#istio-mutual-tls" aria-hidden="true" class="header-anchor">#</a> Istio Mutual TLS</h2> <p><strong>How can I enable mTLS for a canary?</strong></p> <p>When deploying Istio with global mTLS enabled, you have to set the TLS mode to <code>ISTIO_MUTUAL</code>:</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> flagger.app/v1beta1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> Canary
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
<span class="token key atrule">service</span><span class="token punctuation">:</span>
<span class="token key atrule">trafficPolicy</span><span class="token punctuation">:</span>
<span class="token key atrule">tls</span><span class="token punctuation">:</span>
<span class="token key atrule">mode</span><span class="token punctuation">:</span> ISTIO_MUTUAL
</code></pre></div><p>If you run Istio in permissive mode you can disable TLS:</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> flagger.app/v1beta1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> Canary
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
<span class="token key atrule">service</span><span class="token punctuation">:</span>
<span class="token key atrule">trafficPolicy</span><span class="token punctuation">:</span>
<span class="token key atrule">tls</span><span class="token punctuation">:</span>
<span class="token key atrule">mode</span><span class="token punctuation">:</span> DISABLE
</code></pre></div><p><strong>If Flagger is outside of the mesh, how can it start the load test?</strong></p> <p>In order for Flagger to be able to call the load tester service from outside the mesh, you need to disable mTLS on port 80:</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> networking.istio.io/v1alpha3
<span class="token key atrule">kind</span><span class="token punctuation">:</span> DestinationRule
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
<span class="token key atrule">name</span><span class="token punctuation">:</span> flagger<span class="token punctuation">-</span>loadtester
<span class="token key atrule">namespace</span><span class="token punctuation">:</span> test
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
<span class="token key atrule">host</span><span class="token punctuation">:</span> <span class="token string">&quot;flagger-loadtester.test.svc.cluster.local&quot;</span>
<span class="token key atrule">trafficPolicy</span><span class="token punctuation">:</span>
<span class="token key atrule">tls</span><span class="token punctuation">:</span>
<span class="token key atrule">mode</span><span class="token punctuation">:</span> DISABLE
<span class="token punctuation">---</span>
<span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> authentication.istio.io/v1alpha1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> Policy
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
<span class="token key atrule">name</span><span class="token punctuation">:</span> flagger<span class="token punctuation">-</span>loadtester
<span class="token key atrule">namespace</span><span class="token punctuation">:</span> test
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
<span class="token key atrule">targets</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> flagger<span class="token punctuation">-</span>loadtester
<span class="token key atrule">ports</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> <span class="token key atrule">number</span><span class="token punctuation">:</span> <span class="token number">80</span>
</code></pre></div></div> <footer class="page-edit"><!----> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev">
<a href="/intro/" class="prev router-link-active">
Get Started
</a></span> <span class="next"><a href="/install/flagger-install-on-kubernetes.html">
On Kubernetes
</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/15.aada2caa.js" defer></script>
</body>
</html>