This commit is contained in:
Rob Kooper 2025-03-01 18:52:12 +00:00 committed by GitHub
commit 470fbe27a6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 59 additions and 65 deletions

View File

@ -186,7 +186,7 @@ $ oc adm policy add-scc-to-user hostmount-anyuid system:serviceaccount:$NAMESPAC
If you would like to use a custom built nfs-subdir-external-provisioner image, you must edit the provisioner's deployment file to specify the correct location of your `nfs-client-provisioner` container image. If you would like to use a custom built nfs-subdir-external-provisioner image, you must edit the provisioner's deployment file to specify the correct location of your `nfs-client-provisioner` container image.
Next you must edit the provisioner's deployment file to add connection information for your NFS server. Edit `deploy/deployment.yaml` and replace the two occurences of <YOUR NFS SERVER HOSTNAME> with your server's hostname. Next you must edit the provisioner's deployment file to add connection information for your NFS server. Edit `deploy/deployment.yaml` and replace the two occurrences of <YOUR NFS SERVER HOSTNAME> with your server's hostname.
```yaml ```yaml
kind: Deployment kind: Deployment
@ -234,11 +234,11 @@ To disable leader election, define an env variable named ENABLE_LEADER_ELECTION
**_Parameters:_** **_Parameters:_**
| Name | Description | Default | | Name | Description | Default |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------: | | --------------- | ------------------------------------------------------------ | :----------------------------------------------------------: |
| onDelete | If it exists and has a delete value, delete the directory, if it exists and has a retain value, save the directory. | will be archived with name on the share: `archived-<volume.Name>` | | onDelete | If it exists and has a delete value, delete the directory, if it exists and has a retain value, save the directory. | will be archived with name on the share: `archived-<volume.Name>` |
| archiveOnDelete | If it exists and has a false value, delete the directory. if `onDelete` exists, `archiveOnDelete` will be ignored. | will be archived with name on the share: `archived-<volume.Name>` | | archiveOnDelete | If it exists and has a false value, delete the directory. if `onDelete` exists, `archiveOnDelete` will be ignored. | will be archived with name on the share: `archived-<volume.Name>` |
| pathPattern | Specifies a template for creating a directory path via PVC metadata's such as labels, annotations, name or namespace. To specify metadata use `${.PVC.<metadata>}`. Example: If folder should be named like `<pvc-namespace>-<pvc-name>`, use `${.PVC.namespace}-${.PVC.name}` as pathPattern. | n/a | | pathPattern | Specifies a template for creating a directory path via PVC metadata's such as labels, annotations, name or namespace. To specify metadata use `${.PVC.<metadata>}`. Example: If folder should be named like `<pvc-namespace>-<pvc-name>`, use `${.PVC.namespace}-${.PVC.name}` as pathPattern. The default pattern will add the pvname to folder, which will result in a unique folder name, combining namespace, name and an unique id. | `${.PVC.namespace}-${.PVC.name}-${.PVC.pvname}` |
This is `deploy/class.yaml` which defines the NFS subdir external provisioner's Kubernetes Storage Class: This is `deploy/class.yaml` which defines the NFS subdir external provisioner's Kubernetes Storage Class:

View File

