Google Cloud Filestore can be mounted as Persistent Volumes in GKE, but it’s not as simple as just pointing to a Filestore instance.
Let’s see it in action.
Imagine you have a stateless application running in GKE, but it needs to share some configuration files that are updated externally. Or maybe you have a legacy application that expects to write to a shared filesystem. Filestore, Google’s managed NFS service, is the natural fit.
Here’s a basic Pod definition that tries to mount a Filestore instance directly.
apiVersion: v1
kind: Pod
metadata:
name: filestore-test-pod
spec:
containers:
- name: app
image: nginx:latest
volumeMounts:
- name: filestore-volume
mountPath: "/usr/share/nginx/html"
volumes:
- name: filestore-volume
nfs:
server: 10.20.30.40 # Replace with your Filestore IP
path: "/"
This looks like a standard NFS mount, right? But it’s going to fail. The nfs volume type in Kubernetes is intended for existing NFS shares, not for provisioning new ones dynamically. You need a way to tell GKE about your Filestore instance and how to make it available as a Persistent Volume. This is where the cloud-provider-gcp component and PersistentVolumeClaims come in.
The mental model you need is this: GKE’s built-in cloud provider integration understands how to provision and manage Google Cloud resources like Filestore. When you define a PersistentVolumeClaim (PVC) that requests a specific storage class pointing to Filestore, the cloud provider controller intercepts this request. It then talks to the Filestore API to create or identify a Filestore instance and makes it available as a PersistentVolume (PV) that the PVC can bind to. Your Pod then mounts this PV.
Here’s the full workflow:
-
Create a Filestore Instance: First, you need a Filestore instance. You can do this via the Cloud Console or
gcloud. Let’s say you create a basic instance in theus-central1-azone with a 1TB capacity.gcloud filestore instances create my-filestore-instance \ --project=your-gcp-project-id \ --location=us-central1-a \ --network=projects/your-gcp-project-id/global/networks/your-vpc-network \ --tier=STANDARD \ --file-share=name=my-share,capacity-gb=1000 \ --reserved-ip-range=10.10.10.0/24Important: The Filestore instance must be in the same VPC network as your GKE cluster. The
--reserved-ip-rangeis crucial for ensuring the Filestore instance gets an IP address that your GKE nodes can reach. Note the IP address assigned to your Filestore instance. -
Configure StorageClass: You need a
StorageClassthat tells Kubernetes to use Filestore. GKE provides a built-instandard-rwostorage class, but for Filestore, you’ll define your own.apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: google-filestore-standard provisioner: filestore.csi.storage.gke.io parameters: network: projects/your-gcp-project-id/global/networks/your-vpc-network tier: STANDARD instanceName: my-filestore-instance # The name of your Filestore instance volumeName: my-share # The name of the file share within your Filestore instance allowVolumeExpansion: trueThe
provisionerfilestore.csi.storage.gke.iois key here. It tells the GKE CSI driver to provision Filestore volumes. Theparametersspecify which Filestore instance and file share to use.allowVolumeExpansionlets you resize the volume later. -
Create a PersistentVolumeClaim (PVC): Now, you request storage using your new
StorageClass.apiVersion: v1 kind: PersistentVolumeClaim metadata: name: filestore-pvc spec: accessModes: - ReadWriteOnce # Filestore supports RWX, but RWO is more common for single-pod mounts storageClassName: google-filestore-standard resources: requests: storage: 100Gi # Request a size, it will be carved out from your instanceWhen this PVC is created, the
google-filestore-standardStorageClass’s provisioner will create aPersistentVolumeobject that references your Filestore instance and the specified file share, carving out 100Gi for this specific volume. The PVC will then bind to this PV. -
Mount the PVC in your Pod: Finally, you use the PVC in your Pod definition.
apiVersion: v1 kind: Pod metadata: name: filestore-app-pod spec: containers: - name: app-container image: nginx:latest ports: - containerPort: 80 volumeMounts: - name: filestore-storage mountPath: "/usr/share/nginx/html" # Example mount path volumes: - name: filestore-storage persistentVolumeClaim: claimName: filestore-pvcThis Pod will now mount the volume provided by the
filestore-pvcwhich, in turn, is backed by your Filestore instance.
The most surprising part is that the StorageClass parameters directly map to a specific Filestore instance and file share. You’re not creating new Filestore instances per PVC (unless you use a different provisioner setup); you’re creating logical volumes within an existing Filestore instance. This means you need to carefully manage the capacity of your Filestore instance itself, as multiple PVCs will share its total capacity.
The next problem you’ll likely encounter is managing multiple applications that need to access different parts of the same Filestore instance, or understanding how to provision new Filestore instances dynamically based on PVC requests.