Merge pull request #20389 from mqliang/deployment-MinReadySeconds

Move MinReadySeconds out of RollingUpdateDeployment
This commit is contained in:
Saad Ali 2016-02-03 22:44:14 -08:00
commit 0952dcd349
13 changed files with 1105 additions and 1107 deletions

View File

@ -399,7 +399,7 @@ at any time during the update is at most 130% of desired pods.
##### Min Ready Seconds ##### Min Ready Seconds
`.spec.strategy.rollingUpdate.minReadySeconds` is an optional field that specifies the `.spec.minReadySeconds` is an optional field that specifies the
minimum number of seconds for which a newly created pod should be ready minimum number of seconds for which a newly created pod should be ready
without any of its containers crashing, for it to be considered available. without any of its containers crashing, for it to be considered available.
This defaults to 0 (the pod will be considered available as soon as it is ready). This defaults to 0 (the pod will be considered available as soon as it is ready).

File diff suppressed because it is too large Load Diff

View File

@ -243,6 +243,11 @@ type DeploymentSpec struct {
// The deployment strategy to use to replace existing pods with new ones. // The deployment strategy to use to replace existing pods with new ones.
Strategy DeploymentStrategy `json:"strategy,omitempty"` Strategy DeploymentStrategy `json:"strategy,omitempty"`
// Minimum number of seconds for which a newly created pod should be ready
// without any of its container crashing, for it to be considered available.
// Defaults to 0 (pod will be considered available as soon as it is ready)
MinReadySeconds int `json:"minReadySeconds,omitempty"`
// The number of old ReplicationControllers to retain to allow rollback. // The number of old ReplicationControllers to retain to allow rollback.
// This is a pointer to distinguish between explicit zero and not specified. // This is a pointer to distinguish between explicit zero and not specified.
RevisionHistoryLimit *int `json:"revisionHistoryLimit,omitempty"` RevisionHistoryLimit *int `json:"revisionHistoryLimit,omitempty"`
@ -335,11 +340,6 @@ type RollingUpdateDeployment struct {
// new RC can be scaled up further, ensuring that total number of pods running // new RC can be scaled up further, ensuring that total number of pods running
// at any time during the update is atmost 130% of original pods. // at any time during the update is atmost 130% of original pods.
MaxSurge intstr.IntOrString `json:"maxSurge,omitempty"` MaxSurge intstr.IntOrString `json:"maxSurge,omitempty"`
// Minimum number of seconds for which a newly created pod should be ready
// without any of its container crashing, for it to be considered available.
// Defaults to 0 (pod will be considered available as soon as it is ready)
MinReadySeconds int `json:"minReadySeconds,omitempty"`
} }
type DeploymentStatus struct { type DeploymentStatus struct {

View File

@ -266,6 +266,7 @@ func Convert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(in *extensions.
} }
out.UniqueLabelKey = new(string) out.UniqueLabelKey = new(string)
*out.UniqueLabelKey = in.UniqueLabelKey *out.UniqueLabelKey = in.UniqueLabelKey
out.MinReadySeconds = int32(in.MinReadySeconds)
out.Paused = in.Paused out.Paused = in.Paused
if in.RollbackTo != nil { if in.RollbackTo != nil {
out.RollbackTo = new(RollbackConfig) out.RollbackTo = new(RollbackConfig)
@ -304,6 +305,7 @@ func Convert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(in *DeploymentS
if in.UniqueLabelKey != nil { if in.UniqueLabelKey != nil {
out.UniqueLabelKey = *in.UniqueLabelKey out.UniqueLabelKey = *in.UniqueLabelKey
} }
out.MinReadySeconds = int(in.MinReadySeconds)
out.Paused = in.Paused out.Paused = in.Paused
if in.RollbackTo != nil { if in.RollbackTo != nil {
out.RollbackTo = new(extensions.RollbackConfig) out.RollbackTo = new(extensions.RollbackConfig)
@ -362,7 +364,6 @@ func Convert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployme
if err := s.Convert(&in.MaxSurge, out.MaxSurge, 0); err != nil { if err := s.Convert(&in.MaxSurge, out.MaxSurge, 0); err != nil {
return err return err
} }
out.MinReadySeconds = int32(in.MinReadySeconds)
return nil return nil
} }
@ -376,7 +377,6 @@ func Convert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployme
if err := s.Convert(in.MaxSurge, &out.MaxSurge, 0); err != nil { if err := s.Convert(in.MaxSurge, &out.MaxSurge, 0); err != nil {
return err return err
} }
out.MinReadySeconds = int(in.MinReadySeconds)
return nil return nil
} }

View File

@ -2727,6 +2727,7 @@ func autoConvert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(in *extensi
if err := Convert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { if err := Convert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil {
return err return err
} }
out.MinReadySeconds = int32(in.MinReadySeconds)
if in.RevisionHistoryLimit != nil { if in.RevisionHistoryLimit != nil {
out.RevisionHistoryLimit = new(int32) out.RevisionHistoryLimit = new(int32)
*out.RevisionHistoryLimit = int32(*in.RevisionHistoryLimit) *out.RevisionHistoryLimit = int32(*in.RevisionHistoryLimit)
@ -3430,7 +3431,6 @@ func autoConvert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDepl
if err := s.Convert(&in.MaxSurge, &out.MaxSurge, 0); err != nil { if err := s.Convert(&in.MaxSurge, &out.MaxSurge, 0); err != nil {
return err return err
} }
out.MinReadySeconds = int32(in.MinReadySeconds)
return nil return nil
} }
@ -3902,6 +3902,7 @@ func autoConvert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(in *Deploym
if err := s.Convert(&in.Strategy, &out.Strategy, 0); err != nil { if err := s.Convert(&in.Strategy, &out.Strategy, 0); err != nil {
return err return err
} }
out.MinReadySeconds = int(in.MinReadySeconds)
if in.RevisionHistoryLimit != nil { if in.RevisionHistoryLimit != nil {
out.RevisionHistoryLimit = new(int) out.RevisionHistoryLimit = new(int)
*out.RevisionHistoryLimit = int(*in.RevisionHistoryLimit) *out.RevisionHistoryLimit = int(*in.RevisionHistoryLimit)
@ -4608,7 +4609,6 @@ func autoConvert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDepl
} }
// in.MaxUnavailable has no peer in out // in.MaxUnavailable has no peer in out
// in.MaxSurge has no peer in out // in.MaxSurge has no peer in out
out.MinReadySeconds = int(in.MinReadySeconds)
return nil return nil
} }

View File

@ -1167,6 +1167,7 @@ func deepCopy_v1beta1_DeploymentSpec(in DeploymentSpec, out *DeploymentSpec, c *
if err := deepCopy_v1beta1_DeploymentStrategy(in.Strategy, &out.Strategy, c); err != nil { if err := deepCopy_v1beta1_DeploymentStrategy(in.Strategy, &out.Strategy, c); err != nil {
return err return err
} }
out.MinReadySeconds = in.MinReadySeconds
if in.RevisionHistoryLimit != nil { if in.RevisionHistoryLimit != nil {
out.RevisionHistoryLimit = new(int32) out.RevisionHistoryLimit = new(int32)
*out.RevisionHistoryLimit = *in.RevisionHistoryLimit *out.RevisionHistoryLimit = *in.RevisionHistoryLimit
@ -1696,7 +1697,6 @@ func deepCopy_v1beta1_RollingUpdateDeployment(in RollingUpdateDeployment, out *R
} else { } else {
out.MaxSurge = nil out.MaxSurge = nil
} }
out.MinReadySeconds = in.MinReadySeconds
return nil return nil
} }

File diff suppressed because it is too large Load Diff

View File

@ -228,6 +228,11 @@ type DeploymentSpec struct {
// The deployment strategy to use to replace existing pods with new ones. // The deployment strategy to use to replace existing pods with new ones.
Strategy DeploymentStrategy `json:"strategy,omitempty"` Strategy DeploymentStrategy `json:"strategy,omitempty"`
// Minimum number of seconds for which a newly created pod should be ready
// without any of its container crashing, for it to be considered available.
// Defaults to 0 (pod will be considered available as soon as it is ready)
MinReadySeconds int32 `json:"minReadySeconds,omitempty"`
// The number of old ReplicationControllers to retain to allow rollback. // The number of old ReplicationControllers to retain to allow rollback.
// This is a pointer to distinguish between explicit zero and not specified. // This is a pointer to distinguish between explicit zero and not specified.
RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"` RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"`
@ -322,11 +327,6 @@ type RollingUpdateDeployment struct {
// new RC can be scaled up further, ensuring that total number of pods running // new RC can be scaled up further, ensuring that total number of pods running
// at any time during the update is atmost 130% of desired pods. // at any time during the update is atmost 130% of desired pods.
MaxSurge *intstr.IntOrString `json:"maxSurge,omitempty"` MaxSurge *intstr.IntOrString `json:"maxSurge,omitempty"`
// Minimum number of seconds for which a newly created pod should be ready
// without any of its container crashing, for it to be considered available.
// Defaults to 0 (pod will be considered available as soon as it is ready)
MinReadySeconds int32 `json:"minReadySeconds,omitempty"`
} }
// DeploymentStatus is the most recently observed status of the Deployment. // DeploymentStatus is the most recently observed status of the Deployment.

View File

@ -184,6 +184,7 @@ var map_DeploymentSpec = map[string]string{
"selector": "Label selector for pods. Existing ReplicationControllers whose pods are selected by this will be the ones affected by this deployment.", "selector": "Label selector for pods. Existing ReplicationControllers whose pods are selected by this will be the ones affected by this deployment.",
"template": "Template describes the pods that will be created.", "template": "Template describes the pods that will be created.",
"strategy": "The deployment strategy to use to replace existing pods with new ones.", "strategy": "The deployment strategy to use to replace existing pods with new ones.",
"minReadySeconds": "Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)",
"revisionHistoryLimit": "The number of old ReplicationControllers to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified.", "revisionHistoryLimit": "The number of old ReplicationControllers to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified.",
"uniqueLabelKey": "Key of the selector that is added to existing RCs (and label key that is added to its pods) to prevent the existing RCs to select new pods (and old pods being selected by new RC). Users can set this to an empty string to indicate that the system should not add any selector and label. If unspecified, system uses DefaultDeploymentUniqueLabelKey(\"deployment.kubernetes.io/podTemplateHash\"). Value of this key is hash of DeploymentSpec.PodTemplateSpec. No label is added if this is set to empty string.", "uniqueLabelKey": "Key of the selector that is added to existing RCs (and label key that is added to its pods) to prevent the existing RCs to select new pods (and old pods being selected by new RC). Users can set this to an empty string to indicate that the system should not add any selector and label. If unspecified, system uses DefaultDeploymentUniqueLabelKey(\"deployment.kubernetes.io/podTemplateHash\"). Value of this key is hash of DeploymentSpec.PodTemplateSpec. No label is added if this is set to empty string.",
"paused": "Indicates that the deployment is paused and will not be processed by the deployment controller.", "paused": "Indicates that the deployment is paused and will not be processed by the deployment controller.",
@ -532,10 +533,9 @@ func (RollingUpdateDaemonSet) SwaggerDoc() map[string]string {
} }
var map_RollingUpdateDeployment = map[string]string{ var map_RollingUpdateDeployment = map[string]string{
"": "Spec to control the desired behavior of rolling update.", "": "Spec to control the desired behavior of rolling update.",
"maxUnavailable": "The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding up. This can not be 0 if MaxSurge is 0. By default, a fixed value of 1 is used. Example: when this is set to 30%, the old RC can be scaled down to 70% of desired pods immediately when the rolling update starts. Once new pods are ready, old RC can be scaled down further, followed by scaling up the new RC, ensuring that the total number of pods available at all times during the update is at least 70% of desired pods.", "maxUnavailable": "The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding up. This can not be 0 if MaxSurge is 0. By default, a fixed value of 1 is used. Example: when this is set to 30%, the old RC can be scaled down to 70% of desired pods immediately when the rolling update starts. Once new pods are ready, old RC can be scaled down further, followed by scaling up the new RC, ensuring that the total number of pods available at all times during the update is at least 70% of desired pods.",
"maxSurge": "The maximum number of pods that can be scheduled above the desired number of pods. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. By default, a value of 1 is used. Example: when this is set to 30%, the new RC can be scaled up immediately when the rolling update starts, such that the total number of old and new pods do not exceed 130% of desired pods. Once old pods have been killed, new RC can be scaled up further, ensuring that total number of pods running at any time during the update is atmost 130% of desired pods.", "maxSurge": "The maximum number of pods that can be scheduled above the desired number of pods. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. By default, a value of 1 is used. Example: when this is set to 30%, the new RC can be scaled up immediately when the rolling update starts, such that the total number of old and new pods do not exceed 130% of desired pods. Once old pods have been killed, new RC can be scaled up further, ensuring that total number of pods running at any time during the update is atmost 130% of desired pods.",
"minReadySeconds": "Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)",
} }
func (RollingUpdateDeployment) SwaggerDoc() map[string]string { func (RollingUpdateDeployment) SwaggerDoc() map[string]string {

View File

@ -290,7 +290,6 @@ func ValidateRollingUpdateDeployment(rollingUpdate *extensions.RollingUpdateDepl
} }
// Validate that MaxUnavailable is not more than 100%. // Validate that MaxUnavailable is not more than 100%.
allErrs = append(allErrs, IsNotMoreThan100Percent(rollingUpdate.MaxUnavailable, fldPath.Child("maxUnavailable"))...) allErrs = append(allErrs, IsNotMoreThan100Percent(rollingUpdate.MaxUnavailable, fldPath.Child("maxUnavailable"))...)
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(rollingUpdate.MinReadySeconds), fldPath.Child("minReadySeconds"))...)
return allErrs return allErrs
} }
@ -322,6 +321,7 @@ func ValidateDeploymentSpec(spec *extensions.DeploymentSpec, fldPath *field.Path
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(spec.Replicas), fldPath.Child("replicas"))...) allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(spec.Replicas), fldPath.Child("replicas"))...)
allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpecForRC(&spec.Template, spec.Selector, spec.Replicas, fldPath.Child("template"))...) allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpecForRC(&spec.Template, spec.Selector, spec.Replicas, fldPath.Child("template"))...)
allErrs = append(allErrs, ValidateDeploymentStrategy(&spec.Strategy, fldPath.Child("strategy"))...) allErrs = append(allErrs, ValidateDeploymentStrategy(&spec.Strategy, fldPath.Child("strategy"))...)
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(spec.MinReadySeconds), fldPath.Child("minReadySeconds"))...)
if spec.RevisionHistoryLimit != nil { if spec.RevisionHistoryLimit != nil {
// zero is a valid RevisionHistoryLimit // zero is a valid RevisionHistoryLimit
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(*spec.RevisionHistoryLimit), fldPath.Child("revisionHistoryLimit"))...) allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(*spec.RevisionHistoryLimit), fldPath.Child("revisionHistoryLimit"))...)

View File

@ -818,7 +818,7 @@ func (dc *DeploymentController) reconcileOldRCs(allRCs []*api.ReplicationControl
} }
// Check if we can scale down. // Check if we can scale down.
minAvailable := deployment.Spec.Replicas - maxUnavailable minAvailable := deployment.Spec.Replicas - maxUnavailable
minReadySeconds := deployment.Spec.Strategy.RollingUpdate.MinReadySeconds minReadySeconds := deployment.Spec.MinReadySeconds
// Check the expectations of deployment before counting available pods // Check the expectations of deployment before counting available pods
dKey, err := controller.KeyFunc(&deployment) dKey, err := controller.KeyFunc(&deployment)
if err != nil { if err != nil {
@ -942,10 +942,7 @@ func (dc *DeploymentController) updateDeploymentStatus(allRCs []*api.Replication
func (dc *DeploymentController) calculateStatus(allRCs []*api.ReplicationController, newRC *api.ReplicationController, deployment extensions.Deployment) (totalReplicas, updatedReplicas, availableReplicas, unavailableReplicas int, err error) { func (dc *DeploymentController) calculateStatus(allRCs []*api.ReplicationController, newRC *api.ReplicationController, deployment extensions.Deployment) (totalReplicas, updatedReplicas, availableReplicas, unavailableReplicas int, err error) {
totalReplicas = deploymentutil.GetReplicaCountForRCs(allRCs) totalReplicas = deploymentutil.GetReplicaCountForRCs(allRCs)
updatedReplicas = deploymentutil.GetReplicaCountForRCs([]*api.ReplicationController{newRC}) updatedReplicas = deploymentutil.GetReplicaCountForRCs([]*api.ReplicationController{newRC})
minReadySeconds := 0 minReadySeconds := deployment.Spec.MinReadySeconds
if deployment.Spec.Strategy.Type == extensions.RollingUpdateDeploymentStrategyType {
minReadySeconds = deployment.Spec.Strategy.RollingUpdate.MinReadySeconds
}
availableReplicas, err = deploymentutil.GetAvailablePodsForRCs(dc.client, allRCs, minReadySeconds) availableReplicas, err = deploymentutil.GetAvailablePodsForRCs(dc.client, allRCs, minReadySeconds)
if err != nil { if err != nil {
err = fmt.Errorf("failed to count available pods: %v", err) err = fmt.Errorf("failed to count available pods: %v", err)

View File

@ -1604,9 +1604,10 @@ func (dd *DeploymentDescriber) Describe(namespace, name string) (string, error)
fmt.Fprintf(out, "Selector:\t%s\n", labels.FormatLabels(d.Spec.Selector)) fmt.Fprintf(out, "Selector:\t%s\n", labels.FormatLabels(d.Spec.Selector))
fmt.Fprintf(out, "Replicas:\t%d updated | %d total | %d available | %d unavailable\n", d.Status.UpdatedReplicas, d.Spec.Replicas, d.Status.AvailableReplicas, d.Status.UnavailableReplicas) fmt.Fprintf(out, "Replicas:\t%d updated | %d total | %d available | %d unavailable\n", d.Status.UpdatedReplicas, d.Spec.Replicas, d.Status.AvailableReplicas, d.Status.UnavailableReplicas)
fmt.Fprintf(out, "StrategyType:\t%s\n", d.Spec.Strategy.Type) fmt.Fprintf(out, "StrategyType:\t%s\n", d.Spec.Strategy.Type)
fmt.Fprintf(out, "MinReadySeconds:\t%s\n", d.Spec.MinReadySeconds)
if d.Spec.Strategy.RollingUpdate != nil { if d.Spec.Strategy.RollingUpdate != nil {
ru := d.Spec.Strategy.RollingUpdate ru := d.Spec.Strategy.RollingUpdate
fmt.Fprintf(out, "RollingUpdateStrategy:\t%s max unavailable, %s max surge, %d min ready seconds\n", ru.MaxUnavailable.String(), ru.MaxSurge.String(), ru.MinReadySeconds) fmt.Fprintf(out, "RollingUpdateStrategy:\t%s max unavailable, %s max surge\n", ru.MaxUnavailable.String(), ru.MaxSurge.String())
} }
oldRCs, _, err := deploymentutil.GetOldRCs(*d, dd) oldRCs, _, err := deploymentutil.GetOldRCs(*d, dd)
if err == nil { if err == nil {

View File

@ -474,10 +474,10 @@ func testRolloverDeployment(f *Framework) {
deploymentStrategyType := extensions.RollingUpdateDeploymentStrategyType deploymentStrategyType := extensions.RollingUpdateDeploymentStrategyType
Logf("Creating deployment %s", deploymentName) Logf("Creating deployment %s", deploymentName)
newDeployment := newDeployment(deploymentName, deploymentReplicas, deploymentPodLabels, deploymentImageName, deploymentImage, deploymentStrategyType, nil) newDeployment := newDeployment(deploymentName, deploymentReplicas, deploymentPodLabels, deploymentImageName, deploymentImage, deploymentStrategyType, nil)
newDeployment.Spec.MinReadySeconds = deploymentMinReadySeconds
newDeployment.Spec.Strategy.RollingUpdate = &extensions.RollingUpdateDeployment{ newDeployment.Spec.Strategy.RollingUpdate = &extensions.RollingUpdateDeployment{
MaxUnavailable: intstr.FromInt(1), MaxUnavailable: intstr.FromInt(1),
MaxSurge: intstr.FromInt(1), MaxSurge: intstr.FromInt(1),
MinReadySeconds: deploymentMinReadySeconds,
} }
_, err = c.Extensions().Deployments(ns).Create(newDeployment) _, err = c.Extensions().Deployments(ns).Create(newDeployment)
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())