2015-07-12 04:04:52 +00:00
|
|
|
<!-- BEGIN MUNGE: UNVERSIONED_WARNING -->
|
|
|
|
|
2016-06-10 23:46:46 +00:00
|
|
|
<!-- BEGIN STRIP_FOR_RELEASE -->
|
|
|
|
|
|
|
|
<img src="http://kubernetes.io/img/warning.png" alt="WARNING"
|
|
|
|
width="25" height="25">
|
|
|
|
<img src="http://kubernetes.io/img/warning.png" alt="WARNING"
|
|
|
|
width="25" height="25">
|
|
|
|
<img src="http://kubernetes.io/img/warning.png" alt="WARNING"
|
|
|
|
width="25" height="25">
|
|
|
|
<img src="http://kubernetes.io/img/warning.png" alt="WARNING"
|
|
|
|
width="25" height="25">
|
|
|
|
<img src="http://kubernetes.io/img/warning.png" alt="WARNING"
|
|
|
|
width="25" height="25">
|
|
|
|
|
|
|
|
<h2>PLEASE NOTE: This document applies to the HEAD of the source tree</h2>
|
|
|
|
|
|
|
|
If you are using a released version of Kubernetes, you should
|
|
|
|
refer to the docs that go with that version.
|
|
|
|
|
|
|
|
<!-- TAG RELEASE_LINK, added by the munger automatically -->
|
|
|
|
<strong>
|
|
|
|
The latest release of this document can be found
|
|
|
|
[here](http://releases.k8s.io/release-1.2/docs/design/simple-rolling-update.md).
|
|
|
|
|
|
|
|
Documentation for other releases can be found at
|
|
|
|
[releases.k8s.io](http://releases.k8s.io).
|
|
|
|
</strong>
|
|
|
|
--
|
|
|
|
|
|
|
|
<!-- END STRIP_FOR_RELEASE -->
|
2015-07-12 04:04:52 +00:00
|
|
|
|
|
|
|
<!-- END MUNGE: UNVERSIONED_WARNING -->
|
2015-07-17 22:35:41 +00:00
|
|
|
|
2015-04-10 23:11:12 +00:00
|
|
|
## Simple rolling update
|
2015-07-17 22:35:41 +00:00
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
This is a lightweight design document for simple
|
|
|
|
[rolling update](../user-guide/kubectl/kubectl_rolling-update.md) in `kubectl`.
|
2015-04-10 23:11:12 +00:00
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
Complete execution flow can be found [here](#execution-details). See the
|
|
|
|
[example of rolling update](../user-guide/update-demo/) for more information.
|
2015-04-10 23:11:12 +00:00
|
|
|
|
|
|
|
### Lightweight rollout
|
2015-07-17 22:35:41 +00:00
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
Assume that we have a current replication controller named `foo` and it is
|
|
|
|
running image `image:v1`
|
2015-04-10 23:11:12 +00:00
|
|
|
|
2015-07-19 05:58:13 +00:00
|
|
|
`kubectl rolling-update foo [foo-v2] --image=myimage:v2`
|
2015-04-10 23:11:12 +00:00
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
If the user doesn't specify a name for the 'next' replication controller, then
|
|
|
|
the 'next' replication controller is renamed to
|
2015-06-16 21:48:51 +00:00
|
|
|
the name of the original replication controller.
|
2015-04-10 23:11:12 +00:00
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
Obviously there is a race here, where if you kill the client between delete foo,
|
|
|
|
and creating the new version of 'foo' you might be surprised about what is
|
|
|
|
there, but I think that's ok. See [Recovery](#recovery) below
|
2015-04-10 23:11:12 +00:00
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
If the user does specify a name for the 'next' replication controller, then the
|
|
|
|
'next' replication controller is retained with its existing name, and the old
|
|
|
|
'foo' replication controller is deleted. For the purposes of the rollout, we add
|
|
|
|
a unique-ifying label `kubernetes.io/deployment` to both the `foo` and
|
|
|
|
`foo-next` replication controllers. The value of that label is the hash of the
|
|
|
|
complete JSON representation of the`foo-next` or`foo` replication controller.
|
|
|
|
The name of this label can be overridden by the user with the
|
|
|
|
`--deployment-label-key` flag.
|
2015-04-10 23:11:12 +00:00
|
|
|
|
|
|
|
#### Recovery
|
2015-07-17 22:35:41 +00:00
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
If a rollout fails or is terminated in the middle, it is important that the user
|
|
|
|
be able to resume the roll out. To facilitate recovery in the case of a crash of
|
|
|
|
the updating process itself, we add the following annotations to each
|
|
|
|
replication controller in the `kubernetes.io/` annotation namespace:
|
|
|
|
* `desired-replicas` The desired number of replicas for this replication
|
|
|
|
controller (either N or zero)
|
|
|
|
* `update-partner` A pointer to the replication controller resource that is
|
|
|
|
the other half of this update (syntax `<name>` the namespace is assumed to be
|
|
|
|
identical to the namespace of this replication controller.)
|
2015-04-10 23:11:12 +00:00
|
|
|
|
|
|
|
Recovery is achieved by issuing the same command again:
|
|
|
|
|
2015-07-19 08:46:02 +00:00
|
|
|
```sh
|
2015-07-13 13:09:26 +00:00
|
|
|
kubectl rolling-update foo [foo-v2] --image=myimage:v2
|
2015-04-10 23:11:12 +00:00
|
|
|
```
|
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
Whenever the rolling update command executes, the kubectl client looks for
|
|
|
|
replication controllers called `foo` and `foo-next`, if they exist, an attempt
|
|
|
|
is made to roll `foo` to `foo-next`. If `foo-next` does not exist, then it is
|
|
|
|
created, and the rollout is a new rollout. If `foo` doesn't exist, then it is
|
|
|
|
assumed that the rollout is nearly completed, and `foo-next` is renamed to
|
|
|
|
`foo`. Details of the execution flow are given below.
|
2015-04-10 23:11:12 +00:00
|
|
|
|
|
|
|
|
|
|
|
### Aborting a rollout
|
2015-07-17 22:35:41 +00:00
|
|
|
|
2015-04-10 23:11:12 +00:00
|
|
|
Abort is assumed to want to reverse a rollout in progress.
|
|
|
|
|
2015-07-19 05:58:13 +00:00
|
|
|
`kubectl rolling-update foo [foo-v2] --rollback`
|
2015-04-10 23:11:12 +00:00
|
|
|
|
|
|
|
This is really just semantic sugar for:
|
|
|
|
|
2015-07-19 05:58:13 +00:00
|
|
|
`kubectl rolling-update foo-v2 foo`
|
2015-04-10 23:11:12 +00:00
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
With the added detail that it moves the `desired-replicas` annotation from
|
|
|
|
`foo-v2` to `foo`
|
2015-04-10 23:11:12 +00:00
|
|
|
|
|
|
|
|
|
|
|
### Execution Details
|
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
For the purposes of this example, assume that we are rolling from `foo` to
|
|
|
|
`foo-next` where the only change is an image update from `v1` to `v2`
|
2015-04-10 23:11:12 +00:00
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
If the user doesn't specify a `foo-next` name, then it is either discovered from
|
|
|
|
the `update-partner` annotation on `foo`. If that annotation doesn't exist,
|
|
|
|
then `foo-next` is synthesized using the pattern
|
|
|
|
`<controller-name>-<hash-of-next-controller-JSON>`
|
2015-04-10 23:11:12 +00:00
|
|
|
|
|
|
|
#### Initialization
|
2015-07-17 22:35:41 +00:00
|
|
|
|
2015-07-19 05:58:13 +00:00
|
|
|
* If `foo` and `foo-next` do not exist:
|
2016-04-14 00:55:22 +00:00
|
|
|
* Exit, and indicate an error to the user, that the specified controller
|
|
|
|
doesn't exist.
|
2015-07-19 05:58:13 +00:00
|
|
|
* If `foo` exists, but `foo-next` does not:
|
2016-04-14 00:55:22 +00:00
|
|
|
* Create `foo-next` populate it with the `v2` image, set
|
|
|
|
`desired-replicas` to `foo.Spec.Replicas`
|
2015-04-10 23:11:12 +00:00
|
|
|
* Goto Rollout
|
2015-07-19 05:58:13 +00:00
|
|
|
* If `foo-next` exists, but `foo` does not:
|
2015-04-10 23:11:12 +00:00
|
|
|
* Assume that we are in the rename phase.
|
|
|
|
* Goto Rename
|
2015-07-19 05:58:13 +00:00
|
|
|
* If both `foo` and `foo-next` exist:
|
2015-04-10 23:11:12 +00:00
|
|
|
* Assume that we are in a partial rollout
|
2015-07-19 05:58:13 +00:00
|
|
|
* If `foo-next` is missing the `desired-replicas` annotation
|
2016-04-14 00:55:22 +00:00
|
|
|
* Populate the `desired-replicas` annotation to `foo-next` using the
|
|
|
|
current size of `foo`
|
2015-04-10 23:11:12 +00:00
|
|
|
* Goto Rollout
|
|
|
|
|
|
|
|
#### Rollout
|
2015-07-17 22:35:41 +00:00
|
|
|
|
2015-07-19 05:58:13 +00:00
|
|
|
* While size of `foo-next` < `desired-replicas` annotation on `foo-next`
|
|
|
|
* increase size of `foo-next`
|
|
|
|
* if size of `foo` > 0
|
|
|
|
decrease size of `foo`
|
2015-04-10 23:11:12 +00:00
|
|
|
* Goto Rename
|
|
|
|
|
|
|
|
#### Rename
|
2015-07-17 22:35:41 +00:00
|
|
|
|
2015-07-19 05:58:13 +00:00
|
|
|
* delete `foo`
|
|
|
|
* create `foo` that is identical to `foo-next`
|
|
|
|
* delete `foo-next`
|
2015-04-10 23:11:12 +00:00
|
|
|
|
|
|
|
#### Abort
|
2015-07-17 22:35:41 +00:00
|
|
|
|
2015-07-19 05:58:13 +00:00
|
|
|
* If `foo-next` doesn't exist
|
2016-04-14 00:55:22 +00:00
|
|
|
* Exit and indicate to the user that they may want to simply do a new
|
|
|
|
rollout with the old version
|
2015-07-19 05:58:13 +00:00
|
|
|
* If `foo` doesn't exist
|
2015-04-10 23:11:12 +00:00
|
|
|
* Exit and indicate not found to the user
|
2015-07-19 05:58:13 +00:00
|
|
|
* Otherwise, `foo-next` and `foo` both exist
|
2016-04-14 00:55:22 +00:00
|
|
|
* Set `desired-replicas` annotation on `foo` to match the annotation on
|
|
|
|
`foo-next`
|
2015-07-19 05:58:13 +00:00
|
|
|
* Goto Rollout with `foo` and `foo-next` trading places.
|
2015-05-14 22:12:45 +00:00
|
|
|
|
|
|
|
|
2015-07-14 00:13:09 +00:00
|
|
|
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
2015-05-14 22:12:45 +00:00
|
|
|
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/simple-rolling-update.md?pixel)]()
|
2015-07-14 00:13:09 +00:00
|
|
|
<!-- END MUNGE: GENERATED_ANALYTICS -->
|