Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prep for multiple kinds of volume plugins #5642

Merged
merged 1 commit into from
Mar 20, 2015

Conversation

thockin
Copy link
Member

@thockin thockin commented Mar 19, 2015

With @markturansky adding persistent volumes, it becomes clear that volume plugins are needed in more than one kubernetes process. Specifically (at least, perhaps not complete):

  1. PersistentVolumeManager needs to get the access modes for each type of persistent volume.
  2. PersistentVolumeController needs to be able to Create/Destroy/Recycle volumes of each type.
  3. Kubelet needs to be able to Mount() and Unmount() each type of volume.

Each of these needs different functionality from the plugin. I'm trying to balance the desire to have plugins be mostly opaque to the surrounding system with the desire to not have to sprinkle support for a given volume type all over the place.

Options that I saw:

  1. Extend the existing volume.Interface to host a bunch of new methods. Downside is that all plugins (even those that will never support persistent volumes such as secrets) have to implement those functions (even just to panic). Would need to move pkg/kubelet/volume up to pkg/volume. Upside is simple.

  2. Make 2 or 3 different plugin interfaces in 2 or 3 different pkg/something dirs. Downside is that adding a new volume type means creating 1, 2, or 3 new pkg dirs in various places in the codebase with related but not overlapping functionality. E.g. there would be 2 or 3 'nfs' packages implementing 2 or 3 different plugin interfaces. Upside is that the are cleanly factored.

  3. Make 2 or 3 different plugin interfaces but put them all into a single pkg per volume type. Each caller would use a different entrypoint to the plugin pkg (ProbeNodeVolumePlugins, ProbePersistentVolumePlugins, etc). Downside is that naming gets clumsy. Upside is that all (e.g.) NFS code is in a single place, though each caller still needs to enumerate which plugins it supports.

I figured option 1 was right out. I preferred option 3 to option 2, so I implemented the basis for it. I don't HATE it, but I don't love it. I could be talked into option 2. I think we could limit option 2 to two places and 2 interfaces. Not so bad.

@markturansky @smarterclayton @bgrant0607 @vishh for smart opinions. This may set precedent for plugins that span the whole system, so I want to tread carefully.

This PR was mostly gorename.

@markturansky
Copy link
Contributor

Some additional context:

  1. The first option implemented -- very easy, but all volumes get a method not relevant to them: Add GetAccessModes to volume plugin interface #5398.
  2. PersistentVolumeManager exists today and is part of the PV framework: WIP: Persistent Storage Volumes #5344.
  3. PersistentVolumeController (name TBD) is a placeholder idea for dynamic provisioning. I presume all persistent volumes would implement the interface for dynamic provisioning for its volume type.

I prefer option 3 if only for packaging purposes. It will be nice to have just 1 place to define a volume and all its interfaces implemented. This maintains the idea of having an entirely self-contained volume that can be dropped in as a directory with no intimate knowledge of the plugin leaking outside that directory.

More to come after I address the API feedback left for me yesterday and digest this PR more fully.

@smarterclayton
Copy link
Contributor

3 doesn't sound terrible. All nfs code in one place benefits the extender because "copy-and-paste-extension" becomes much more obvious.

On Mar 19, 2015, at 2:38 AM, Tim Hockin notifications@github.com wrote:

With @markturansky adding persistent volumes, it becomes clear that volume plugins are needed in more than one kubernetes process. Specifically (at least, perhaps not complete):

  1. PersistentVolumeManager needs to get the access modes for each type of persistent volume.
  2. PersistentVolumeController needs to be able to Create/Destroy/Recycle volumes of each type.
  3. Kubelet needs to be able to Mount() and Unmount() each type of volume.

Each of these needs different functionality from the plugin. I'm trying to balance the desire to have plugins be mostly opaque to the surrounding system with the desire to not have to sprinkle support for a given volume type all over the place.

Options that I saw:

  1. Extend the existing volume.Interface to host a bunch of new methods. Downside is that all plugins (even those that will never support persistent volumes such as secrets) have to implement those functions (even just to panic). Would need to move pkg/kubelet/volume up to pkg/volume. Upside is simple.

  2. Make 2 or 3 different plugin interfaces in 2 or 3 different pkg/something dirs. Downside is that adding a new volume type means creating 1, 2, or 3 new pkg dirs in various places in the codebase with related but not overlapping functionality. E.g. there would be 2 or 3 'nfs' packages implementing 2 or 3 different plugin interfaces. Upside is that the are cleanly factored.

  3. Make 2 or 3 different plugin interfaces but put them all into a single pkg per volume type. Each caller would use a different entrypoint to the plugin pkg (ProbeNodeVolumePlugins, ProbePersistentVolumePlugins, etc). Downside is that naming gets clumsy. Upside is that all (e.g.) NFS code is in a single place, though each caller still needs to enumerate which plugins it supports.

I figured option 1 was right out. I preferred option 3 to option 2, so I implemented the basis for it. I don't HATE it, but I don't love it. I could be talked into option 2. I think we could limit option 2 to two places and 2 interfaces. Not so bad.

@markturansky @smarterclayton @bgrant0607 @vishh for smart opinions. This may set precedent for plugins that span the whole system, so I want to tread carefully.

This PR was mostly gorename.

You can view, comment on, or merge this pull request online at:

#5642

Commit Summary

Move pkg/kubelet/volume to pkg/volume
Rename all volume symbols to say 'Node'
File Changes

M cmd/integration/integration.go (6)
M cmd/kubelet/app/plugins.go (28)
M cmd/kubelet/app/server.go (9)
M cmd/kubernetes/kubernetes.go (2)
M pkg/kubelet/kubelet.go (9)
M pkg/kubelet/kubelet_test.go (12)
M pkg/kubelet/volumes.go (2)
R pkg/volume/doc.go (0)
R pkg/volume/empty_dir/empty_dir.go (18)
R pkg/volume/empty_dir/empty_dir_linux.go (0)
R pkg/volume/empty_dir/empty_dir_test.go (8)
R pkg/volume/empty_dir/empty_dir_unsupported.go (0)
R pkg/volume/gce_pd/gce_pd.go (14)
R pkg/volume/gce_pd/gce_pd_test.go (14)
R pkg/volume/gce_pd/gce_util.go (0)
R pkg/volume/gce_pd/gce_util_test.go (0)
R pkg/volume/git_repo/git_repo.go (12)
R pkg/volume/git_repo/git_repo_test.go (22)
R pkg/volume/host_path/host_path.go (12)
R pkg/volume/host_path/host_path_test.go (10)
R pkg/volume/plugins.go (27)
R pkg/volume/secret/secret.go (12)
R pkg/volume/secret/secret_test.go (16)
R pkg/volume/testing.go (62)
R pkg/volume/volume.go (8)
Patch Links:

https://github.com/GoogleCloudPlatform/kubernetes/pull/5642.patch
https://github.com/GoogleCloudPlatform/kubernetes/pull/5642.diff

Reply to this email directly or view it on GitHub.

@ghost
Copy link

ghost commented Mar 19, 2015

Is each new volume type really going to need a new implementation of all three interfaces? e.g. I would imagine that several different volume types would be mountable by a single common kubelet plugin based around *nix 'mount', perhaps? Similarly an iscsi-initiator based plugin might be able to mount volumes from multiple different storage vendors (NetApp, EMC etc), whereas the vendor interfaces for creation, deletion etc of volumes are mostly different (NetApp OnTAP, EMC Atmos etc).

Let me go and read and digest Mark's PV and plugin stuff, after which I hope to be able to provide more intelligent input :-)

@markturansky
Copy link
Contributor

@quinton-hoole I think you're right in that many volumes will mount similarly. We have a few people working on other storage plugins (iscsci and gluster, currently, and i've heard ceph bandied about). We've already agreed that we will likely find commonality among them and will take on the refactoring task of making them work well and adhere to whatever patterns we discover.

@thockin
Copy link
Member Author

thockin commented Mar 19, 2015 via email

@markturansky
Copy link
Contributor

The move and rename LGTM. Also, "gore name" is the worst (or best) name for a Go extension.

@thockin
Copy link
Member Author

thockin commented Mar 19, 2015

As a slight counter to my own proposal, which do you find least fugly?

volume.{NodePlugin, NodeHost, NodeVolume, NodePluginMgr},
volume.{PersistentPlugin, PersistentHost, PersistentVolume,
PersistentPluginMgr}

or

volume.{Plugin, Host, Volume, PluginMgr}, volume.{PersistentPlugin,
PersistentHost, PersistentVolume, PersistentPluginMgr}

The latter leaves all of the node types "undecorated", since every volume
plugin has to implement those, but only some will implement Persistent*

I want to make this decision soon, polish off the PR, commit, and let you
proceed.

On Thu, Mar 19, 2015 at 12:15 PM, Mark Turansky notifications@github.com
wrote:

The move and rename LGTM. Also, "gore name" is the worst (or best) name
for a Go extension.


