4.9 KiB
Simple rolling update
This is a lightweight design document for simple
rolling update in kubectl.
Complete execution flow can be found here. See the example of rolling update for more information.
Lightweight rollout
Assume that we have a current replication controller named foo and it is
running image image:v1
kubectl rolling-update foo [foo-v2] --image=myimage:v2
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.
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 below
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 thefoo-next orfoo replication 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
replication controller in the kubernetes.io/ annotation namespace:
desired-replicasThe desired number of replicas for this replication controller (either N or zero)update-partnerA 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.)
Recovery is achieved by issuing the same command again:
kubectl rolling-update 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 foo [foo-v2] --rollback
This is really just semantic sugar for:
kubectl rolling-update 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
fooandfoo-nextdo not exist:- Exit, and indicate an error to the user, that the specified controller doesn't exist.
- If
fooexists, butfoo-nextdoes not:- Create
foo-nextpopulate it with thev2image, setdesired-replicastofoo.Spec.Replicas - Goto Rollout
- Create
- If
foo-nextexists, butfoodoes not:- Assume that we are in the rename phase.
- Goto Rename
- If both
fooandfoo-nextexist:- Assume that we are in a partial rollout
- If
foo-nextis missing thedesired-replicasannotation- Populate the
desired-replicasannotation tofoo-nextusing the current size offoo
- Populate the
- Goto Rollout
Rollout
- While size of
foo-next<desired-replicasannotation onfoo-next- increase size of
foo-next - if size of
foo> 0 decrease size offoo
- increase size of
- Goto Rename
Rename
- delete
foo - create
foothat is identical tofoo-next - delete
foo-next
Abort
- If
foo-nextdoesn't exist- Exit and indicate to the user that they may want to simply do a new rollout with the old version
- If
foodoesn't exist- Exit and indicate not found to the user
- Otherwise,
foo-nextandfooboth exist- Set
desired-replicasannotation onfooto match the annotation onfoo-next - Goto Rollout with
fooandfoo-nexttrading places.
- Set