recreate.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*
  2. Copyright 2016 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package deployment
  14. import (
  15. "k8s.io/kubernetes/pkg/apis/extensions"
  16. unversionedclient "k8s.io/kubernetes/pkg/client/unversioned"
  17. "k8s.io/kubernetes/pkg/controller"
  18. rsutil "k8s.io/kubernetes/pkg/util/replicaset"
  19. "k8s.io/kubernetes/pkg/util/wait"
  20. )
  21. // rolloutRecreate implements the logic for recreating a replica set.
  22. func (dc *DeploymentController) rolloutRecreate(deployment *extensions.Deployment) error {
  23. // Don't create a new RS if not already existed, so that we avoid scaling up before scaling down
  24. newRS, oldRSs, err := dc.getAllReplicaSetsAndSyncRevision(deployment, false)
  25. if err != nil {
  26. return err
  27. }
  28. allRSs := append(oldRSs, newRS)
  29. activeOldRSs := controller.FilterActiveReplicaSets(oldRSs)
  30. // scale down old replica sets
  31. scaledDown, err := dc.scaleDownOldReplicaSetsForRecreate(activeOldRSs, deployment)
  32. if err != nil {
  33. return err
  34. }
  35. if scaledDown {
  36. // Update DeploymentStatus
  37. return dc.updateDeploymentStatus(allRSs, newRS, deployment)
  38. }
  39. // Wait for all old replica set to scale down to zero.
  40. if err := dc.waitForInactiveReplicaSets(activeOldRSs); err != nil {
  41. return err
  42. }
  43. // If we need to create a new RS, create it now
  44. // TODO: Create a new RS without re-listing all RSs.
  45. if newRS == nil {
  46. newRS, oldRSs, err = dc.getAllReplicaSetsAndSyncRevision(deployment, true)
  47. if err != nil {
  48. return err
  49. }
  50. allRSs = append(oldRSs, newRS)
  51. }
  52. // scale up new replica set
  53. scaledUp, err := dc.scaleUpNewReplicaSetForRecreate(newRS, deployment)
  54. if err != nil {
  55. return err
  56. }
  57. if scaledUp {
  58. // Update DeploymentStatus
  59. return dc.updateDeploymentStatus(allRSs, newRS, deployment)
  60. }
  61. dc.cleanupDeployment(oldRSs, deployment)
  62. // Sync deployment status
  63. return dc.syncDeploymentStatus(allRSs, newRS, deployment)
  64. }
  65. // scaleDownOldReplicaSetsForRecreate scales down old replica sets when deployment strategy is "Recreate"
  66. func (dc *DeploymentController) scaleDownOldReplicaSetsForRecreate(oldRSs []*extensions.ReplicaSet, deployment *extensions.Deployment) (bool, error) {
  67. scaled := false
  68. for _, rs := range oldRSs {
  69. // Scaling not required.
  70. if rs.Spec.Replicas == 0 {
  71. continue
  72. }
  73. scaledRS, _, err := dc.scaleReplicaSetAndRecordEvent(rs, 0, deployment)
  74. if err != nil {
  75. return false, err
  76. }
  77. if scaledRS {
  78. scaled = true
  79. }
  80. }
  81. return scaled, nil
  82. }
  83. // waitForInactiveReplicaSets will wait until all passed replica sets are inactive and have been noticed
  84. // by the replica set controller.
  85. func (dc *DeploymentController) waitForInactiveReplicaSets(oldRSs []*extensions.ReplicaSet) error {
  86. for i := range oldRSs {
  87. rs := oldRSs[i]
  88. condition := rsutil.ReplicaSetIsInactive(dc.client.Extensions(), rs)
  89. if err := wait.ExponentialBackoff(unversionedclient.DefaultRetry, condition); err != nil {
  90. return err
  91. }
  92. }
  93. return nil
  94. }
  95. // scaleUpNewReplicaSetForRecreate scales up new replica set when deployment strategy is "Recreate"
  96. func (dc *DeploymentController) scaleUpNewReplicaSetForRecreate(newRS *extensions.ReplicaSet, deployment *extensions.Deployment) (bool, error) {
  97. scaled, _, err := dc.scaleReplicaSetAndRecordEvent(newRS, deployment.Spec.Replicas, deployment)
  98. return scaled, err
  99. }