Merge pull request #44672 from kargakis/update-deployment-completeness

Automatic merge from submit-queue (batch tested with PRs 43575, 44672)

Update deployment and daemonset completeness checks

maxUnavailable being taken into account for deployment completeness has caused a lot of confusion (https://github.com/kubernetes/kubernetes/issues/44395, https://github.com/kubernetes/kubernetes/issues/44657, https://github.com/kubernetes/kubernetes/issues/40496, others as well I am sure) so I am willing to just stop using it and require all of the new Pods for a Deployment to be available for the Deployment to be considered complete (hence both `rollout status` and ProgressDeadlineSeconds will not be successful in cases where a 1-pod Deployment never becomes successful because its Pod never transitions to ready).

@kubernetes/sig-apps-api-reviews thoughts?
```release-note
Deployments and DaemonSets are now considered complete once all of the new pods are up and running - affects `kubectl rollout status` (and ProgressDeadlineSeconds for Deployments)
```
Fixes https://github.com/kubernetes/kubernetes/issues/44395
This commit is contained in:
Kubernetes Submit Queue
2017-04-24 10:34:00 -07:00
committed by GitHub
4 changed files with 37 additions and 100 deletions

View File

@@ -418,17 +418,6 @@ func MaxUnavailable(deployment extensions.Deployment) int32 {
return maxUnavailable
}
// MaxUnavailableInternal returns the maximum unavailable pods a rolling deployment can take.
// TODO: remove the duplicate
func MaxUnavailableInternal(deployment internalextensions.Deployment) int32 {
if !(deployment.Spec.Strategy.Type == internalextensions.RollingUpdateDeploymentStrategyType) || deployment.Spec.Replicas == 0 {
return int32(0)
}
// Error caught by validation
_, maxUnavailable, _ := ResolveFenceposts(&deployment.Spec.Strategy.RollingUpdate.MaxSurge, &deployment.Spec.Strategy.RollingUpdate.MaxUnavailable, deployment.Spec.Replicas)
return maxUnavailable
}
// MinAvailable returns the minimum available pods of a given deployment
func MinAvailable(deployment *extensions.Deployment) int32 {
if !IsRollingUpdate(deployment) {
@@ -839,12 +828,12 @@ func IsRollingUpdate(deployment *extensions.Deployment) bool {
return deployment.Spec.Strategy.Type == extensions.RollingUpdateDeploymentStrategyType
}
// DeploymentComplete considers a deployment to be complete once its desired replicas equals its
// updatedReplicas, no old pods are running, and it doesn't violate minimum availability.
// DeploymentComplete considers a deployment to be complete once all of its desired replicas
// are updated and available, and no old pods are running.
func DeploymentComplete(deployment *extensions.Deployment, newStatus *extensions.DeploymentStatus) bool {
return newStatus.UpdatedReplicas == *(deployment.Spec.Replicas) &&
newStatus.Replicas == *(deployment.Spec.Replicas) &&
newStatus.AvailableReplicas >= *(deployment.Spec.Replicas)-MaxUnavailable(*deployment) &&
newStatus.AvailableReplicas == *(deployment.Spec.Replicas) &&
newStatus.ObservedGeneration >= deployment.Generation
}

View File

@@ -960,37 +960,43 @@ func TestDeploymentComplete(t *testing.T) {
expected bool
}{
{
name: "complete",
name: "not complete: min but not all pods become available",
d: deployment(5, 5, 5, 4, 1, 0),
expected: true,
expected: false,
},
{
name: "not complete",
name: "not complete: min availability is not honored",
d: deployment(5, 5, 5, 3, 1, 0),
expected: false,
},
{
name: "complete #2",
name: "complete",
d: deployment(5, 5, 5, 5, 0, 0),
expected: true,
},
{
name: "not complete #2",
name: "not complete: all pods are available but not updated",
d: deployment(5, 5, 4, 5, 0, 0),
expected: false,
},
{
name: "not complete #3",
name: "not complete: still running old pods",
// old replica set: spec.replicas=1, status.replicas=1, status.availableReplicas=1
// new replica set: spec.replicas=1, status.replicas=1, status.availableReplicas=0
d: deployment(1, 2, 1, 1, 0, 1),
expected: false,
},
{
name: "not complete: one replica deployment never comes up",
d: deployment(1, 1, 1, 0, 1, 1),
expected: false,
},
}
for _, test := range tests {