Skip to content

Commit

Permalink
Auto: unconditionally set affinity when RWO or RWOP is requested.
Browse files Browse the repository at this point in the history
Force HostPath to be used preemptively instead of letting the scheduler
choose where to place the first pod.

Also add support for ReadWriteOncePod.
  • Loading branch information
jp39 committed Aug 18, 2024
1 parent 52c1040 commit e31eb9f
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 14 deletions.
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@ but the `PersistentVolume` objects will have a [NodeAffinity][node affinity] con
![architecture with Hostpath](architecture.hostpath.drawio.svg "Architecture with Hostpath provisioning")

As a third option, if the ZFS host is part of the cluster, you can let the provisioner choose
whether [NFS][nfs] or [HostPath][hostpath] is used with the `Auto` mode. If the scheduler
decides to place a Pod onto the ZFS host, *and* the requested access mode in the Persistent Volume
Claim is `ReadWriteOnce` (the volume can only be accessed by pods running on the same node)
[HostPath][hostpath] will automatically be used, otherwise [NFS][nfs] will be used.
whether [NFS][nfs] or [HostPath][hostpath] is used with the `Auto` mode. If the requested
[AccessModes][access modes] in the Persistent Volume Claim contains `ReadWriteOnce` (the volume
can only be accessed by pods running on the same node), or `ReadWriteOncePod` (the volume can only
be accessed by one single Pod at any time), then [HostPath][hostpath] will be used and
the [NodeAffinity][node affinity] will be configured on the `PersistentVolume` objects so the
scheduler will automatically place the corresponding Pods onto the ZFS host. Otherwise
[NFS][nfs] will be used and [NodeAffinity][node affinity] will not be set.

Currently all ZFS attributes are inherited from the parent dataset.

Expand Down Expand Up @@ -92,8 +95,8 @@ parameters:
For NFS, you can also specify other options, as described in [exports(5)][man exports].
The following example configures a storage class using the `Auto` type. The provisioner
will decide whether [HostPath][hostpath] or [NFS][nfs] will be used based on where the
pods are being scheduled.
will decide whether [HostPath][hostpath] or [NFS][nfs] will be used based on the
[AccessModess][access modes] requested by the persistent volume claim.

```yaml
kind: StorageClass
Expand Down Expand Up @@ -215,3 +218,4 @@ I (@ccremer) have been allowed to take over maintenance for this repository.
[helm chart]: https://github.com/ccremer/kubernetes-zfs-provisioner/blob/master/charts/kubernetes-zfs-provisioner/README.md
[gentics]: https://www.gentics.com/genticscms/index.en.html
[gentics repo]: https://github.com/gentics/kubernetes-zfs-provisioner
[access modes]: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes
3 changes: 0 additions & 3 deletions charts/kubernetes-zfs-provisioner/templates/storageclass.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ metadata:
{{ toYaml . | nindent 4 }}
{{- end }}
provisioner: {{ $.Values.provisioner.instance }}
{{- if eq .type "auto" }}
volumeBindingMode: WaitForFirstConsumer
{{- end }}
reclaimPolicy: {{ .policy | default "Delete" }}
parameters:
parentDataset: {{ .parentDataset }}
Expand Down
10 changes: 5 additions & 5 deletions pkg/provisioner/provision.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func (p *ZFSProvisioner) Provision(ctx context.Context, options controller.Provi
},
Spec: v1.PersistentVolumeSpec{
PersistentVolumeReclaimPolicy: reclaimPolicy,
AccessModes: createAccessModes(useHostPath),
AccessModes: createAccessModes(options, useHostPath),
Capacity: v1.ResourceList{
v1.ResourceStorage: options.PVC.Spec.Resources.Requests[v1.ResourceStorage],
},
Expand All @@ -91,17 +91,17 @@ func canUseHostPath(parameters *ZFSStorageClassParameters, options controller.Pr
case HostPath:
return true
case Auto:
if options.SelectedNode == nil || parameters.HostPathNodeName != options.SelectedNode.Name {
return false
}
if slices.Contains(options.PVC.Spec.AccessModes, v1.ReadOnlyMany) || slices.Contains(options.PVC.Spec.AccessModes, v1.ReadWriteMany) {
return false
}
}
return true
}

func createAccessModes(useHostPath bool) []v1.PersistentVolumeAccessMode {
func createAccessModes(options controller.ProvisionOptions, useHostPath bool) []v1.PersistentVolumeAccessMode {
if slices.Contains(options.PVC.Spec.AccessModes, v1.ReadWriteOncePod) {
return []v1.PersistentVolumeAccessMode{v1.ReadWriteOncePod}
}
accessModes := []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce}
if !useHostPath {
accessModes = append(accessModes, v1.ReadOnlyMany, v1.ReadWriteMany)
Expand Down

0 comments on commit e31eb9f

Please sign in to comment.