Skip to content

Commit 5c5b29c

Browse files
authored
Allow traffic switch before stack is 100% Ready (#456)
Given the need for switching traffic to a stack that isn't 100% ready yet, the minReadyPercent StackSet field allows setting a minimum percentage of ready replicas required to enable the traffic switch. minReadyPercent is optional and expects values from 1 to 100. In case of value equal to or under 0 or over 100, it's normalized to 100, which keeps the original behaviour.
1 parent a133914 commit 5c5b29c

File tree

8 files changed

+278
-32
lines changed

8 files changed

+278
-32
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ spec:
7676
weight: 80
7777
- stackName: mystack-v2
7878
weight: 20
79+
# optional percentage of required Replicas ready to allow traffic switch
80+
# if none specified, defaults to 100
81+
minReadyPercent: 90
7982
stackLifecycle:
8083
scaledownTTLSeconds: 300
8184
limit: 5 # maximum number of scaled down stacks to keep.

docs/stackset.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ spec:
1313
weight: 40
1414
- stackName: my-app-v2
1515
weight: 60
16+
minReadyPercent: 90
1617
stackLifecycle:
1718
scaledownTTLSeconds: 300
1819
limit: 5

docs/stackset_crd.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ spec:
103103
- backendPort
104104
- hosts
105105
type: object
106+
minReadyPercent:
107+
description: minReadyPercent sets the minimum percentage of Pods expected
108+
to be Ready to consider a Stack for traffic switch
109+
type: integer
106110
routegroup:
107111
description: RouteGroup is an alternative to ingress allowing more
108112
advanced routing configuration while still maintaining the ability

pkg/apis/zalando.org/v1/types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ type StackSetSpec struct {
6161
// weights. It defines the desired traffic. Clients that
6262
// orchestrate traffic switching should write this part.
6363
Traffic []*DesiredTraffic `json:"traffic,omitempty"`
64+
// minReadyPercent sets the minimum percentage of Pods expected
65+
// to be Ready to consider a Stack for traffic switch
66+
MinReadyPercent int `json:"minReadyPercent,omitempty"`
6467
}
6568

6669
// EmbeddedObjectMetaWithAnnotations defines the metadata which can be attached

pkg/core/test_helpers.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,14 @@ func testStack(name string) *testStackFactory {
4545
}
4646

4747
func (f *testStackFactory) ready(replicas int32) *testStackFactory {
48+
return f.partiallyReady(replicas, replicas)
49+
}
50+
51+
func (f *testStackFactory) partiallyReady(readyReplicas, replicas int32) *testStackFactory {
4852
f.container.resourcesUpdated = true
4953
f.container.deploymentReplicas = replicas
50-
f.container.updatedReplicas = replicas
51-
f.container.readyReplicas = replicas
54+
f.container.updatedReplicas = readyReplicas
55+
f.container.readyReplicas = readyReplicas
5256
return f
5357
}
5458

pkg/core/traffic.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ func allZero(weights map[string]float64) bool {
2121
return true
2222
}
2323

24+
// normalizeMinReadyPercent normalizes minimum percentage of Ready pods.
25+
// If value is under or equal to 0, or over or equal to 100, set it to 1.0
26+
// If value is between 0-100, it's then set as decimal
27+
func normalizeMinReadyPercent(minReadyPercent int) float64 {
28+
if minReadyPercent >= 100 || minReadyPercent <= 0 {
29+
return 1.0
30+
}
31+
return float64(minReadyPercent) / 100
32+
}
33+
2434
// normalizeWeights normalizes a map of backend weights.
2535
// If all weights are zero the total weight of 100 is distributed equally
2636
// between all backends.
@@ -155,9 +165,11 @@ func (ssc *StackSetContainer) ManageTraffic(currentTimestamp time.Time) error {
155165
}
156166
}
157167

168+
minReadyPercent := normalizeMinReadyPercent(ssc.StackSet.Spec.MinReadyPercent)
158169
for stackName, stack := range stacks {
159170
stack.desiredTrafficWeight = desiredWeights[stackName]
160171
stack.actualTrafficWeight = actualWeights[stackName]
172+
stack.minReadyPercent = minReadyPercent
161173
}
162174

163175
// Run the traffic reconciler which will update the actual weights according to the desired weights. The resulting

0 commit comments

Comments
 (0)