-
Notifications
You must be signed in to change notification settings - Fork 336
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
Add dynamic provisioning support for CSI migration scenarios #253
Conversation
ef09afb
to
ae0c72e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR Deep! Just a couple small comments.
handlesMigrationFromInTreePlugin := false | ||
handlesMigrationFromInTreePluginName := "" | ||
if csitranslationlib.IsMigratedCSIDriverByName(provisionerName) { | ||
handlesMigrationFromInTreePluginName, err = csitranslationlib.GetInTreeNameFromCSIName(provisionerName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this instead be a parameter passed in to the provisioner? If an inTreePluginName
is given then it handles that migration and if an empty string or nothing is passed in we know it doesn't handle it.
This just gives us more options. Maybe someone will want to run two of the same driver, one for migration one for native CSI. Or maybe someone wants to do a fork of a driver and use that for migration (for some crazy weird reason). Either way I think leaving it open for more options seems like a better idea unless there is a specific issue we have with doing that.
Also could we envision a scenario where we would want to pass in multiple in-tree plugin names? Maybe if in the future a single external provisioner could service multiple drivers? Or a single driver is able to handle the dynamic provisioning for multiple different in-tree plugins. This is probably not as useful to think about right now but it would be nice to leave room for it.
Maybe just a string parameter is fine for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The suggestion to have options and keep this extensible sounds good. The main concern I have with the options is that some of the logic in https://github.com/kubernetes/csi-translation-lib/blob/master/translate.go is pretty tightly bound to names of specific CSI drivers for certain translations like https://github.com/kubernetes/csi-translation-lib/blob/master/translate.go#L72. Perhaps we can add a note for authors in the migration notes that name changes for a CSI driver needs to be reflected in the csi-translation-lib.
pkg/controller/controller.go
Outdated
volumeNameUUIDLength int | ||
config *rest.Config | ||
driverName string | ||
handlesMigrationFromInTreePlugin bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this bool since the existence of handlesMigrationFromInTreePluginName
kind of implies that it is migrated right?
performInTreeTranslation := false | ||
if p.handlesMigrationFromInTreePlugin { | ||
storageClassName := options.PVC.Spec.StorageClassName | ||
storageClass, err := p.client.StorageV1().StorageClasses().Get(*storageClassName, metav1.GetOptions{}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add a TODO(ISSUENUMBER): use informers
pkg/controller/controller.go
Outdated
if err != nil { | ||
return nil, fmt.Errorf("failed to get storage class named %s: %v", *storageClassName, err) | ||
} | ||
if storageClass.Provisioner == p.handlesMigrationFromInTreePluginName { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add the else block that can log that we are not translating the storage class parameters. Just to make this easier to understand (I got confused at first)
pkg/controller/controller.go
Outdated
return nil, fmt.Errorf("failed to get storage class named %s: %v", *storageClassName, err) | ||
} | ||
if storageClass.Provisioner == p.handlesMigrationFromInTreePluginName { | ||
klog.V(2).Infof("Perform CSI migration for intree plugin %s", storageClass.Provisioner) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
be more specific here. CSI Migration: translating storage class parameters for in-tree plugin %s
?
pkg/controller/controller.go
Outdated
@@ -551,6 +576,13 @@ func (p *csiProvisioner) Provision(options controller.VolumeOptions) (*v1.Persis | |||
pv.Spec.PersistentVolumeSource.CSI.FSType = fsType | |||
} | |||
|
|||
if performInTreeTranslation { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
performInTreeTranslation
doesn't seem like the right name.
It relates to "this specific volume is using translation logic for migration"
volumeMigrated
?
volumeShimmed
?
volumeTranslated
?
I would go with translated probably but will defer to you
pkg/controller/controller.go
Outdated
volumeNamePrefix: volumeNamePrefix, | ||
volumeNameUUIDLength: volumeNameUUIDLength, | ||
handlesMigrationFromInTreePlugin: handlesMigrationFromInTreePlugin, | ||
handlesMigrationFromInTreePluginName: handlesMigrationFromInTreePluginName, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe just supportsInTreePlugin
(name is implied)?
@@ -59,12 +59,32 @@ var ( | |||
workerThreads = flag.Uint("worker-threads", 100, "Number of provisioner worker threads, in other words nr. of simultaneous CSI calls.") | |||
operationTimeout = flag.Duration("timeout", 10*time.Second, "Timeout for waiting for creation or deletion of a volume") | |||
provisioner = flag.String("provisioner", "", "This option is deprecated") | |||
inTreePluginName = flag.String("supersedes-in-tree-plugin-name", "", "An in-tree plugin that is superseded by this CSI plugin") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would appreciate "migration" somewhere in the parameter name and description. --migrated-plugin-name
?
klog.Warningf("Provisioner name: %s not registered in CSI translation library for performing migrations for %s", csiPluginName, inTreePluginName) | ||
return | ||
} | ||
inTreePluginNameFromLib, err := csitranslationlib.GetInTreeNameFromCSIName(csiPluginName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we can query in-tree plugin name from CSI driver name, why do we need --supersedes-in-tree-plugin-name
option? Should be --feature-gate
enough? It allows us to enable it by default during beta.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops this is complete opposite of my comment from earlier. I didn't think about enabling it by default during beta. Sorry @ddebroy could you change it back... my bad
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will revert back to querying behavior. That will ensure a single source of truth i.e. the translation library and enablement of migration by default. As far as feature gates is concerned, this will depend on the in-tree feature gates to be enabled for individual plugins (besides migration in general) for the PV controller to pass PVCs with in-tree provisioners to external provisioners.
Comments above have been addressed and ready for another look @jsafrane @davidz627 |
Signed-off-by: Deep Debroy <[email protected]>
Rebased to latest changes. |
pkg/controller/controller.go
Outdated
@@ -325,6 +329,31 @@ func getVolumeCapability( | |||
} | |||
|
|||
func (p *csiProvisioner) Provision(options controller.VolumeOptions) (*v1.PersistentVolume, error) { | |||
if options.PVC.Spec.Selector != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is already selector check below.
(this is probably result of rebase)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for catching this. Will remove.
if p.supportsMigrationFromInTreePluginName != "" { | ||
storageClassName := options.PVC.Spec.StorageClassName | ||
//TODO(https://github.com/kubernetes-csi/external-provisioner/issues/256): use informers | ||
storageClass, err := p.client.StorageV1().StorageClasses().Get(*storageClassName, metav1.GetOptions{}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the only reason for Get
class is to get the provisioner name, there is one in PVC.Annotations["volume.beta.kubernetes.io/storage-provisioner"]
. Can this be used instead? Or please add comment why it can't.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. PVC.Annotations["volume.beta.kubernetes.io/storage-provisioner"]
cannot be used for migration scenarios because it's set to the name of the CSI provisioner at https://github.com/kubernetes/kubernetes/blob/596a48dd64bcaa01c1d2515dc79a558a4466d463/pkg/controller/volume/persistentvolume/pv_controller.go#L1383 and https://github.com/kubernetes/kubernetes/blob/596a48dd64bcaa01c1d2515dc79a558a4466d463/pkg/controller/volume/persistentvolume/pv_controller.go#L1396 so that external CSI provisioner can detect the PVC and act on it. Will clarify with comment.
if migratedVolume { | ||
pv, err = csitranslationlib.TranslateCSIPVToInTree(pv) | ||
if err != nil { | ||
return nil, err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This leaves the provisioned volume orphaned in the storage backend. We can either delete it (possibly resulting in other errors, oh well...) or return an error that suggests there is an orphan that must be cleaned manually. Both are quite bad, I'd prefer deleting the volume though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, some log (or even an event?) that this is a critical bug and should be reported / fixed would be helpful.
LGTM, will let @jsafrane do the final tagging |
lgtm, please squash the commits (at least no "Address code review comments") |
Signed-off-by: Deep Debroy <[email protected]>
Commits squashed. |
/lgtm |
@ddebroy: GitHub didn't allow me to assign the following users: for, approval. Note that only kubernetes-csi members and repo collaborators can be assigned and that issues/PRs can only have 10 assignees at the same time. |
/approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: davidz627, ddebroy, jsafrane The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Upgrade csi-lib-utils to 0.8.1
adb3af9df Merge pull request kubernetes-csi#252 from bells17/update-go-version b82ee3888 Merge pull request kubernetes-csi#253 from bells17/fix-typo c31745621 Fix typo 0a7850561 Bump to Go 1.22.3 edd89ad58 Merge pull request kubernetes-csi#251 from jsafrane/add-logcheck 043fd0991 Add test-logcheck target d7535ae0c Merge pull request kubernetes-csi#250 from jsafrane/go-1.22 b52e7ad35 Update go to 1.22.2 14fdb6f66 Merge pull request kubernetes-csi#247 from msau42/prow 9b4352e9f Update release playbook c7bb972cc Fix release notes script to use fixed tags 463a0e9f5 Add script to update specific go modules git-subtree-dir: release-tools git-subtree-split: adb3af9dfa3ed4d1a922cd839bb48e0b73918617
f40f0ccd4 Merge pull request kubernetes-csi#256 from solumath/master cfa92106c Instruction update 379a1bb9b Merge pull request kubernetes-csi#255 from humblec/sidecar-md a5667bbbb fix typo in sidecar release process 49676850e Merge pull request kubernetes-csi#254 from bells17/add-github-actions d9bd160c2 Update skip list in codespell GitHub Action adb3af9df Merge pull request kubernetes-csi#252 from bells17/update-go-version f5aebfc9f Add GitHub Actions workflows b82ee3888 Merge pull request kubernetes-csi#253 from bells17/fix-typo c31745621 Fix typo 0a7850561 Bump to Go 1.22.3 edd89ad58 Merge pull request kubernetes-csi#251 from jsafrane/add-logcheck 043fd0991 Add test-logcheck target d7535ae0c Merge pull request kubernetes-csi#250 from jsafrane/go-1.22 b52e7ad35 Update go to 1.22.2 14fdb6f66 Merge pull request kubernetes-csi#247 from msau42/prow 9b4352e9f Update release playbook c7bb972cc Fix release notes script to use fixed tags 463a0e9f5 Add script to update specific go modules git-subtree-dir: release-tools git-subtree-split: f40f0ccd458f2d4555e3ca98d69b5a984bae0f14
NOTE 1: The CSI migration provisioning logic here is not directly feature gated. However, the feature flags on the in-tree side sufficiently protects the logic here. This is because the PV controller in-tree will only yield PVCs (for in-tree provisioners) to the external provisioner when the feature flags for CSI migration for a particular plugin is enabled in-tree which in turn will make a plugin advertise
IsMigratedToCSI
: kubernetes/kubernetes@23478f1#diff-3f32ad90966ceeb297f57c2a8d726348R1404NOTE 2: Unit tests are skipped for now. We need to address kubernetes/kubernetes#74594 to be able to inject unit-tests as desired into the translation framework for unit testing purposes.
Tested e2e with GCE PD CSI driver name and ensured CSI driver got invoked for provisioning but the resulting PV pointed to GCEPersistentDisk