10 changed files with 259 additions and 0 deletions
			
			
		| @ -0,0 +1,4 @@ | |||||
|  | /lib | ||||
|  | /.ksonnet/registries | ||||
|  | /app.override.yaml | ||||
|  | /.ks_environment | ||||
| @ -0,0 +1,11 @@ | |||||
|  | apiVersion: 0.1.0 | ||||
|  | environments: | ||||
|  |   default: | ||||
|  |     destination: | ||||
|  |       namespace: default | ||||
|  |       server: https://kubernetes.default.svc | ||||
|  |     k8sVersion: v1.10.0 | ||||
|  |     path: default | ||||
|  | kind: ksonnet.io/app | ||||
|  | name: blue-green-deploy | ||||
|  | version: 0.0.1 | ||||
| @ -0,0 +1,3 @@ | |||||
|  | workflows: | ||||
|  | - name: blue-green | ||||
|  |   path: workflows/bluegreen.yaml | ||||
| @ -0,0 +1,68 @@ | |||||
|  | local env = std.extVar("__ksonnet/environments"); | ||||
|  | local params = std.extVar("__ksonnet/params").components["bg-deploy"]; | ||||
|  | [ | ||||
|  |    { | ||||
|  |       "apiVersion": "v1", | ||||
|  |       "kind": "Service", | ||||
|  |       "metadata": { | ||||
|  |          "name": params.name, | ||||
|  |          "annotations": { | ||||
|  |             "argocd.argoproj.io/workflow-sync": "blue-green", | ||||
|  |             "argocd.argoproj.io/workflow-param.blue-green.service-name": params.name, | ||||
|  |             "argocd.argoproj.io/workflow-param.blue-green.new-service-manifest": "{{manifest}}", | ||||
|  |          }, | ||||
|  |       }, | ||||
|  |       "spec": { | ||||
|  |          "ports": [ | ||||
|  |             { | ||||
|  |                "port": params.servicePort, | ||||
|  |                "targetPort": params.containerPort | ||||
|  |             } | ||||
|  |          ], | ||||
|  |          "selector": { | ||||
|  |             "app": params.name | ||||
|  |          }, | ||||
|  |          "type": params.type | ||||
|  |       } | ||||
|  |    }, | ||||
|  |    { | ||||
|  |       "apiVersion": "apps/v1beta2", | ||||
|  |       "kind": "Deployment", | ||||
|  |       "metadata": { | ||||
|  |          "name": params.name, | ||||
|  |          "annotations": { | ||||
|  |             "argocd.argoproj.io/workflow-sync": "blue-green", | ||||
|  |             "argocd.argoproj.io/workflow-param.blue-green.deployment-name": params.name, | ||||
|  |             "argocd.argoproj.io/workflow-param.blue-green.new-deployment-manifest": "{{manifest}}", | ||||
|  |          }, | ||||
|  |       }, | ||||
|  |       "spec": { | ||||
|  |          "replicas": params.replicas, | ||||
|  |          "selector": { | ||||
|  |             "matchLabels": { | ||||
|  |                "app": params.name | ||||
|  |             }, | ||||
|  |          }, | ||||
|  |          "template": { | ||||
|  |             "metadata": { | ||||
|  |                "labels": { | ||||
|  |                   "app": params.name | ||||
|  |                } | ||||
|  |             }, | ||||
|  |             "spec": { | ||||
|  |                "containers": [ | ||||
|  |                   { | ||||
|  |                      "image": params.image, | ||||
|  |                      "name": params.name, | ||||
|  |                      "ports": [ | ||||
|  |                      { | ||||
|  |                         "containerPort": params.containerPort | ||||
|  |                      } | ||||
|  |                      ] | ||||
|  |                   } | ||||
|  |                ] | ||||
|  |             } | ||||
|  |          } | ||||
|  |       } | ||||
|  |    } | ||||
|  | ] | ||||
| @ -0,0 +1,18 @@ | |||||
|  | { | ||||
|  |   global: { | ||||
|  |     // User-defined global parameters; accessible to all component and environments, Ex: | ||||
|  |     // replicas: 4, | ||||
|  |   }, | ||||
|  |   components: { | ||||
|  |     // Component-level parameters, defined initially from 'ks prototype use ...' | ||||
|  |     // Each object below should correspond to a component in the components/ directory | ||||
|  |     "bg-deploy": { | ||||
|  |       containerPort: 80, | ||||
|  |       image: "gcr.io/heptio-images/ks-guestbook-demo:0.1", | ||||
|  |       name: "bg-deploy", | ||||
|  |       replicas: 3, | ||||
|  |       servicePort: 80, | ||||
|  |       type: "LoadBalancer", | ||||
|  |     }, | ||||
|  |   }, | ||||
|  | } | ||||
| @ -0,0 +1,4 @@ | |||||
|  | local components = std.extVar("__ksonnet/components"); | ||||
|  | components + { | ||||
|  |   // Insert user-specified overrides here. | ||||
|  | } | ||||
| @ -0,0 +1,2 @@ | |||||
|  | { | ||||
|  | } | ||||
| @ -0,0 +1,8 @@ | |||||
|  | local base = import "base.libsonnet"; | ||||
|  | // uncomment if you reference ksonnet-lib | ||||
|  | // local k = import "k.libsonnet"; | ||||
|  | 
 | ||||
|  | base + { | ||||
|  |   // Insert user-specified overrides here. For example if a component is named \"nginx-deployment\", you might have something like:\n") | ||||
|  |   // "nginx-deployment"+: k.deployment.mixin.metadata.labels({foo: "bar"}) | ||||
|  | } | ||||
| @ -0,0 +1,17 @@ | |||||
|  | local params = std.extVar("__ksonnet/params"); | ||||
|  | local globals = import "globals.libsonnet"; | ||||
|  | local envParams = params + { | ||||
|  |   components +: { | ||||
|  |     // Insert component parameter overrides here. Ex: | ||||
|  |     // guestbook +: { | ||||
|  |     //   name: "guestbook-dev", | ||||
|  |     //   replicas: params.global.replicas, | ||||
|  |     // }, | ||||
|  |   }, | ||||
|  | }; | ||||
|  | 
 | ||||
|  | { | ||||
|  |   components: { | ||||
|  |     [x]: envParams.components[x] + globals, for x in std.objectFields(envParams.components) | ||||
|  |   }, | ||||
|  | } | ||||
| @ -0,0 +1,124 @@ | |||||
|  | # 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"] | ||||
					Loading…
					
					
				
		Reference in new issue