Skip to content
This repository has been archived by the owner on Jul 30, 2021. It is now read-only.

Checkpoint and activate itself. #366

Merged
merged 3 commits into from
Mar 30, 2017

Conversation

yifan-gu
Copy link

This PR enables us to GC itself using the existing codepath.
Also it removes the needs for the checkpoint-installer, which
also enables us to update the checkpointer by just updating the
checkpointer's manifest.

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Mar 10, 2017
@yifan-gu yifan-gu changed the title Checkpoint and activate itself. WIP (don't review): Checkpoint and activate itself. Mar 10, 2017
@yifan-gu yifan-gu force-pushed the gc_checkpointer branch 5 times, most recently from e05ca93 to dc12082 Compare March 11, 2017 00:58
@yifan-gu yifan-gu changed the title WIP (don't review): Checkpoint and activate itself. Checkpoint and activate itself. Mar 11, 2017
@yifan-gu
Copy link
Author

Fix #253
Fix #206

Ready for a review.

I did several tests manually:

  • Boot up 2 nodes.
  • Schedule checkpointer on both.
  • Schedule a test pod (checkpoints enabled) on the worker node.
  • See 4 checkpointers, 2 running, 2 standby.
  • Suspend the master, reboot the worker node.
  • The standby checkpointer starts, which then starts checkpoints.
  • Resume the master, see 4 checkpointers, 2 running, 2 standby, and the static checkpointer now is the effective one on the worker node.
  • Checkpointer stops the test pod's checkpoints after the test pod is running.
  • Boot up 2 nodes.
  • Schedule checkpointer on both.
  • Schedule a test pod (checkpoints enabled) on the worker node.
  • See 4 checkpointers, 2 running, 2 standby.
  • Suspend the worker, delete the test pod, recreate the checkpointer daemonset so it only schedules on master node.
  • Suspend the master
  • Resume/reboot the worker
  • The standby checkpointer starts, which then starts checkpoints.
  • Resume the master
  • The standby checkpointer cleans the checkpoints and itself.

/cc @aaronlevy @stuart-warren

Copy link
Contributor

@aaronlevy aaronlevy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple minor comments, but this is looking awesome

@@ -295,6 +351,11 @@ func writeCheckpointManifest(pod *v1.Pod) error {
return writeAndAtomicRename(path, b, 0644)
}

// isPodCheckpointer returns true if the pod is the checkpointer itself.
func isPodCheckpointer(pod *v1.Pod) bool {
return strings.HasPrefix(pod.Name, "pod-checkpointer")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems a bit fragile. Is there another way we could determine this? We can know our "self" via the downward api + inject as env vars - maybe that's an option?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aaronlevy Which downward API? Getting the podname?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. We could probably check that maybe:

pod.Name == self.Namespace
pod.Name == self.Name + "-" + self.NodeName // Because we care about the static pod, right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm actually, it won't have the node-name suffix in the checkpoint manifest - so maybe just pod.Name == self.Name if we care about the parent pod

or, if we care about the checkpointed copy, something like:

pod.Name == strings.TrimSuffix(self.Name, self.NodeName) && pod.Name != self.Name

if err := os.Remove(p); err != nil && !os.IsNotExist(err) {
glog.Errorf("Failed to remove active checkpoint %s: %v", p, err)
continue
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a slightly worried about swapping the order of removal here. My thought being that we should stop the pods first, then remove the assets they rely on. It might not be an issue - because we weren't waiting for the pods to actually stop - but do you forsee issues in removing a secret / configMap for example from underneath a running pod?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested this, it actually successfully removed without an issue. But I want to just double check and understand why it's not an issue and report back.

Alternatively, we can keep the order. and just leave the configmap/scret for the checkpointer untouched. And next time we create the configmap/scret again, we always overwrite the existing one. This seems safer and doesn't cause any issue except for two small files. WDYT?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @aaronlevy ^

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So actually removing the config, secret will always succeed, it's not a unmounting operaton.
But maybe that's not graceful to pods as they might have some prestop hooks or whatever graceful termination process that will require the secrets/configs.
I will revert this ordering change.

Copy link
Author

@yifan-gu yifan-gu Mar 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had more discussion on this. As for now we are not waiting the pod to be deleted anyway, so maybe it's fine to leave as is, and improve this later.
Adding a TODO to capture that.

@@ -104,6 +104,22 @@ func TestProcess(t *testing.T) {
activeCheckpoints: map[string]*v1.Pod{"AA": {}},
localParents: map[string]*v1.Pod{"AA": {}},
},
{
desc: "Inactive pod-checkpointer, local parent, local running, api parent: should start",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be worth adding another test to make sure it still starts even with a local parent (the checkpointed copy always needs to run)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure

@yifan-gu yifan-gu force-pushed the gc_checkpointer branch 2 times, most recently from 22d4c2e to e077b08 Compare March 14, 2017 02:49
This enables us to GC itself using the existing codepath.
Also it removes the needs for the checkpoint-installer, which
also enables us to update the checkpointer by just updating the
checkpointer's manifest.
Remove pod-checkpoint-installer.
@yifan-gu
Copy link
Author

Comments addressed, PTAL @aaronlevy

@aaronlevy
Copy link
Contributor

This LGTM - but going to hold off on merging this to coordinate these changes at same time as k8s v1.6.0

@yifan-gu
Copy link
Author

Add one more commit for cleaning up all checkpoints when the pod checkpointer is removed.
Will squash if this passes the review @aaronlevy

Copy link
Contributor

@aaronlevy aaronlevy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@yifan-gu yifan-gu merged commit a936ee1 into kubernetes-retired:master Mar 30, 2017
@yifan-gu yifan-gu deleted the gc_checkpointer branch March 30, 2017 00:23
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
cncf-cla: yes Indicates the PR's author has signed the CNCF CLA.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants