A canary deployment is more complex than a blue-green deployment. It requires a service mesh to route traffic to the canary version of the application. In this example, we will use Istio.
Requirements
Prometheus (required for analysis templates)
Configuration
Create a service definition:
Copy apiVersion : v1
kind : Service
metadata :
name : demo-app
spec :
selector :
app : demo-app
ports :
- name : http-web
appProtocol : http
port : 80
Create a destination rule definition:
Copy apiVersion : networking.istio.io/v1alpha3
kind : DestinationRule
metadata :
name : demo-app-destination-rule
spec :
host : demo-app.demo-app.svc.cluster.local
subsets :
- name : stable
labels :
app : demo-app
- name : canary
labels :
app : demo-app
Create a virtual service definition with destination routing rules:
Copy apiVersion : networking.istio.io/v1alpha3
kind : VirtualService
metadata :
name : demo-app-vs
spec :
hosts :
- "demo-app.ms1.com"
gateways :
- demo-app-gateway
http :
- name : primary
route :
- destination :
host : demo-app.demo-app.svc.cluster.local
subset : stable
weight : 100
- destination :
host : demo-app.demo-app.svc.cluster.local
subset : canary
weight : 0
Create a gateway definition:
Copy apiVersion : networking.istio.io/v1alpha3
kind : Gateway
metadata :
name : demo-app-gateway
spec :
selector :
istio : ingressgateway
servers :
- port :
number : 80
name : http-web
protocol : HTTP
hosts :
- "demo-app.ms1.com"
Create an analysis template
Copy apiVersion : argoproj.io/v1alpha1
kind : AnalysisTemplate
metadata :
name : istio-success-rate
spec :
args :
- name : demo-app
- name : demo-app
metrics :
- name : success-rate
initialDelay : 60s
interval : 20s
successCondition : result[0] > 0.90
provider :
prometheus :
address : http://prometheus.istio-system:9090
query : >+
sum(irate(istio_requests_total{
reporter="source",
destination_service=~"{{args.service}}.{{args.namespace}}.svc.cluster.local",
response_code!~"5.*"}[40s])
)
/
sum(irate(istio_requests_total{
reporter="source",
destination_service=~"{{args.service}}.{{args.namespace}}.svc.cluster.local"}[40s])
)
Create a rollout resource with the following configuration:
A rollout configuration encapulates a replicaset definition. No need to write both the rollout and the replicaset.
Copy apiVersion : argoproj.io/v1alpha1
kind : Rollout
metadata :
name : demo-app-canary-rollout
spec :
strategy :
canary :
trafficRouting :
istio :
virtualService :
name : demo-app-vs
routes :
- primary
destinationRule :
name : demo-app-destination-rule
canarySubsetName : canary
stableSubsetName : stable
steps :
- setWeight : 10
- pause :
duration : 2s
- setWeight : 30
- pause :
duration : 2s
- setWeight : 50
- pause :
duration : 2s
analysis :
templates :
- templateName : istio-success-rate
startingStep : 1
args :
- name : service
value : demo-app.demo-app.svc.cluster.local
- name : namespace
value : demo-app
selector :
matchLabels :
app : demo-app
template :
metadata :
labels :
app : demo-app
spec :
serviceAccountName : demo-app
containers :
- name : demo-app
image : memogarcia10/demo-app:v4
imagePullPolicy : Always
ports :
- containerPort : 80
name : http-web
securityContext :
runAsUser : 1000
resources :
limits :
cpu : 5m
memory : 64Mi