Skip to content

Latest commit

 

History

History
94 lines (68 loc) · 4.89 KB

simple-rolling-update.md

File metadata and controls

94 lines (68 loc) · 4.89 KB

Simple rolling update

This is a lightweight design document for simple rolling update in kubectl

Complete execution flow can be found here.

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 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 thefoo-next orfoo 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 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 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] --rollback

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.
  • 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.

Analytics