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.
Istio
ArgoCD
Argo Rollouts
Prometheus (required for analysis templates)
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:
Create a virtual service definition with destination routing rules:
Create a gateway definition:
Create an analysis template
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.
Last updated 2 years ago
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
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
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"
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]) )
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