Skip to main content
This guide is for teams running workloads on an Nscale Kubernetes Service (NKS) cluster who want shared, persistent, POSIX filesystem storage for their pods. The storage is Nscale file storage, shown as Filesystem in the console. The Nscale File Storage CSI Driver and a high-performance NFS client on the nodes are already installed and maintained for you, so there is nothing to deploy. You create one Kubernetes StorageClass, and from then on your teams request storage with ordinary PersistentVolumeClaim objects.
Before you start, you need:
  • kubectl access to the cluster. See Access your cluster, or run nscale kubernetes kubeconfig get <cluster-id> --merge.
  • File storage available to you. It’s currently offered only in the reserved cloud environment, and the cluster’s VPC needs at least a /24 CIDR block. See Filesystem availability.
  • The Nscale CLI, logged in with nscale login, to look up the file storage class ID. The console doesn’t show class IDs.

What is already in your cluster

Step 1: Find your file storage class ID

A file storage class is an Nscale-side definition of the kind of storage to create: its performance characteristics and the storage features available in a region. Your Kubernetes StorageClass selects one by ID. A file storage class belongs to a region, and you must use one from the region your NKS cluster was provisioned in. Find that region first. The cluster listing shows it in the Region column, or you can read it from the cluster directly:
Then list the file storage classes available in that region with nscale filestorage classes:
Copy the ID of the class you want. To extract just the IDs, or to inspect the full payload:
A class from a different region can’t be attached to your cluster’s network, and PVCs using it never bind.

Step 2: Create a StorageClass

storageclass.yaml
Apply and verify it:

Fields

Parameters

