Skip to content

Commit

Permalink
Merge pull request #1451 from miguelvalerio/fix-initialization-downtime
Browse files Browse the repository at this point in the history
Fix initial deployment downtime
  • Loading branch information
aryan9600 authored Aug 18, 2023
2 parents 2944581 + b25e12d commit ba7fedf
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 18 deletions.
10 changes: 2 additions & 8 deletions pkg/canary/daemonset_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@ func (c *DaemonSetController) ScaleFromZero(cd *flaggerv1.Canary) error {
return nil
}

// Initialize creates the primary DaemonSet, scales down the canary DaemonSet,
// and returns the pod selector label and container ports
// Initialize creates the primary DaemonSet if it does not exist.
func (c *DaemonSetController) Initialize(cd *flaggerv1.Canary) (err error) {
err = c.createPrimaryDaemonSet(cd, c.includeLabelPrefix)
if err != nil {
Expand All @@ -105,13 +104,8 @@ func (c *DaemonSetController) Initialize(cd *flaggerv1.Canary) (err error) {
return fmt.Errorf("%w", err)
}
}

c.logger.With("canary", fmt.Sprintf("%s.%s", cd.Name, cd.Namespace)).
Infof("Scaling down DaemonSet %s.%s", cd.Spec.TargetRef.Name, cd.Namespace)
if err := c.ScaleToZero(cd); err != nil {
return fmt.Errorf("ScaleToZero failed: %w", err)
}
}

return nil
}

Expand Down
9 changes: 1 addition & 8 deletions pkg/canary/deployment_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ type DeploymentController struct {
includeLabelPrefix []string
}

// Initialize creates the primary deployment, hpa,
// scales to zero the canary deployment and returns the pod selector label and container ports
// Initialize creates the primary deployment if it does not exist.
func (c *DeploymentController) Initialize(cd *flaggerv1.Canary) (err error) {
if err := c.createPrimaryDeployment(cd, c.includeLabelPrefix); err != nil {
return fmt.Errorf("createPrimaryDeployment failed: %w", err)
Expand All @@ -58,12 +57,6 @@ func (c *DeploymentController) Initialize(cd *flaggerv1.Canary) (err error) {
return fmt.Errorf("%w", err)
}
}

c.logger.With("canary", fmt.Sprintf("%s.%s", cd.Name, cd.Namespace)).
Infof("Scaling down Deployment %s.%s", cd.Spec.TargetRef.Name, cd.Namespace)
if err := c.ScaleToZero(cd); err != nil {
return fmt.Errorf("scaling down canary deployment %s.%s failed: %w", cd.Spec.TargetRef.Name, cd.Namespace, err)
}
}

return nil
Expand Down
10 changes: 10 additions & 0 deletions pkg/controller/scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,16 @@ func (c *Controller) advanceCanary(name string, namespace string) {
return
}

// scale down the canary target to 0 replicas after the service is pointing to the primary target
if cd.Status.Phase == "" || cd.Status.Phase == flaggerv1.CanaryPhaseInitializing {
c.logger.With("canary", fmt.Sprintf("%s.%s", cd.Name, cd.Namespace)).
Infof("Scaling down %s %s.%s", cd.Spec.TargetRef.Kind, cd.Spec.TargetRef.Name, cd.Namespace)
if err := canaryController.ScaleToZero(cd); err != nil {
c.recordEventWarningf(cd, "scaling down canary %s %s.%s failed: %v", cd.Spec.TargetRef.Kind, cd.Spec.TargetRef.Name, cd.Namespace, err)
return
}
}

// take over an existing virtual service or ingress
// runs after the primary is ready to ensure zero downtime
if !strings.HasPrefix(provider, flaggerv1.AppMeshProvider) {
Expand Down
7 changes: 6 additions & 1 deletion pkg/controller/scheduler_daemonset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,14 @@ func TestScheduler_DaemonSetNewRevision(t *testing.T) {
mocks := newDaemonSetFixture(nil)
mocks.ctrl.advanceCanary("podinfo", "default")

// check if ScaleToZero was performed
ds, err := mocks.kubeClient.AppsV1().DaemonSets("default").Get(context.TODO(), "podinfo", metav1.GetOptions{})
require.NoError(t, err)
assert.Contains(t, ds.Spec.Template.Spec.NodeSelector, "flagger.app/scale-to-zero")

// update
dae2 := newDaemonSetTestDaemonSetV2()
_, err := mocks.kubeClient.AppsV1().DaemonSets("default").Update(context.TODO(), dae2, metav1.UpdateOptions{})
_, err = mocks.kubeClient.AppsV1().DaemonSets("default").Update(context.TODO(), dae2, metav1.UpdateOptions{})
require.NoError(t, err)

// detect changes
Expand Down
7 changes: 6 additions & 1 deletion pkg/controller/scheduler_deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,14 @@ func TestScheduler_DeploymentNewRevision(t *testing.T) {
// initialization done
mocks.ctrl.advanceCanary("podinfo", "default")

// check if ScaleToZero was performed
dp, err := mocks.kubeClient.AppsV1().Deployments("default").Get(context.TODO(), "podinfo", metav1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, int32(0), *dp.Spec.Replicas)

// update
dep2 := newDeploymentTestDeploymentV2()
_, err := mocks.kubeClient.AppsV1().Deployments("default").Update(context.TODO(), dep2, metav1.UpdateOptions{})
_, err = mocks.kubeClient.AppsV1().Deployments("default").Update(context.TODO(), dep2, metav1.UpdateOptions{})
require.NoError(t, err)

// detect changes
Expand Down

0 comments on commit ba7fedf

Please sign in to comment.