You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
4.4 KiB
125 lines
4.4 KiB
7 years ago
|
# This workflow performs a "blue-green" deployment, while preserving the original deployment object
|
||
|
# and name. It accomplishes this by temporarily redirecting traffic to a *clone* of the original
|
||
|
# deployment, then after upgrading the original deployment to a later version, transfering traffic
|
||
|
# back to the original (now upgraded) deployment.
|
||
|
apiVersion: argoproj.io/v1alpha1
|
||
|
kind: Workflow
|
||
|
metadata:
|
||
|
generateName: k8s-bluegreen-
|
||
|
spec:
|
||
|
entrypoint: k8s-bluegreen
|
||
|
arguments:
|
||
|
parameters:
|
||
|
- name: deployment-name
|
||
|
- name: service-name
|
||
|
- name: new-deployment-manifest
|
||
|
- name: new-service-manifest
|
||
|
|
||
|
templates:
|
||
|
- name: k8s-bluegreen
|
||
|
steps:
|
||
|
# 1. Create a parallel Kubernetes deployment with tweaks to name and selectors
|
||
|
- - name: create-blue-deployment
|
||
|
template: clone-deployment
|
||
|
|
||
|
# 2. Wait for parallel deployment to become ready
|
||
|
- - name: wait-for-blue-deployment
|
||
|
template: wait-deployment-ready
|
||
|
arguments:
|
||
|
parameters:
|
||
|
- name: deployment-name
|
||
|
value: '{{workflow.parameters.deployment-name}}-blue'
|
||
|
|
||
|
# 3. Patch the named service to point to the parallel deployment app
|
||
|
- - name: switch-service-to-blue-deployment
|
||
|
template: patch-service
|
||
|
|
||
|
# 4. Update the original deployment (receiving no traffic) with a new version
|
||
|
- - name: apply-green-deployment
|
||
|
template: apply-manifest
|
||
|
arguments:
|
||
|
parameters:
|
||
|
- name: manifest
|
||
|
value: '{{workflow.parameters.new-deployment-manifest}}'
|
||
|
|
||
|
# 5. Wait for the original deployment, now updated, to become ready
|
||
|
- - name: wait-for-green-deployment
|
||
|
template: wait-deployment-ready
|
||
|
arguments:
|
||
|
parameters:
|
||
|
- name: deployment-name
|
||
|
value: '{{workflow.parameters.deployment-name}}'
|
||
|
|
||
|
# dummy approval step for demo purposes. Sleeps for 30 seconds
|
||
|
- - name: approve
|
||
|
template: approve
|
||
|
|
||
|
# 6. Patch the named service to point to the original, now updated app
|
||
|
- - name: switch-service-to-green-deployment
|
||
|
template: apply-manifest
|
||
|
arguments:
|
||
|
parameters:
|
||
|
- name: manifest
|
||
|
value: '{{workflow.parameters.new-service-manifest}}'
|
||
|
|
||
|
# 7. Remove the cloned deployment (no longer receiving traffic)
|
||
|
- - name: delete-cloned-deployment
|
||
|
template: delete-deployment
|
||
|
|
||
|
# end of steps
|
||
|
|
||
|
# clone deployment creates a "blue" clone of an existing deployment.
|
||
|
# -blue is appended to the metadata.name, as well as the values in the spec.selector.matchLabels,
|
||
|
# and spec.template.metadata.labels
|
||
|
- name: clone-deployment
|
||
|
container:
|
||
|
image: argoproj/argoexec:v2.1.1
|
||
|
command: [sh, -c, -x]
|
||
|
args:
|
||
|
- kubectl get --export -o json deployment.apps/{{workflow.parameters.deployment-name}} > /tmp/original-deploy &&
|
||
|
jq -r '.metadata.name+="-blue" |
|
||
|
.spec.template.metadata.labels += (.spec.template.metadata.labels | to_entries | map(select(.key != "applications.argoproj.io/app-name")) | map(.value+="-blue") | from_entries) |
|
||
|
.spec.selector.matchLabels += (.spec.selector.matchLabels | to_entries | map(select(.key != "applications.argoproj.io/app-name")) | map(.value+="-blue") | from_entries)'
|
||
|
/tmp/original-deploy > /tmp/cloned-deploy &&
|
||
|
cat /tmp/cloned-deploy &&
|
||
|
kubectl apply -o yaml -f /tmp/cloned-deploy
|
||
|
|
||
|
- name: apply-manifest
|
||
|
inputs:
|
||
|
parameters:
|
||
|
- name: manifest
|
||
|
resource:
|
||
|
action: apply
|
||
|
manifest: '{{inputs.parameters.manifest}}'
|
||
|
|
||
|
- name: wait-deployment-ready
|
||
|
inputs:
|
||
|
parameters:
|
||
|
- name: deployment-name
|
||
|
container:
|
||
|
image: argoproj/argoexec:v2.1.1
|
||
|
command: [kubectl, rollout, status, --watch=true, 'deployments/{{inputs.parameters.deployment-name}}']
|
||
|
|
||
|
- name: patch-service
|
||
|
container:
|
||
|
image: argoproj/argoexec:v2.1.1
|
||
|
command: [sh, -c, -x]
|
||
|
args:
|
||
|
- kubectl get -n default service {{workflow.parameters.service-name}} --export -o json > /tmp/original-svc &&
|
||
|
jq '.spec.selector = (.spec.selector | with_entries(.value+="-blue"))' /tmp/original-svc > /tmp/blue-svc &&
|
||
|
kubectl apply -o yaml -f /tmp/blue-svc
|
||
|
|
||
|
- name: delete-deployment
|
||
|
resource:
|
||
|
action: delete
|
||
|
manifest: |
|
||
|
apiVersion: apps/v1
|
||
|
kind: Deployment
|
||
|
metadata:
|
||
|
name: {{workflow.parameters.deployment-name}}-blue
|
||
|
|
||
|
- name: approve
|
||
|
container:
|
||
|
image: argoproj/argoexec:v2.1.1
|
||
|
command: [sleep, "30"]
|