Any other filestorage.csi.nscale.com/* parameter is rejected, and the PVC stays Pending with an unsupported StorageClass parameter error.

Attachment mount options and performance

use-attachment-mount-options: "true" is optional, but recommended. When it is enabled, the driver passes through the mount options that Nscale publishes for the specific network attachment backing your volume, including the multipath options that let a single mount use several storage endpoints in parallel. Without it, the volume still mounts and works correctly, but it mounts with plain kernel NFS defaults and loses that extra throughput. These options need the NFS client that NKS installs on its nodes, so on NKS you can enable this safely. On a self-managed cluster without it, the mount fails with mount.nfs: an incorrect mount option was specified.

StorageClass mount options

You can add mountOptions to the StorageClass, and they are passed to every NFS mount for volumes created from it:
A StorageClass mount option overrides an attachment mount option with the same key. If you have enabled use-attachment-mount-options, leave mountOptions empty unless you have a specific reason to override it. That way the options Nscale publishes for your attachment apply exactly as intended.

Step 3: Create a PersistentVolumeClaim

pvc.yaml
The PVC becomes Bound once the driver has created the file storage and Nscale has attached it to your cluster’s network. This normally takes well under a minute. File storage is sized in whole GiB, so a request is rounded up to the next GiB. Requesting 100Gi gives you 100 GiB; requesting 500Mi gives you 1 GiB. Supported access modes: ReadOnlyMany and block volumes are not supported. Each PVC maps to exactly one file storage resource. To share data between pods, have them mount the same PVC with ReadWriteMany.

Step 4: Mount the PVC in a pod

pod.yaml
Any number of pods, on any number of nodes, can mount the same ReadWriteMany PVC the same way. A Deployment or StatefulSet uses the identical volumes block.

Grow a volume

If the StorageClass sets allowVolumeExpansion: true, edit the PVC request:
Expansion is grow-only and happens online: the mounted pods keep running and see the new size without a restart. Shrink requests are rejected.

Delete a PVC and the Retain reclaim policy

The reclaim policy decides what happens to your data when someone deletes a PVC. With reclaimPolicy: Retain, deleting the PVC never deletes your data. Kubernetes does not call the driver at all. The PersistentVolume is left behind in Released state and the file storage still exists in your project. From there you have three options:
  1. Delete it with the Nscale CLI or in console.nscale.com, once you are sure.
  2. Re-use it. Bind it to a new PVC in this cluster or in another cluster in the same project, or attach it to a compute instance. See Use existing file storage.
  3. Leave it. It stays in the project and keeps using quota, so you still have to decide what to do with it later.
Find the file storage ID behind a released volume. The CSI volumeHandle is the file storage ID:
Then remove the leftover Kubernetes object, and the storage itself if you no longer want it:
Under Retain, deleting the PersistentVolume only removes the Kubernetes object. It does not touch the file storage; only the CLI, the console, or the Nscale API does that.
The reclaim policy is set on each PV when it is created. Changing reclaimPolicy on the StorageClass affects only volumes provisioned after the change. To change an existing one:
Check this on any PVC you care about before deleting it. If the PV says Delete, the data goes with it.

Use existing file storage

Sometimes the storage exists before the PVC does: a volume retained from a deleted PVC, a dataset shared with another cluster or a compute instance, a filesystem seeded outside Kubernetes, or storage whose lifecycle a different team owns. In those cases you don’t ask the driver to provision anything. You point Kubernetes at storage that already exists by writing the PersistentVolume yourself. Such a volume is an admin-managed volume. The CSI driver only mounts it. It never creates, deletes, or resizes it, whatever happens to the Kubernetes objects.
The file storage must be attached to the network your NKS cluster uses. The same file storage can be attached to more than one network, so a volume shared with another cluster or instance is normal. But nothing in this flow checks the attachment for you. If it is missing, the PVC still binds, but the pod hangs in ContainerCreating until the NFS mount times out.

Collect the values

From the output you need the file storage ID, and two values from the attachment for your cluster’s network in status.attachments[]: Split mountSource on the last colon: for 10.0.0.16:/mnt/nfs the server is 10.0.0.16 and the export path is /mnt/nfs. The same values are visible under Storage → Filesystem in the console.

Write the PersistentVolume

pv.yaml
Three details matter:
  • volumeHandle: static:<file-storage-id>. The static: prefix is what protects your data. The driver recognizes it and refuses to delete or resize the file storage, so removing this PersistentVolume can never remove storage the driver did not create. Keeping the real ID after the prefix means kubectl get pv still shows which file storage backs the volume.
  • persistentVolumeReclaimPolicy: Retain. With Retain, Kubernetes never asks the driver to delete anything in the first place. The static: handle is the backstop, not the primary control, so set both.
  • claimRef. Without it, any PVC in any namespace that matches on capacity and access mode can bind this volume.
Put mount options in spec.mountOptions, not in a filestorage.csi.nscale.com/mount-options volume attribute. That attribute is split on commas and breaks a comma-separated value such as a remoteports list.

Write the PersistentVolumeClaim

pvc.yaml
storageClassName: "" on both objects keeps a default StorageClass from being applied, and the PVC can’t request more than the PV’s declared capacity. Pods then mount the PVC exactly as in step 4.

What the driver does and does not do

To resize storage used this way, grow the file storage through the CLI or console, then raise spec.capacity on the PV to match. Leave the PVC as it is: with storageClassName: "" there’s no StorageClass that allows expansion, so the API server rejects a PVC resize.

Troubleshooting

The StorageClass has a filestorage.csi.nscale.com/* parameter the driver doesn’t accept. Use only the supported parameters, then recreate the StorageClass and the PVC.
Check that storage-class-id is a class from the cluster’s region. A class from another region can’t be attached to the cluster’s network. Run kubectl describe pvc <pvc-name> to see the driver’s events.
The file storage isn’t attached to the cluster’s network, so the NFS mount times out. Attach it to that network in the console, or run nscale filestorage update <storage-id> without a file and add the network in the pre-filled prompts, then recreate the pod. A --file payload that only lists the network resets posixAcl and atimeUpdateIntervalSeconds. See Use existing file storage.
The node doesn’t have the NFS client that NKS installs, so it can’t use the attachment mount options. On a self-managed cluster, set use-attachment-mount-options to "false".
Volumes can only grow. Check that the new request is larger than the current size, and that the StorageClass sets allowVolumeExpansion: true. For existing file storage, see what the driver does and does not do.

Managed Kubernetes (NKS)

Create and connect to an NKS cluster

Filesystem

Create, attach, and configure file storage in the console

File storage CLI

Manage file storage, storage classes, and snapshot policies from the command line

Kubernetes CLI

Manage clusters and kubeconfigs from the command line