k3s/docs/design/simple-rolling-update.md

166 lines
6.0 KiB
Markdown
Raw Normal View History

2015-07-12 04:04:52 +00:00
<!-- BEGIN MUNGE: UNVERSIONED_WARNING -->
<!-- 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
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
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
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
`kubectl rolling-update foo [foo-v2] --image=myimage:v2`
2015-04-10 23:11:12 +00:00
If the user doesn't specify a name for the 'next' replication controller, then
the 'next' replication controller is renamed to
the name of the original replication controller.
2015-04-10 23:11:12 +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
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
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:
```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
```
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.
`kubectl rolling-update foo [foo-v2] --rollback`
2015-04-10 23:11:12 +00:00
This is really just semantic sugar for:
`kubectl rolling-update foo-v2 foo`
2015-04-10 23:11:12 +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
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
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
* If `foo` and `foo-next` do not exist:
* Exit, and indicate an error to the user, that the specified controller
doesn't exist.
* If `foo` exists, but `foo-next` does not:
* 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
* 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
* If both `foo` and `foo-next` exist:
2015-04-10 23:11:12 +00:00
* Assume that we are in a partial rollout
* If `foo-next` is missing the `desired-replicas` annotation
* 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
* 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
* 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
* If `foo-next` doesn't exist
* Exit and indicate to the user that they may want to simply do a new
rollout with the old version
* If `foo` doesn't exist
2015-04-10 23:11:12 +00:00
* Exit and indicate not found to the user
* Otherwise, `foo-next` and `foo` both exist
* Set `desired-replicas` annotation on `foo` to match the annotation on
`foo-next`
* Goto Rollout with `foo` and `foo-next` trading places.
2015-07-14 00:13:09 +00:00
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
[![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 -->