Canary Deployments with Argo Rollouts and Istio
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
Istio
ArgoCD
Argo Rollouts
Prometheus (required for analysis templates)
Configuration
Create a service definition:
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:
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:
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:
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
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.
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
Last updated