Reply to this email directly or view it on GitHub
#5642 (comment)
.

@thockin thockin force-pushed the volume_multi_plugins branch from 4ddbc65 to 45bd7fc Compare March 19, 2015 19:57
@vishh
Copy link
Contributor

vishh commented Mar 19, 2015

+1 for the 3rd option. Although a bit tedious with naming, it makes it easy to manage all the plugins.

As for NodePlugin vs Plugin I prefer the latter.

@@ -261,8 +261,7 @@ func SimpleRunKubelet(client *client.Client,
hostname, rootDir, manifestURL, address string,
port uint,
masterServiceNamespace string,
volumePlugins []volume.Plugin,
tlsOptions *kubelet.TLSOptions,
volumePlugins []volume.NodePlugin, tlsOptions *kubelet.TLSOptions,
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Move tlsOptions *kubelet.TLSOptions, to the next line

Copy link
Member Author

Choose a reason for hiding this comment

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

not sure how that happened..

@satnam6502
Copy link
Contributor

/sub

@thockin thockin force-pushed the volume_multi_plugins branch from 45bd7fc to 7060a53 Compare March 19, 2015 20:34
@markturansky
Copy link
Contributor

As to your two choices above, I think I prefer the latter ("volume.{Plugin, Host, Volume, PluginMgr}, volume.{PersistentPlugin, PersistentHost, PersistentVolume, PersistentPluginMgr}") but I'll know with certainty when I start using it!

@thockin
Copy link
Member Author

thockin commented Mar 19, 2015

updated PR is coming soon

@thockin thockin force-pushed the volume_multi_plugins branch from 7060a53 to ae6ff51 Compare March 19, 2015 22:03
@thockin
Copy link
Member Author

thockin commented Mar 19, 2015

Third choice - it's more verbose but I think it is most consistent.

volume.{VolumePlugin, VolumeHost, Volume, VolumePluginMgr} and
volume.{PersistentVolumePlugin, PersistentVolumeHost, PersistentVolume, PersistentVolumePluginMgr}

I'm pushing an updated PR with 2 commits. First commit is the minimal
(Plugin, Host, Volume, PluginMgr). 2nd commit just does the extra renames
(VolumePlugin, VolumeHost, Volume, VolumePluginMgr)

On Thu, Mar 19, 2015 at 1:36 PM, Mark Turansky notifications@github.com
wrote:

As to your two choices above, I think I prefer the latter
("volume.{Plugin, Host, Volume, PluginMgr}, volume.{PersistentPlugin,
PersistentHost, PersistentVolume, PersistentPluginMgr}") but I'll know with
certainty when I start using it!


Reply to this email directly or view it on GitHub
#5642 (comment)
.

@thockin thockin changed the title RFC: Prep for multiple kinds of volume plugins Prep for multiple kinds of volume plugins Mar 19, 2015
@thockin
Copy link
Member Author

thockin commented Mar 19, 2015

I can take or leave the last commit. I sort of prefer it, so if nobody objects strongly, I'd say go with it.

@thockin thockin force-pushed the volume_multi_plugins branch 2 times, most recently from 4f87a4c to 73c0a02 Compare March 19, 2015 22:43
@markturansky
Copy link
Contributor

LGTM. I like the 2nd commit because VolumePluginMgr (for example) is clearer than PluginMgr.

Overall, the renames and moves make sense.

If pkg/volume is now a top-level thing, does it make sense to move pkg/util/mount functionality to pkg/volume?

@vishh
Copy link
Contributor

vishh commented Mar 20, 2015

Needs a rebase @thockin. LGTM otherwise.

@thockin thockin force-pushed the volume_multi_plugins branch from 73c0a02 to 448e7d1 Compare March 20, 2015 20:27
@thockin
Copy link
Member Author

thockin commented Mar 20, 2015

rebased

@markturansky re: util/mount - I'd rather leave it as it's own thing - it's potentially useful and has no other kubernetes tie-ins (whcih is what util/ should be for IMO)

Move pkg/kubelet/volume/... to pkg/volume/...
Some renames to make the soon-to-come persistent volumes work clearer.
@vishh
Copy link
Contributor

vishh commented Mar 20, 2015

LGTM

vishh added a commit that referenced this pull request Mar 20, 2015
Prep for multiple kinds of volume plugins
@vishh vishh merged commit f118ca8 into kubernetes:master Mar 20, 2015
@thockin thockin deleted the volume_multi_plugins branch March 27, 2015 20:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants