support rollout trait

Signed-off-by: 天元 <jianbo.sjb@alibaba-inc.com>
This commit is contained in:
天元
2020-11-10 20:13:27 +08:00
parent 025ce5d74d
commit fd3f300901
10 changed files with 203 additions and 23 deletions
@@ -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
}
+4 -4
View File
@@ -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"
}
}
+1 -1
View File
@@ -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: <ingress-IP-address>
```
**In [kind cluster setup](../../install.md#kind)**, you can visit the service via localhost:
+81 -1
View File
@@ -1,3 +1,83 @@
# Setting Rollout Strategy
> TODO
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: <your-ingress-IP-address>
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://<your-ingress-IP-address>/
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.
<details>
<summary>Under the hood, it was flagger canary running.</summary>
```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
```
</details>
@@ -15,7 +15,6 @@ spec:
provider: smi
progressDeadlineSeconds: 60
service:
name: rollout-demo-app
# ClusterIP port number
port: 80
# container port number or name
+3 -3
View File
@@ -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 (
+6 -8
View File
@@ -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=
+35
View File
@@ -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
}
@@ -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: |-
+9 -5
View File
@@ -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 {