Merge pull request #19366 from ironcladlou/noop-zero-replicas
Support rolling update to 0 desired replicas
This commit is contained in:
		@@ -208,13 +208,20 @@ func (r *RollingUpdater) Update(config *RollingUpdaterConfig) error {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Further validation.
 | 
						// Validate maximums.
 | 
				
			||||||
	if maxUnavailable == 0 && maxSurge == 0 {
 | 
						if desired > 0 && maxUnavailable == 0 && maxSurge == 0 {
 | 
				
			||||||
		return fmt.Errorf("one of maxSurge or maxUnavailable must be specified")
 | 
							return fmt.Errorf("one of maxSurge or maxUnavailable must be specified")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// The minumum pods which must remain available througout the update
 | 
						// The minumum pods which must remain available througout the update
 | 
				
			||||||
	// calculated for internal convenience.
 | 
						// calculated for internal convenience.
 | 
				
			||||||
	minAvailable := original - maxUnavailable
 | 
						minAvailable := int(math.Max(float64(0), float64(desired-maxUnavailable)))
 | 
				
			||||||
 | 
						// If the desired new scale is 0, then the max unavailable is necessarily
 | 
				
			||||||
 | 
						// the effective scale of the old RC regardless of the configuration
 | 
				
			||||||
 | 
						// (equivalent to 100% maxUnavailable).
 | 
				
			||||||
 | 
						if desired == 0 {
 | 
				
			||||||
 | 
							maxUnavailable = original
 | 
				
			||||||
 | 
							minAvailable = 0
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fmt.Fprintf(out, "Scaling up %s from %d to %d, scaling down %s from %d to 0 (keep %d pods available, don't exceed %d pods)\n",
 | 
						fmt.Fprintf(out, "Scaling up %s from %d to %d, scaling down %s from %d to 0 (keep %d pods available, don't exceed %d pods)\n",
 | 
				
			||||||
		newRc.Name, newRc.Spec.Replicas, desired, oldRc.Name, oldRc.Spec.Replicas, minAvailable, original+maxSurge)
 | 
							newRc.Name, newRc.Spec.Replicas, desired, oldRc.Name, oldRc.Spec.Replicas, minAvailable, original+maxSurge)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -539,7 +539,7 @@ Scaling foo-v1 down to 0
 | 
				
			|||||||
				down{oldReady: 10, newReady: 20, to: 0},
 | 
									down{oldReady: 10, newReady: 20, to: 0},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			output: `Created foo-v2
 | 
								output: `Created foo-v2
 | 
				
			||||||
Scaling up foo-v2 from 0 to 20, scaling down foo-v1 from 10 to 0 (keep 10 pods available, don't exceed 70 pods)
 | 
					Scaling up foo-v2 from 0 to 20, scaling down foo-v1 from 10 to 0 (keep 20 pods available, don't exceed 70 pods)
 | 
				
			||||||
Scaling foo-v2 up to 20
 | 
					Scaling foo-v2 up to 20
 | 
				
			||||||
Scaling foo-v1 down to 0
 | 
					Scaling foo-v1 down to 0
 | 
				
			||||||
`,
 | 
					`,
 | 
				
			||||||
@@ -557,6 +557,83 @@ Scaling foo-v1 down to 0
 | 
				
			|||||||
			output: `Continuing update with existing controller foo-v2.
 | 
								output: `Continuing update with existing controller foo-v2.
 | 
				
			||||||
Scaling up foo-v2 from 1 to 1, scaling down foo-v1 from 1 to 0 (keep 1 pods available, don't exceed 2 pods)
 | 
					Scaling up foo-v2 from 1 to 1, scaling down foo-v1 from 1 to 0 (keep 1 pods available, don't exceed 2 pods)
 | 
				
			||||||
Scaling foo-v1 down to 0
 | 
					Scaling foo-v1 down to 0
 | 
				
			||||||
 | 
					`,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name:        "3->0 1/1 desired 0 (absolute values)",
 | 
				
			||||||
 | 
								oldRc:       oldRc(3, 3),
 | 
				
			||||||
 | 
								newRc:       newRc(0, 0),
 | 
				
			||||||
 | 
								newRcExists: true,
 | 
				
			||||||
 | 
								maxUnavail:  intstr.FromInt(1),
 | 
				
			||||||
 | 
								maxSurge:    intstr.FromInt(1),
 | 
				
			||||||
 | 
								expected: []interface{}{
 | 
				
			||||||
 | 
									down{oldReady: 3, newReady: 0, to: 0},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								output: `Continuing update with existing controller foo-v2.
 | 
				
			||||||
 | 
					Scaling up foo-v2 from 0 to 0, scaling down foo-v1 from 3 to 0 (keep 0 pods available, don't exceed 4 pods)
 | 
				
			||||||
 | 
					Scaling foo-v1 down to 0
 | 
				
			||||||
 | 
					`,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name:        "3->0 10/10 desired 0 (percentages)",
 | 
				
			||||||
 | 
								oldRc:       oldRc(3, 3),
 | 
				
			||||||
 | 
								newRc:       newRc(0, 0),
 | 
				
			||||||
 | 
								newRcExists: true,
 | 
				
			||||||
 | 
								maxUnavail:  intstr.FromString("10%"),
 | 
				
			||||||
 | 
								maxSurge:    intstr.FromString("10%"),
 | 
				
			||||||
 | 
								expected: []interface{}{
 | 
				
			||||||
 | 
									down{oldReady: 3, newReady: 0, to: 0},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								output: `Continuing update with existing controller foo-v2.
 | 
				
			||||||
 | 
					Scaling up foo-v2 from 0 to 0, scaling down foo-v1 from 3 to 0 (keep 0 pods available, don't exceed 3 pods)
 | 
				
			||||||
 | 
					Scaling foo-v1 down to 0
 | 
				
			||||||
 | 
					`,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name:        "3->0 10/10 desired 0 (create new RC)",
 | 
				
			||||||
 | 
								oldRc:       oldRc(3, 3),
 | 
				
			||||||
 | 
								newRc:       newRc(0, 0),
 | 
				
			||||||
 | 
								newRcExists: false,
 | 
				
			||||||
 | 
								maxUnavail:  intstr.FromString("10%"),
 | 
				
			||||||
 | 
								maxSurge:    intstr.FromString("10%"),
 | 
				
			||||||
 | 
								expected: []interface{}{
 | 
				
			||||||
 | 
									down{oldReady: 3, newReady: 0, to: 0},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								output: `Created foo-v2
 | 
				
			||||||
 | 
					Scaling up foo-v2 from 0 to 0, scaling down foo-v1 from 3 to 0 (keep 0 pods available, don't exceed 3 pods)
 | 
				
			||||||
 | 
					Scaling foo-v1 down to 0
 | 
				
			||||||
 | 
					`,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name:        "0->0 1/1 desired 0 (absolute values)",
 | 
				
			||||||
 | 
								oldRc:       oldRc(0, 0),
 | 
				
			||||||
 | 
								newRc:       newRc(0, 0),
 | 
				
			||||||
 | 
								newRcExists: true,
 | 
				
			||||||
 | 
								maxUnavail:  intstr.FromInt(1),
 | 
				
			||||||
 | 
								maxSurge:    intstr.FromInt(1),
 | 
				
			||||||
 | 
								expected: []interface{}{
 | 
				
			||||||
 | 
									down{oldReady: 0, newReady: 0, to: 0},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								output: `Continuing update with existing controller foo-v2.
 | 
				
			||||||
 | 
					Scaling up foo-v2 from 0 to 0, scaling down foo-v1 from 0 to 0 (keep 0 pods available, don't exceed 1 pods)
 | 
				
			||||||
 | 
					`,
 | 
				
			||||||
 | 
							}, {
 | 
				
			||||||
 | 
								name:        "30->2 50%/0",
 | 
				
			||||||
 | 
								oldRc:       oldRc(30, 30),
 | 
				
			||||||
 | 
								newRc:       newRc(0, 2),
 | 
				
			||||||
 | 
								newRcExists: false,
 | 
				
			||||||
 | 
								maxUnavail:  intstr.FromString("50%"),
 | 
				
			||||||
 | 
								maxSurge:    intstr.FromInt(0),
 | 
				
			||||||
 | 
								expected: []interface{}{
 | 
				
			||||||
 | 
									down{oldReady: 30, newReady: 0, to: 1},
 | 
				
			||||||
 | 
									up{2},
 | 
				
			||||||
 | 
									down{oldReady: 1, newReady: 2, to: 0},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								output: `Created foo-v2
 | 
				
			||||||
 | 
					Scaling up foo-v2 from 0 to 2, scaling down foo-v1 from 30 to 0 (keep 1 pods available, don't exceed 30 pods)
 | 
				
			||||||
 | 
					Scaling foo-v1 down to 1
 | 
				
			||||||
 | 
					Scaling foo-v2 up to 2
 | 
				
			||||||
 | 
					Scaling foo-v1 down to 0
 | 
				
			||||||
`,
 | 
					`,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user