diff --git a/charts/vela-core/templates/addons/istio.yaml b/charts/vela-core/templates/addons/istio.yaml index bf42e033b..32718fb8b 100644 --- a/charts/vela-core/templates/addons/istio.yaml +++ b/charts/vela-core/templates/addons/istio.yaml @@ -120,6 +120,82 @@ data: \ port: int\n}\n\n#uri: {\n exact?: string\n prefix?: string\n} \n" type: raw + - name: canary-rollback + properties: + apiVersion: core.oam.dev/v1beta1 + kind: WorkflowStepDefinition + metadata: + name: canary-rollback + namespace: vela-system + spec: + schematic: + cue: + template: |- + import ("vela/op") + + parameter: {...} + + comps: op.#Load + compNames: [ for name, c in comps.value {name}] + firstcomp: compNames[0] + + rolloutObj: op.#Read & { + value: { + apiVersion: "standard.oam.dev/v1alpha1" + kind: "Rollout" + metadata: { + name: firstcomp + namespace: context.namespace + } + } + } + + _sourceRevision: rolloutObj.value.status.LastSourceRevision + + apply: op.#ApplyComponent & { + value: comps.value[firstcomp] + patch: { + traits: "rollout": { + spec: { + targetRevisionName: _sourceRevision + } + } + + traits: "virtualService": { + spec: + // +patchStrategy=retainKeys + http: [ + { + route: [{ + destination: { + host: firstcomp + subset: _sourceRevision + } + weight: 100 + }] + }, + ] + } + + traits: "destinationRule": { + // +patchStrategy=retainKeys + spec: { + host: firstcomp + subsets: [ + { + name: _sourceRevision + labels: {"app.oam.dev/revision": _sourceRevision} + }, + ] + } + } + } + } + + applyRemaining: op.#ApplyRemaining & { + exceptions: [firstcomp] + } + type: raw - name: canary-traffic properties: apiVersion: core.oam.dev/v1beta1 diff --git a/docs/examples/canary-rollout-use-case/README.md b/docs/examples/canary-rollout-use-case/README.md index 18de12474..9a5d16085 100644 --- a/docs/examples/canary-rollout-use-case/README.md +++ b/docs/examples/canary-rollout-use-case/README.md @@ -21,21 +21,25 @@ kubectl label namespace default istio-injection=enabled kubectl apply -f first-deploy.yaml ``` -Wait a few minutes all pods have been ready. Use kubectl port-forward map gateway's service port to localhost. +Wait a few minutes until all pods are ready. Use kubectl port-forward map gateway's service port to localhost. ```shell kubectl port-forward service/istio-ingressgateway -n istio-system 19082:80 ``` -Request `127.0.0.1:19082` in your browser will see webpage like this. +Request http://127.0.0.1:19082/productpage in your browser will see webpage like this. ![pic-v1](../../resources/canary-pic-v2.jpg) ## Canary Rollout -Update application to define a canary rollout workflow. This workflow will suspend after only upgrade one batch pods of `reviews` component and shift 10% traffic to new revision. It's give user some time to manual-check. +Update the Application to define a canary rollout workflow. +This workflow will suspend after rolling the first batch of new `reviews` pods and shift 10% traffic to new revision. +It waits for user to do manual-check. + ```shell kubectl apply -f rollout-v2.yaml ``` -Wait a few minutes new revision pods ready. Request `127.0.0.1:19082` in your browser again several times. Will see almost 90% chance see previous the webpage and 10% chance see the new webpage whose reviews will display red starts like this. + +Wait a few minutes new revision pods ready. Request http://127.0.0.1:19082/productpage in your browser again several times. Will see almost 90% chance see previous the webpage and 10% chance see the new webpage whose reviews will display red starts like this. ![pic-v2](../../resources/canary-pic-v3.jpg) @@ -47,13 +51,14 @@ resume workflow to continue rollout rest replicas and shift all traffic to new r vela workflow reumse book-info ``` -By request again. You will always see the new webpage +Request again. You will always see the new webpage -### Cancel rollout workflow and revert. +### Rollback to the first deployment + +If you find some problems after manual-check and want to revert to previous revision, you can rollback to the first deployment. -If you find some problems after manual-check and want to revert to previous revision. You can cancel the rollout workflow and revert. ```shell -kubectl apply -f revert-in-middle.yaml +kubectl apply -f rollback.yaml ``` By request again. You will always see the old webpage diff --git a/docs/examples/canary-rollout-use-case/revert-in-middle.yaml b/docs/examples/canary-rollout-use-case/rollback.yaml similarity index 53% rename from docs/examples/canary-rollout-use-case/revert-in-middle.yaml rename to docs/examples/canary-rollout-use-case/rollback.yaml index dd3fdc853..7e0a25870 100644 --- a/docs/examples/canary-rollout-use-case/revert-in-middle.yaml +++ b/docs/examples/canary-rollout-use-case/rollback.yaml @@ -20,61 +20,60 @@ spec: traits: + - type: rollout + properties: + targetSize: 2 + # This means to rollout two more replicas in two batches. + rolloutBatches: + - replicas: 1 + - replicas: 1 + - type: canary-traffic properties: port: - 9080 - - type: rollout - properties: - targetRevision: reviews-v1 - batchPartition: 1 - targetSize: 2 - # This means to rollout two more replicas in two batches. - rolloutBatches: - - replicas: 2 - - name: productpage type: webservice properties: - image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2 - port: 9080 + image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2 + port: 9080 traits: - - type: expose - properties: - port: - - 9080 + - type: expose + properties: + port: + - 9080 - - type: istio-gateway - properties: - hosts: - - "*" - gateway: ingressgateway - match: - - exact: /productpage - - prefix: /static - - exact: /login - - prefix: /api/v1/products - port: 9080 + - type: istio-gateway + properties: + hosts: + - "*" + gateway: ingressgateway + match: + - exact: /productpage + - prefix: /static + - exact: /login + - prefix: /api/v1/products + port: 9080 - name: ratings type: webservice properties: - image: docker.io/istio/examples-bookinfo-ratings-v1:1.16.2 - port: 9080 + image: docker.io/istio/examples-bookinfo-ratings-v1:1.16.2 + port: 9080 traits: - - type: expose - properties: - port: - - 9080 + - type: expose + properties: + port: + - 9080 - name: details type: webservice properties: - image: docker.io/istio/examples-bookinfo-details-v1:1.16.2 - port: 9080 + image: docker.io/istio/examples-bookinfo-details-v1:1.16.2 + port: 9080 traits: - type: expose @@ -82,4 +81,7 @@ spec: port: - 9080 - + workflow: + steps: + - name: rollback + type: canary-rollback diff --git a/vela-templates/addons/auto-gen/istio.yaml b/vela-templates/addons/auto-gen/istio.yaml index dbdcf88e2..9b89ee0e5 100644 --- a/vela-templates/addons/auto-gen/istio.yaml +++ b/vela-templates/addons/auto-gen/istio.yaml @@ -117,6 +117,82 @@ spec: \ port: int\n}\n\n#uri: {\n exact?: string\n prefix?: string\n} \n" type: raw + - name: canary-rollback + properties: + apiVersion: core.oam.dev/v1beta1 + kind: WorkflowStepDefinition + metadata: + name: canary-rollback + namespace: vela-system + spec: + schematic: + cue: + template: |- + import ("vela/op") + + parameter: {...} + + comps: op.#Load + compNames: [ for name, c in comps.value {name}] + firstcomp: compNames[0] + + rolloutObj: op.#Read & { + value: { + apiVersion: "standard.oam.dev/v1alpha1" + kind: "Rollout" + metadata: { + name: firstcomp + namespace: context.namespace + } + } + } + + _sourceRevision: rolloutObj.value.status.LastSourceRevision + + apply: op.#ApplyComponent & { + value: comps.value[firstcomp] + patch: { + traits: "rollout": { + spec: { + targetRevisionName: _sourceRevision + } + } + + traits: "virtualService": { + spec: + // +patchStrategy=retainKeys + http: [ + { + route: [{ + destination: { + host: firstcomp + subset: _sourceRevision + } + weight: 100 + }] + }, + ] + } + + traits: "destinationRule": { + // +patchStrategy=retainKeys + spec: { + host: firstcomp + subsets: [ + { + name: _sourceRevision + labels: {"app.oam.dev/revision": _sourceRevision} + }, + ] + } + } + } + } + + applyRemaining: op.#ApplyRemaining & { + exceptions: [firstcomp] + } + type: raw - name: canary-traffic properties: apiVersion: core.oam.dev/v1beta1 diff --git a/vela-templates/addons/istio/definitions/rollback-wf-def.yaml b/vela-templates/addons/istio/definitions/rollback-wf-def.yaml new file mode 100644 index 000000000..31a8066ee --- /dev/null +++ b/vela-templates/addons/istio/definitions/rollback-wf-def.yaml @@ -0,0 +1,73 @@ +apiVersion: core.oam.dev/v1beta1 +kind: WorkflowStepDefinition +metadata: + name: canary-rollback + namespace: vela-system +spec: + schematic: + cue: + template: |- + import ("vela/op") + + parameter: {...} + + comps: op.#Load + compNames: [ for name, c in comps.value {name}] + firstcomp: compNames[0] + + rolloutObj: op.#Read & { + value: { + apiVersion: "standard.oam.dev/v1alpha1" + kind: "Rollout" + metadata: { + name: firstcomp + namespace: context.namespace + } + } + } + + _sourceRevision: rolloutObj.value.status.LastSourceRevision + + apply: op.#ApplyComponent & { + value: comps.value[firstcomp] + patch: { + traits: "rollout": { + spec: { + targetRevisionName: _sourceRevision + } + } + + traits: "virtualService": { + spec: + // +patchStrategy=retainKeys + http: [ + { + route: [{ + destination: { + host: firstcomp + subset: _sourceRevision + } + weight: 100 + }] + }, + ] + } + + traits: "destinationRule": { + // +patchStrategy=retainKeys + spec: { + host: firstcomp + subsets: [ + { + name: _sourceRevision + labels: {"app.oam.dev/revision": _sourceRevision} + }, + ] + } + } + } + } + + applyRemaining: op.#ApplyRemaining & { + exceptions: [firstcomp] + }