From fd3f3009015b291ab092173b255cd57d931ae5f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A9=E5=85=83?= Date: Fri, 6 Nov 2020 13:02:45 +0800 Subject: [PATCH] support rollout trait MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 天元 --- .../templates/defwithtemplate/rollout.yaml | 50 +++++++++++ charts/vela-core/templates/velaConfig.yaml | 8 +- docs/en/developers/devex/appfile.md | 2 +- docs/en/developers/set-rollout.md | 82 ++++++++++++++++++- .../rollout-demo/appConfig-rollout-v1.yaml | 1 - go.mod | 6 +- go.sum | 14 ++-- hack/vela-templates/cue/rollout.cue | 35 ++++++++ hack/vela-templates/definitions/rollout.yaml | 14 ++++ pkg/oam/trait.go | 14 ++-- 10 files changed, 203 insertions(+), 23 deletions(-) create mode 100644 charts/vela-core/templates/defwithtemplate/rollout.yaml create mode 100644 hack/vela-templates/cue/rollout.cue create mode 100644 hack/vela-templates/definitions/rollout.yaml diff --git a/charts/vela-core/templates/defwithtemplate/rollout.yaml b/charts/vela-core/templates/defwithtemplate/rollout.yaml new file mode 100644 index 000000000..6dca0977c --- /dev/null +++ b/charts/vela-core/templates/defwithtemplate/rollout.yaml @@ -0,0 +1,50 @@ +apiVersion: core.oam.dev/v1alpha2 +kind: TraitDefinition +metadata: + name: rollout +spec: + appliesToWorkloads: + - podspecworkload.standard.oam.dev + - deployments.apps + definitionRef: + name: canaries.flagger.app + workloadRefPath: spec.targetRef + revisionEnabled: true + extension: + template: |- + output: { + apiVersion: "flagger.app/v1beta1" + kind: "Canary" + spec: { + provider: "smi" + progressDeadlineSeconds: 60 + service: { + // Currently Traffic route is not supported, but this is required field for flagger CRD + port: 80 + // Currently Traffic route is not supported, but this is required field for flagger CRD + targetPort: 8080 + } + analysis: { + interval: parameter.interval + // max number of failed metric checks before rollback + threshold: 10 + // max traffic percentage routed to canary + // percentage (0-100) + maxWeight: 50 + // canary increment step + // percentage (0-100) + stepWeight: parameter.stepWeight + // max replicas scale up to canary + maxReplicas: parameter.replica + } + } + } + parameter: { + // +usage=total replica of the workload + replica: *5 | int + // +alias=step-weight + // +usage=weight percent of every step in rolling update + stepWeight: *20 | int + interval: *"30s" | string + } + diff --git a/charts/vela-core/templates/velaConfig.yaml b/charts/vela-core/templates/velaConfig.yaml index 5cb96c18f..701805678 100644 --- a/charts/vela-core/templates/velaConfig.yaml +++ b/charts/vela-core/templates/velaConfig.yaml @@ -14,11 +14,11 @@ data: } flagger.app: | { - "repo": "flagger", - "urL": "https://flagger.app", + "repo": "oam-flagger", + "urL": "https://oam.dev/flagger/archives/", "name": "flagger", "namespace": "vela-system", - "version": "1.2.0" + "version": "1.1.0" } keda: | { @@ -27,4 +27,4 @@ data: "name": "keda", "namespace": "keda", "version": "2.0.0-rc3" - } + } \ No newline at end of file diff --git a/docs/en/developers/devex/appfile.md b/docs/en/developers/devex/appfile.md index dbc2a3689..c103dd333 100644 --- a/docs/en/developers/devex/appfile.md +++ b/docs/en/developers/devex/appfile.md @@ -188,7 +188,7 @@ Services: Created at: ... Updated at: ... Routes: - - route: Visiting URL: http://example.com IP: localhost + - route: Visiting URL: http://example.com IP: ``` **In [kind cluster setup](../../install.md#kind)**, you can visit the service via localhost: diff --git a/docs/en/developers/set-rollout.md b/docs/en/developers/set-rollout.md index 601964fd5..8f9e0d1b0 100644 --- a/docs/en/developers/set-rollout.md +++ b/docs/en/developers/set-rollout.md @@ -1,3 +1,83 @@ # Setting Rollout Strategy -> TODO \ No newline at end of file +You could use rollout capability to rolling upgrade your app. + +The workflow will like below: + +Firstly, deploy your app by: + +```shell script +$ vela svc deploy testapp -t webservice --image oamdev/testapp:v1 --port 8080 +App testapp deployed +``` + +Add route for visit: + +```shell script +$ vela route testapp --domain myhost.com +Adding route for app testapp +⠋ Checking Status ... +✅ Application Deployed Successfully! + - Name: testapp + Type: webservice + HEALTHY Ready: 1/1 + Traits: + - ✅ route: Visiting URL: http://myhost.com IP: + + Last Deployment: + Created at: 2020-11-09 12:50:30 +0800 CST + Updated at: 2020-11-09T12:51:19+08:00 +``` + +```shell script +$ curl -H "Host:myhost.com" http:/// +Hello World% +``` + +Secondly, add rollout policy for your app: + +```shell script +vela rollout testapp --replica 5 --step-weight 20 --interval 5s +``` + +Then update your app by: + +```shell script +vela svc deploy testapp -t webservice --image oamdev/testapp:v2 --port 8080 +``` + +Then it will rolling update your instance, you could try `curl` your app multiple times: + +```shell script +$ curl -H "Host:myhost.com" http://39.97.232.19/ +Hello World -- Updated Version Two!% +$ curl -H "Host:myhost.com" http://39.97.232.19/ +Hello World% +$ curl -H "Host:myhost.com" http://39.97.232.19/ +Hello World% +$ curl -H "Host:myhost.com" http://39.97.232.19/ +Hello World -- Updated Version Two!% +$ curl -H "Host:myhost.com" http://39.97.232.19/ +Hello World% +$ curl -H "Host:myhost.com" http://39.97.232.19/ +Hello World -- Updated Version Two!% +``` + +It will return both version of output info as both instances are all existing. + +
+ Under the hood, it was flagger canary running. + +```shell script +$ kubectl get canaries.flagger.app testapp-trait-76fc76fddc -w +NAME STATUS WEIGHT LASTTRANSITIONTIME +testapp-trait-76fc76fddc Progressing 0 2020-11-10T09:06:10Z +testapp-trait-76fc76fddc Progressing 20 2020-11-10T09:06:30Z +testapp-trait-76fc76fddc Progressing 40 2020-11-10T09:06:40Z +testapp-trait-76fc76fddc Progressing 60 2020-11-10T09:07:31Z +testapp-trait-76fc76fddc Promoting 0 2020-11-10T09:08:00Z +testapp-trait-76fc76fddc Promoting 100 2020-11-10T09:08:10Z +testapp-trait-76fc76fddc Finalising 0 2020-11-10T09:08:20Z +testapp-trait-76fc76fddc Succeeded 0 2020-11-10T09:08:30Z +``` +
\ No newline at end of file diff --git a/e2e/raw-objects/samples/rollout-demo/appConfig-rollout-v1.yaml b/e2e/raw-objects/samples/rollout-demo/appConfig-rollout-v1.yaml index a91968a4d..2ca5a9bbe 100644 --- a/e2e/raw-objects/samples/rollout-demo/appConfig-rollout-v1.yaml +++ b/e2e/raw-objects/samples/rollout-demo/appConfig-rollout-v1.yaml @@ -15,7 +15,6 @@ spec: provider: smi progressDeadlineSeconds: 60 service: - name: rollout-demo-app # ClusterIP port number port: 80 # container port number or name diff --git a/go.mod b/go.mod index 274cb2534..1ec7a37aa 100644 --- a/go.mod +++ b/go.mod @@ -8,8 +8,8 @@ require ( github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 github.com/briandowns/spinner v1.11.1 github.com/coreos/prometheus-operator v0.41.1 - github.com/crossplane/crossplane-runtime v0.9.0 - github.com/crossplane/oam-kubernetes-runtime v0.3.0-rc1.0.20201027023226-ad311dba14a0 + github.com/crossplane/crossplane-runtime v0.10.0 + github.com/crossplane/oam-kubernetes-runtime v0.3.2 github.com/fatih/color v1.9.0 github.com/gertd/go-pluralize v0.1.7 github.com/ghodss/yaml v1.0.0 @@ -47,7 +47,7 @@ require ( k8s.io/klog v1.0.0 k8s.io/kubectl v0.18.6 k8s.io/utils v0.0.0-20200603063816-c1c6865ac451 - sigs.k8s.io/controller-runtime v0.6.1 + sigs.k8s.io/controller-runtime v0.6.2 ) replace ( diff --git a/go.sum b/go.sum index 18da83902..af8165631 100644 --- a/go.sum +++ b/go.sum @@ -412,18 +412,14 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/crossplane/crossplane-runtime v0.8.0 h1:IBm5LWVeqB2BjHpkykURHY0PSozXWfIXk7LfWtr27wY= -github.com/crossplane/crossplane-runtime v0.8.0/go.mod h1:gNY/21MLBaz5KNP7hmfXbBXp8reYRbwY5B/97Kp4tgM= -github.com/crossplane/crossplane-runtime v0.9.0 h1:K6/tLhXKzhsEUUddTvEWWnQLLrawWyw1ptNK7NBDpDU= -github.com/crossplane/crossplane-runtime v0.9.0/go.mod h1:gNY/21MLBaz5KNP7hmfXbBXp8reYRbwY5B/97Kp4tgM= -github.com/crossplane/crossplane-tools v0.0.0-20200219001116-bb8b2ce46330/go.mod h1:C735A9X0x0lR8iGVOOxb49Mt70Ua4EM2b7PGaRPBLd4= -github.com/crossplane/oam-kubernetes-runtime v0.3.0-rc1.0.20201027023226-ad311dba14a0 h1:GJFcWCOHMY8e8Tq5Tdm6k8pN4cct7nBOuLUDqhKldQs= -github.com/crossplane/oam-kubernetes-runtime v0.3.0-rc1.0.20201027023226-ad311dba14a0/go.mod h1:IHZdsf7012nElIUHhq4vNvmEDMMUI0UrHoXfp6bOsb4= +github.com/crossplane/crossplane-runtime v0.10.0 h1:H8YvMcrm1uzZYpwU/BpxjRQfceVulxgYJMx4rmX38Hg= +github.com/crossplane/crossplane-runtime v0.10.0/go.mod h1:cJl5ZZONisre4v6wTmbrC8Jh3AI+erq/lNaxZzv9tnU= +github.com/crossplane/oam-kubernetes-runtime v0.3.2 h1:iUBsYYn+33X1liRm6sn7oUA2hoXCWW8ik5QtATLZNxk= +github.com/crossplane/oam-kubernetes-runtime v0.3.2/go.mod h1:K4/F1XOPBvmW/PaRSPL3wNA4kCrFGUQC7WkBYcwIGx8= github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/daixiang0/gci v0.0.0-20200727065011-66f1df783cb2/go.mod h1:+AV8KmHTGxxwp/pY84TLQfFKp2vuKXXJVzF3kD/hfR4= github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= -github.com/dave/jennifer v1.3.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -2696,6 +2692,8 @@ sigs.k8s.io/controller-runtime v0.6.0 h1:Fzna3DY7c4BIP6KwfSlrfnj20DJ+SeMBK8HSFvO sigs.k8s.io/controller-runtime v0.6.0/go.mod h1:CpYf5pdNY/B352A1TFLAS2JVSlnGQ5O2cftPHndTroo= sigs.k8s.io/controller-runtime v0.6.1 h1:LcK2+nk0kmaOnKGN+vBcWHqY5WDJNJNB/c5pW+sU8fc= sigs.k8s.io/controller-runtime v0.6.1/go.mod h1:XRYBPdbf5XJu9kpS84VJiZ7h/u1hF3gEORz0efEja7A= +sigs.k8s.io/controller-runtime v0.6.2 h1:jkAnfdTYBpFwlmBn3pS5HFO06SfxvnTZ1p5PeEF/zAA= +sigs.k8s.io/controller-runtime v0.6.2/go.mod h1:vhcq/rlnENJ09SIRp3EveTaZ0yqH526hjf9iJdbUJ/E= sigs.k8s.io/controller-tools v0.2.4/go.mod h1:m/ztfQNocGYBgTTCmFdnK94uVvgxeZeE3LtJvd/jIzA= sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0= sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= diff --git a/hack/vela-templates/cue/rollout.cue b/hack/vela-templates/cue/rollout.cue new file mode 100644 index 000000000..472bd9ae9 --- /dev/null +++ b/hack/vela-templates/cue/rollout.cue @@ -0,0 +1,35 @@ +output: { + apiVersion: "flagger.app/v1beta1" + kind: "Canary" + spec: { + provider: "smi" + progressDeadlineSeconds: 60 + service: { + // Currently Traffic route is not supported, but this is required field for flagger CRD + port: 80 + // Currently Traffic route is not supported, but this is required field for flagger CRD + targetPort: 8080 + } + analysis: { + interval: parameter.interval + // max number of failed metric checks before rollback + threshold: 10 + // max traffic percentage routed to canary + // percentage (0-100) + maxWeight: 50 + // canary increment step + // percentage (0-100) + stepWeight: parameter.stepWeight + // max replicas scale up to canary + maxReplicas: parameter.replica + } + } +} +parameter: { + // +usage=total replica of the workload + replica: *5 | int + // +alias=step-weight + // +usage=weight percent of every step in rolling update + stepWeight: *20 | int + interval: *"30s" | string +} diff --git a/hack/vela-templates/definitions/rollout.yaml b/hack/vela-templates/definitions/rollout.yaml new file mode 100644 index 000000000..03419abd5 --- /dev/null +++ b/hack/vela-templates/definitions/rollout.yaml @@ -0,0 +1,14 @@ +apiVersion: core.oam.dev/v1alpha2 +kind: TraitDefinition +metadata: + name: rollout +spec: + appliesToWorkloads: + - podspecworkload.standard.oam.dev + - deployments.apps + definitionRef: + name: canaries.flagger.app + workloadRefPath: spec.targetRef + revisionEnabled: true + extension: + template: |- diff --git a/pkg/oam/trait.go b/pkg/oam/trait.go index c4503b5cc..ca37fb14a 100644 --- a/pkg/oam/trait.go +++ b/pkg/oam/trait.go @@ -173,19 +173,23 @@ func AddOrUpdateTrait(env *types.EnvMeta, appName string, componentName string, return app, err } for _, v := range template.Parameters { + name := v.Name + if v.Alias != "" { + name = v.Alias + } switch v.Type { case cue.IntKind: - traitData[v.Name], err = flagSet.GetInt64(v.Name) + traitData[v.Name], err = flagSet.GetInt64(name) case cue.StringKind: - traitData[v.Name], err = flagSet.GetString(v.Name) + traitData[v.Name], err = flagSet.GetString(name) case cue.BoolKind: - traitData[v.Name], err = flagSet.GetBool(v.Name) + traitData[v.Name], err = flagSet.GetBool(name) case cue.NumberKind, cue.FloatKind: - traitData[v.Name], err = flagSet.GetFloat64(v.Name) + traitData[v.Name], err = flagSet.GetFloat64(name) } if err != nil { - return nil, fmt.Errorf("get flag(s) \"%s\" err %v", v.Name, err) + return nil, fmt.Errorf("get flag(s) \"%s\" err %v", name, err) } } if err = app.SetTrait(componentName, traitAlias, traitData); err != nil {