{"id":18690451,"url":"https://github.com/kvaps/subprovisioner","last_synced_at":"2025-11-08T08:30:31.136Z","repository":{"id":205041188,"uuid":"656564994","full_name":"kvaps/subprovisioner","owner":"kvaps","description":"A CSI plugin for Kubernetes that allows provisioning Block volumes from an existing Filesystem volume.","archived":false,"fork":false,"pushed_at":"2023-06-21T07:45:13.000Z","size":53,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"dev","last_synced_at":"2024-12-28T02:30:18.561Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://gitlab.com/subprovisioner/subprovisioner","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kvaps.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-06-21T07:44:58.000Z","updated_at":"2023-06-21T07:46:57.000Z","dependencies_parsed_at":"2023-11-02T09:45:13.561Z","dependency_job_id":null,"html_url":"https://github.com/kvaps/subprovisioner","commit_stats":null,"previous_names":["kvaps/subprovisioner"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kvaps%2Fsubprovisioner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kvaps%2Fsubprovisioner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kvaps%2Fsubprovisioner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kvaps%2Fsubprovisioner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kvaps","download_url":"https://codeload.github.com/kvaps/subprovisioner/tar.gz/refs/heads/dev","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239550283,"owners_count":19657541,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T10:47:37.765Z","updated_at":"2025-11-08T08:30:31.104Z","avatar_url":"https://github.com/kvaps.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- ----------------------------------------------------------------------- --\u003e\n\n# Subprovisioner\n\nA CSI plugin for Kubernetes that allows provisioning `Block` volumes from an\nexisting `Filesystem` volume.\n\n\u003c!-- ----------------------------------------------------------------------- --\u003e\n\n## How to install\n\nThe Subprovisioner images aren't currently published anywhere, so you must build\nthem yourself:\n\n```console\n$ make\n```\n\nThis will use Docker to build an image tagged\n`subprovisioner/subprovisioner:0.0.0`. You must then make sure your Kubernetes\ncluster can pull it, and finally run:\n\n```console\n$ kubectl apply -f deployment.yaml\n```\n\nIf you need to prefix a registry to the image tag, adjust `deployment.yaml`\naccordingly before running the command above.\n\nAnd to uninstall:\n\n```console\n$ kubectl delete --ignore-not-found -f deployment.yaml\n```\n\n\u003c!-- ----------------------------------------------------------------------- --\u003e\n\n## How it's used\n\nAssume you have a `PersistentVolumeClaim` (PVC) of `Filesystem` type with\nsupport for the `ReadWriteMany` access mode, and that it is named `backing-pvc`\nand belongs to namespace `default`.\n\nFirst, create a `StorageClass`:\n\n```yaml\napiVersion: storage.k8s.io/v1\nkind: StorageClass\nmetadata:\n  name: my-storage-class\nprovisioner: subprovisioner.gitlab.io\nparameters:\n  backingClaimName: backing-pvc\n  backingClaimNamespace: default\n  basePath: volumes  # path in backing-pvc under which to store volumes; default is \"\", i.e., at the root\nallowVolumeExpansion: true  # optional\n```\n\nThen provision `Block` volumes from that `StorageClass` as usual:\n\n```yaml\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: my-dynamically-provisioned-block-pvc\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 1Ti\n  volumeMode: Block\n  storageClassName: my-storage-class\n```\n\nThat's it!\n\nNote that the volumes will initially be filled with zeroes and are thinly\nprovisioned, so you can specify volumes sizes bigger than the capacity of the\nbacking volume.\n\n### Expanding volumes\n\nIt is possible to increase the capacity of an existing volume. To do so simply\nedit the `spec.resources.requests.storage` field of the PVC. Once the volume is\nexpanded, `status.capacity.storage` will be updated to reflect its new size.\n\nThe volume will only be expanded once it isn't mounted by any pod.\n\n### Cloning volumes\n\n`Block` volumes may be provisioned by cloning other existing `Block` volumes.\nThis is achieved by referencing an existing PVC in the `spec.dataSource` field\nof the new PVC:\n\n```yaml\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: my-cloned-pvc\nspec:\n  accessModes:\n    - ReadWriteOnce\n  dataSource:\n    kind: PersistentVolumeClaim\n    name: my-dynamically-provisioned-block-pvc\n  resources:\n    requests:\n      storage: 2Ti\n  volumeMode: Block\n  storageClassName: my-storage-class\n```\n\nNote that you may give the cloned volume a bigger size than the original volume.\nThe excess size will be filled with zeroes.\n\nThe clone will be completed only once the original PVC isn't mounted by any pod.\n\n### Snapshotting volumes\n\n\u003e Your Kubernetes distribution might not support volume snapshotting out of the\n\u003e box. Follow [this documentation] to manually install the volume snapshot CRDs\n\u003e and controller.\n\n[this documentation]: https://github.com/kubernetes-csi/external-snapshotter#csi-snapshotter\n\nYou can create `VolumeSnapshot`s from an existing `Block` volume, to later\nprovision new volumes from it. In this case you will need to create a\n[`VolumeSnapshotClass`] beforehand. No parameters need to be specified on it,\nand a single `VolumeSnapshotClass` is enough for all Subprovisioner volumes,\neven if they have different backing volumes or `StorageClass`es. This will do:\n\n```yaml\napiVersion: snapshot.storage.k8s.io/v1\nkind: VolumeSnapshotClass\nmetadata:\n  name: subprovisioner\ndriver: subprovisioner.gitlab.io\ndeletionPolicy: Delete\n```\n\nThen create a `VolumeSnapshot` from an existing PVC like this:\n\n```yaml\napiVersion: snapshot.storage.k8s.io/v1\nkind: VolumeSnapshot\nmetadata:\n  name: my-snapshot\nspec:\n  volumeSnapshotClassName: subprovisioner\n  source:\n    persistentVolumeClaimName: my-dynamically-provisioned-block-pvc\n```\n\nThe snapshot will be completed only once the PVC isn't mounted by any pod.\n\nYou can then provision `Block` volumes from that `VolumeSnapshot`:\n\n```yaml\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: my-cloned-pvc\nspec:\n  accessModes:\n    - ReadWriteOnce\n  dataSource:\n    apiGroup: snapshot.storage.k8s.io\n    kind: VolumeSnapshot\n    name: my-snapshot\n  resources:\n    requests:\n      storage: 2Ti\n  volumeMode: Block\n  storageClassName: my-storage-class\n```\n\nJust like with volume cloning, you may give the volume a bigger size than that\nof the snapshot, and the excess size will be filled with zeroes.\n\n[`VolumeSnapshotClass`]: https://kubernetes.io/docs/concepts/storage/volume-snapshot-classes/\n\n\u003c!-- ----------------------------------------------------------------------- --\u003e\n\n## How it works\n\nProvisioned `Block` volumes are stored in the backing `Filesystem` volume as\nqcow2 image files. [qemu-storage-daemon] is used to expose those images as block\ndevices. Volume cloning and snapshotting is implemented by creating overlay\nqcow2 files, making it very efficient.\n\n[qemu-storage-daemon]: https://qemu.readthedocs.io/en/latest/tools/qemu-storage-daemon.html\n\n\u003c!-- ----------------------------------------------------------------------- --\u003e\n\n## Features\n\n- Dynamic `Block` volume provisioning.\n- `ReadWriteOnce`, `ReadWriteOncePod`, and `ReadOnlyMany` access modes.\n- Efficient (constant-time) offline volume expansion.\n- Efficient (constant-time) offline volume cloning.\n- Efficient (constant-time) offline volume snapshotting.\n\n\u003c!-- ----------------------------------------------------------------------- --\u003e\n\n## Limitations\n\n- The backing volume must be `ReadWriteMany`.\n\n- You have to be careful not to delete the backing volume PVC prior to deleting\n  PVCs backed by it, or else deletion of the latter will hang.\n\n- The plugin assumes that all nodes in the Kubernetes cluster have the the\n  kernel NBD client loaded, such that NBD block nodes are available at\n  `/dev/nbd0`, `/dev/nbd1`, etc.\n\n- The number of Subprovisioner-provisioned volumes that can be simultaneously\n  mounted on a given node is limited by the amount of kernel NBD block devices\n  that are available. Assuming the NBD kernel client was built as a module, use\n  the `nbds_max` option to increase the maximum number of NBD block devices if\n  needed, _e.g._, `modprobe nbd nbds_max=64`.\n\n- The plugin assumes that it created all PVs that have `spec.csi.driver` set to\n  `subprovisioner.gitlab.io`, so don't create such a PV manually.\n\n- On some systems, you may need to configure Docker [mount-propagation] to allow\n  for bidirectional volume mounts, which Subprovisioner will eventually on.\n\n[mount-propagation]: https://kubernetes.io/docs/concepts/storage/volumes/#configuration\n\n\u003c!-- ----------------------------------------------------------------------- --\u003e\n\n## Some TODO\n\n- Support online volume cloning.\n- Support online volume snapshotting.\n- Allow provisioning `Filesystem` volumes.\n- Propagate volume accessibility constraints from the backing volume to the\n  provisioned volumes.\n- Support multiple backing volumes, as long as the set of nodes they're\n  accessible from is disjoint.\n- Opt-in support for making provisioned volumes accessible from any node even\n  if the corresponding backing volume is not, by using networked NBD.\n- Run at most one qemu-storage-daemon instance per node, per backing volume,\n  per `Block` volume namespace.\n\n\u003c!-- ----------------------------------------------------------------------- --\u003e\n\n## License\n\nThis project is released under the Apache 2.0 license. See [LICENSE](LICENSE).\n\n\u003c!-- ----------------------------------------------------------------------- --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkvaps%2Fsubprovisioner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkvaps%2Fsubprovisioner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkvaps%2Fsubprovisioner/lists"}