summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oppenheimer <davidopp@gmail.com>2015-04-23 11:52:30 -0700
committerDavid Oppenheimer <davidopp@gmail.com>2015-04-23 11:52:30 -0700
commit870c24fc2cc0aa993e799eff909f5c4493f4a979 (patch)
tree4a071f15438a97555d789be7c7d036999e9680ee
parent747bb0de5dd4f1fdb64962aebeb89c283c79e81b (diff)
parent2a117380292929bf29f390e90f8cbe57d3b8fd74 (diff)
Merge pull request #6713 from brendandburns/docs
Suggest a simple rolling update.
-rw-r--r--simple-rolling-update.md92
1 files changed, 92 insertions, 0 deletions
diff --git a/simple-rolling-update.md b/simple-rolling-update.md
new file mode 100644
index 00000000..43b086ae
--- /dev/null
+++ b/simple-rolling-update.md
@@ -0,0 +1,92 @@
+## Simple rolling update
+This is a lightweight design document for simple rolling update in ```kubectl```
+
+Complete execution flow can be found [here](#execution-details).
+
+### Lightweight rollout
+Assume that we have a current replication controller named ```foo``` and it is running image ```image:v1```
+
+```kubectl rolling-update rc foo [foo-v2] --image=myimage:v2```
+
+If the user doesn't specify a name for the 'next' controller, then the 'next' controller is renamed to
+the name of the original controller.
+
+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
+
+If the user does specify a name for the 'next' controller, then the 'next' controller is retained with its existing name,
+and the old 'foo' 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``` controllers.
+The value of that label is the hash of the complete JSON representation of the```foo-next``` or```foo``` controller. The name of this label can be overridden by the user with the ```--deployment-label-key``` flag.
+
+#### Recovery
+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 replicaController in the ```kubernetes.io/``` annotation namespace:
+ * ```desired-replicas``` The desired number of replicas for this controller (either N or zero)
+ * ```update-partner``` A pointer to the replicaiton 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.)
+
+Recovery is achieved by issuing the same command again:
+
+```
+kubectl rolling-update rc foo [foo-v2] --image=myimage:v2
+```
+
+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.
+
+
+### Aborting a rollout
+Abort is assumed to want to reverse a rollout in progress.
+
+```kubectl rolling-update rc foo [foo-v2] --abort```
+
+This is really just semantic sugar for:
+
+```kubectl rolling-update rc foo-v2 foo```
+
+With the added detail that it moves the ```desired-replicas``` annotation from ```foo-v2``` to ```foo```
+
+
+### 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`
+
+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>```
+
+#### Initialization
+ * If ```foo``` and ```foo-next``` do not exist:
+ * Exit, and indicate an error to the user, that the specified controller doesn't exist.
+ * Goto Rollout
+ * If ```foo``` exists, but ```foo-next``` does not:
+ * Create ```foo-next``` populate it with the ```v2``` image, set ```desired-replicas``` to ```foo.Spec.Replicas```
+ * Goto Rollout
+ * If ```foo-next``` exists, but ```foo``` does not:
+ * Assume that we are in the rename phase.
+ * Goto Rename
+ * If both ```foo``` and ```foo-next``` exist:
+ * 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```
+ * Goto Rollout
+
+#### Rollout
+ * 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```
+ * Goto Rename
+
+#### Rename
+ * delete ```foo```
+ * create ```foo``` that is identical to ```foo-next```
+ * delete ```foo-next```
+
+#### Abort
+ * 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
+ * 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.