@ -48,45 +48,45 @@ The command removes all the Kubernetes components associated with the chart and
The following tables lists the configurable parameters of this chart and their default values. The following tables lists the configurable parameters of this chart and their default values.
| Parameter | Description | Default | | Parameter | Description | Default |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | | ------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
| `replicaCount` | Number of provisioner instances to deployed | `1` | | `replicaCount` | Number of provisioner instances to deployed | `1` |
| `strategyType` | Specifies the strategy used to replace old Pods by new ones | `Recreate` | | `strategyType` | Specifies the strategy used to replace old Pods by new ones | `Recreate` |
| `image.repository` | Provisioner image | `registry.k8s.io/sig-storage/nfs-subdir-external-provisioner` | | `image.repository` | Provisioner image | `registry.k8s.io/sig-storage/nfs-subdir-external-provisioner` |
| `image.tag` | Version of provisioner image | `v4.0.2` | | `image.tag` | Version of provisioner image | `v4.0.2` |
| `image.pullPolicy` | Image pull policy | `IfNotPresent` | | `image.pullPolicy` | Image pull policy | `IfNotPresent` |
| `imagePullSecrets` | Image pull secrets | `[]` | | `imagePullSecrets` | Image pull secrets | `[]` |
| `storageClass.name` | Name of the storageClass | `nfs-client` | | `storageClass.name` | Name of the storageClass | `nfs-client` |
| `storageClass.defaultClass` | Set as the default StorageClass | `false` | | `storageClass.defaultClass` | Set as the default StorageClass | `false` |
| `storageClass.allowVolumeExpansion` | Allow expanding the volume | `true` | | `storageClass.allowVolumeExpansion` | Allow expanding the volume | `true` |
| `storageClass.reclaimPolicy` | Method used to reclaim an obsoleted volume | `Delete` | | `storageClass.reclaimPolicy` | Method used to reclaim an obsoleted volume | `Delete` |
| `storageClass.provisionerName` | Name of the provisionerName | null | | `storageClass.provisionerName` | Name of the provisionerName | null |
| `storageClass.archiveOnDelete` | Archive PVC when deleting | `true` | | `storageClass.archiveOnDelete` | Archive PVC when deleting | `true` |
| `storageClass.onDelete` | Strategy on PVC deletion. Overrides archiveOnDelete when set to lowercase values 'delete' or 'retain' | null | | `storageClass.onDelete` | Strategy on PVC deletion. Overrides archiveOnDelete when set to lowercase values 'delete' or 'retain' | null |
| `storageClass.pathPattern` | Specifies a template for the directory name | null | | `storageClass.pathPattern` | Specifies a template for the directory name. The default will combine PVC namespce, PVC name and PV name which will result in a unique folder name. | `${.PVC.namespace}-${.PVC.name}-${.PVC.pvname}` |
| `storageClass.accessModes` | Set access mode for PV | `ReadWriteOnce` | | `storageClass.accessModes` | Set access mode for PV | `ReadWriteOnce` |
| `storageClass.volumeBindingMode` | Set volume binding mode for Storage Class | `Immediate` | | `storageClass.volumeBindingMode` | Set volume binding mode for Storage Class | `Immediate` |
| `storageClass.annotations` | Set additional annotations for the StorageClass | `{}` | | `storageClass.annotations` | Set additional annotations for the StorageClass | `{}` |
| `leaderElection.enabled` | Enables or disables leader election | `true` | | `leaderElection.enabled` | Enables or disables leader election | `true` |
| `nfs.server` | Hostname of the NFS server (required) | null (ip or hostname) | | `nfs.server` | Hostname of the NFS server (required) | null (ip or hostname) |
| `nfs.path` | Basepath of the mount point to be used | `/nfs-storage` | | `nfs.path` | Basepath of the mount point to be used | `/nfs-storage` |
| `nfs.mountOptions` | Mount options (e.g. 'nfsvers=3') | null | | `nfs.mountOptions` | Mount options (e.g. 'nfsvers=3') | null |
| `nfs.volumeName` | Volume name used inside the pods | `nfs-subdir-external-provisioner-root` | | `nfs.volumeName` | Volume name used inside the pods | `nfs-subdir-external-provisioner-root` |
| `nfs.reclaimPolicy` | Reclaim policy for the main nfs volume used for subdir provisioning | `Retain` | | `nfs.reclaimPolicy` | Reclaim policy for the main nfs volume used for subdir provisioning | `Retain` |
| `resources` | Resources required (e.g. CPU, memory) | `{}` | | `resources` | Resources required (e.g. CPU, memory) | `{}` |
| `rbac.create` | Use Role-based Access Control | `true` | | `rbac.create` | Use Role-based Access Control | `true` |
| `podSecurityPolicy.enabled` | Create & use Pod Security Policy resources | `false` | | `podSecurityPolicy.enabled` | Create & use Pod Security Policy resources | `false` |
| `podAnnotations` | Additional annotations for the Pods | `{}` | | `podAnnotations` | Additional annotations for the Pods | `{}` |
| `priorityClassName` | Set pod priorityClassName | null | | `priorityClassName` | Set pod priorityClassName | null |
| `serviceAccount.create` | Should we create a ServiceAccount | `true` | | `serviceAccount.create` | Should we create a ServiceAccount | `true` |
| `serviceAccount.name` | Name of the ServiceAccount to use | null | | `serviceAccount.name` | Name of the ServiceAccount to use | null |
| `serviceAccount.annotations` | Additional annotations for the ServiceAccount | `{}` | | `serviceAccount.annotations` | Additional annotations for the ServiceAccount | `{}` |
| `nodeSelector` | Node labels for pod assignment | `{}` | | `nodeSelector` | Node labels for pod assignment | `{}` |
| `affinity` | Affinity settings | `{}` | | `affinity` | Affinity settings | `{}` |
| `tolerations` | List of node taints to tolerate | `[]` | | `tolerations` | List of node taints to tolerate | `[]` |
| `labels` | Additional labels for any resource created | `{}` | | `labels` | Additional labels for any resource created | `{}` |
| `podDisruptionBudget.enabled` | Create and use Pod Disruption Budget | `false` | | `podDisruptionBudget.enabled` | Create and use Pod Disruption Budget | `false` |
| `podDisruptionBudget.maxUnavailable` | Set maximum unavailable pods in the Pod Disruption Budget | `1` | | `podDisruptionBudget.maxUnavailable` | Set maximum unavailable pods in the Pod Disruption Budget | `1` |
## Install Multiple Provisioners ## Install Multiple Provisioners

