Skip to content

Static Provisioning

Static provisioning lets you mount an existing flexFS volume into Kubernetes pods. This works with both the Enterprise and Community editions.

  • The flexFS CSI driver is installed
  • A flexFS volume already exists (created during server installation or via configure.flexfs)
  • You have a Secret containing the admin server address and an account token

Create the PersistentVolumeClaim and PersistentVolume

Section titled “Create the PersistentVolumeClaim and PersistentVolume”
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: flexfs-static
namespace: default
spec:
storageClassName: ""
accessModes:
- ReadWriteMany
resources:
requests:
storage: 8Ei
apiVersion: v1
kind: PersistentVolume
metadata:
name: flexfs-static
spec:
storageClassName: ""
accessModes:
- ReadWriteMany
capacity:
storage: 8Ei
csi:
driver: csi.flexfs.io
volumeHandle: <VOLUME-NAME>
nodePublishSecretRef:
name: flexfs-secret
namespace: default
claimRef:
name: flexfs-static
namespace: default

Replace <VOLUME-NAME> with the name of your existing flexFS volume.

FieldDescription
storageClassName: ""Empty string prevents Kubernetes from using a default StorageClass.
csi.driverMust be csi.flexfs.io.
csi.volumeHandleThe name of the flexFS volume to mount. This is the volume name as shown in configure.flexfs or the free server.
csi.nodePublishSecretRefReference to the Kubernetes Secret containing adminAddr and token.
claimRefPre-binds the PV to the PVC so they pair immediately.

The Secret must contain at minimum the adminAddr and token fields:

apiVersion: v1
kind: Secret
metadata:
name: flexfs-secret
namespace: default
stringData:
adminAddr: <ADMIN-ADDR>
token: <ACCOUNT-TOKEN>

For encrypted volumes, add the secret field:

stringData:
adminAddr: <ADMIN-ADDR>
token: <ACCOUNT-TOKEN>
secret: <ENCRYPTION-SECRET>

See the Secret field reference for all supported fields.

Terminal window
kubectl apply -f secret.yaml
kubectl apply -f static-volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
containers:
- name: app
image: ubuntu:latest
command: ["sleep", "infinity"]
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: flexfs-static

To mount the volume as read-only, set readOnly: true on the pod’s claim reference:

volumes:
- name: data
persistentVolumeClaim:
claimName: flexfs-static
readOnly: true

Setting readOnly: true under the PV’s spec.csi has no effect: for CSI volumes the kubelet takes the read-only flag from the pod’s persistentVolumeClaim.readOnly, not from the PV source. An ro entry in mountOptions is stripped by the driver, so that is not an alternative route either.

You can pass additional mount options via mountOptions on the PV:

spec:
csi:
driver: csi.flexfs.io
volumeHandle: <VOLUME-NAME>
nodePublishSecretRef:
name: flexfs-secret
namespace: default
mountOptions:
- acl
- xattr
- verbose

Statically provisioned volumes and resizing

Section titled “Statically provisioned volumes and resizing”

A pre-existing volume’s size is yours to manage, and a static PV keeps it that way. Kubernetes refuses to resize a claim that was not dynamically provisioned by an expansion-capable StorageClass — an attempt returns only dynamically provisioned pvc can be resized — so the ordinary static setup shown above cannot be resized at all.

Two things follow if you deviate from it. A static PV that names an expansion-enabled StorageClass and carries a controllerExpandSecretRef is resizable, and editing that claim would raise the quota on your pre-existing volume; leave one or both off if the volume’s size is managed out of band. And a volume with no quota cannot be expanded in any case — the driver refuses rather than reporting a meaningless capacity — so a volume you created without --maxBlocks is inert to resizing however the PV is written.

A static PV’s capacity field is informational: nothing enforces it. Quotas live on the volume, set with configure.flexfs update volume --maxBlocks/--maxInodes.

The driver imposes no per-node volume limit. Each volume gets its own base FUSE mount under <kubeletDir>/flexfs/<volume-name>/ — where <kubeletDir> is the configured kubelet root, /var/lib/kubelet by default — and multiple pods referencing the same volume share that one base mount through bind mounts, so the cost of extra pods on the same volume is a bind mount rather than another FUSE session.