View File

@ -41,6 +41,8 @@ import (
const ( const (
provisionerNameKey = "PROVISIONER_NAME" provisionerNameKey = "PROVISIONER_NAME"
defaultPathPattern = "${.PVC.namespace}-${.PVC.name}-${.PVC.pvname}"
mountPath = "/persistentvolumes"
) )
type nfsProvisioner struct { type nfsProvisioner struct {
@ -73,10 +75,6 @@ func (meta *pvcMetadata) stringParser(str string) string {
return str return str
} }
const (
mountPath = "/persistentvolumes"
)
var _ controller.Provisioner = &nfsProvisioner{} var _ controller.Provisioner = &nfsProvisioner{}
func (p *nfsProvisioner) Provision(ctx context.Context, options controller.ProvisionOptions) (*v1.PersistentVolume, controller.ProvisioningState, error) { func (p *nfsProvisioner) Provision(ctx context.Context, options controller.ProvisionOptions) (*v1.PersistentVolume, controller.ProvisioningState, error) {
@ -85,32 +83,28 @@ func (p *nfsProvisioner) Provision(ctx context.Context, options controller.Provi
} }
glog.V(4).Infof("nfs provisioner: VolumeOptions %v", options) glog.V(4).Infof("nfs provisioner: VolumeOptions %v", options)
pvcNamespace := options.PVC.Namespace
pvcName := options.PVC.Name
pvName := strings.Join([]string{pvcNamespace, pvcName, options.PVName}, "-")
metadata := &pvcMetadata{ metadata := &pvcMetadata{
data: map[string]string{ data: map[string]string{
"name": pvcName, "name": options.PVC.Name,
"namespace": pvcNamespace, "namespace": options.PVC.Namespace,
"pvname": options.PVName,
}, },
labels: options.PVC.Labels, labels: options.PVC.Labels,
annotations: options.PVC.Annotations, annotations: options.PVC.Annotations,
} }
fullPath := filepath.Join(mountPath, pvName)
path := filepath.Join(p.path, pvName)
pathPattern, exists := options.StorageClass.Parameters["pathPattern"] pathPattern, exists := options.StorageClass.Parameters["pathPattern"]
if exists { if !exists || pathPattern == "" {
customPath := metadata.stringParser(pathPattern) pathPattern = defaultPathPattern
if customPath != "" {
path = filepath.Join(p.path, customPath)
fullPath = filepath.Join(mountPath, customPath)
}
} }
parsedPath := metadata.stringParser(pathPattern)
if parsedPath == "" {
return nil, controller.ProvisioningFinished, errors.New("unable to parse pathPattern: " + pathPattern)
}
path := filepath.Join(p.path, parsedPath)
fullPath := filepath.Join(mountPath, parsedPath)
glog.V(4).Infof("creating path %s", fullPath) glog.V(4).Infof("creating path %s", fullPath)
if err := os.MkdirAll(fullPath, 0o777); err != nil { if err := os.MkdirAll(fullPath, 0o777); err != nil {
return nil, controller.ProvisioningFinished, errors.New("unable to create directory to provision new pv: " + err.Error()) return nil, controller.ProvisioningFinished, errors.New("unable to create directory to provision new pv: " + err.Error())