
Google Cloud Filestore is Google Cloud's managed NFS file storage service that provides shared file systems for Compute Engine instances and Google Kubernetes Engine workloads. It removes the need to operate file servers, but it bills for provisioned capacity instead of consumed capacity, enforces per-tier minimum instance sizes and fixed performance tiers, and confines each instance to a single Google Cloud zone or region with access governed by Google Cloud IAM and VPC peering. Teams that need shared storage on their own infrastructure, with control over replication, performance tuning, and capacity growth, require a self-managed alternative.
CephFS is a POSIX-compliant distributed file system built on the Ceph storage platform that provides the same ReadWriteMany shared storage semantics as Filestore without the managed-service constraints. It provides shared storage across multiple nodes and can be deployed on Kubernetes using the Rook operator. CephFS supports dynamic volume provisioning through the Container Storage Interface (CSI) and can be extended using NFS-Ganesha to provide NFS access for external clients.
This article explains how to deploy CephFS on a Kubernetes Engine cluster using Rook. It covers installing the Rook operator, creating a Ceph cluster, configuring a CephFS filesystem, provisioning persistent volumes, and exporting storage over NFS. It also covers verifying storage functionality, configuring snapshots and monitoring, and preparing the environment for workload integration.
CephFS maps directly to Google Cloud Filestore features while providing a self-managed and Kubernetes-native storage platform.
Key components of the CephFS deployment include:
Before you begin, you need to:
kubectl and configure access to the Kubernetes cluster.Rook extends Kubernetes with orchestration capabilities for Ceph storage services such as MONs, MGRs, OSDs, and MDSs.
Create the project directory.
Switch to the project directory.
Verify that all Kubernetes nodes are in the Ready state.
Output:
Add the Rook Helm repository.
Update the local Helm repository index.
Install the Rook Ceph operator using the Rook Ceph Helm chart.
The command installs the Rook operator and the required Kubernetes custom resource definitions (CRDs).
This article pins the Rook operator to v1.19.7, a tested release that automatically provisions the Ceph CSI driver used for dynamic CephFS volume provisioning. If you install a newer Rook version, confirm that the rook-ceph.cephfs.csi.ceph.com CSI driver is created before provisioning PersistentVolumeClaims.
Verify that the Rook Ceph operator resources are deploying.
Output:
Verify that the Ceph custom resource definitions (CRDs) are available before deploying the Ceph cluster.
The Ceph cluster provides the distributed storage backend used by CephFS. Rook deploys Ceph components as Kubernetes pods and manages storage devices attached to the worker nodes. The cluster is configured through the CephCluster custom resource.
Create the Ceph cluster configuration file.
Add the following configuration to the file:
Save and close the file.
The deviceFilter: "^vd[b-z]" setting instructs Rook to use only additional VirtIO block storage devices such as vdb, vdc, and vdd when creating Ceph OSDs. This excludes the primary system disk, which is typically attached as vda on cloud-based Kubernetes worker nodes. Verify the available block devices on each node before deployment and update the filter if your storage devices use a different naming scheme.
The configuration:
/var/lib/rook^vd[b-z] device filterDeploy the Ceph cluster.
Monitor the Ceph pods during deployment and wait for the monitor (MON), manager (MGR), and OSD pods to initialize.
The deployment process may take several minutes while Rook initializes the Ceph monitor (MON), manager (MGR), and object storage daemon (OSD) services. If the pods remain in a pending or failed state for an extended period, refer to the Rook Ceph Common Issues Documentation.
Verify that the OSD pods are running.
Output:
Verify that the Ceph cluster reaches the Ready state.
Output:
The CephFS filesystem provides shared file storage backed by the Ceph cluster. Rook deploys Ceph metadata server (MDS) pods to manage filesystem metadata and coordinate file access between Kubernetes workloads. The filesystem is defined through the CephFilesystem custom resource.
Create the Ceph filesystem configuration file.
Add the following configuration to the file:
Save and close the file.
The configuration:
cephfsDeploy the CephFS filesystem.
Monitor the CephFS resources during deployment and wait for the MDS pods to initialize.
Verify that the MDS pods are running.
Output:
Verify that the Ceph filesystem reaches the Ready state.
Output:
The CephFS CSI driver enables Kubernetes workloads to dynamically provision and mount shared CephFS storage volumes using PersistentVolumeClaims (PVCs).
Create the CephFS StorageClass configuration file.
Add the following configuration to the file:
Save and close the file.
The configuration:
cephfs-storagecephfs filesystemDeploy the StorageClass.
Verify that the StorageClass is created.
Output:
Create the PersistentVolumeClaim configuration file.
Add the following configuration to the file:
Save and close the file.
The configuration:
cephfs-pvcReadWriteMany access modeDeploy the PersistentVolumeClaim.
Verify that the PersistentVolumeClaim is bound.
Output:
Create the test pod configuration file.
Add the following configuration to the file:
Save and close the file.
The configuration mounts the CephFS-backed PersistentVolumeClaim inside the pod at /mnt/cephfs.
Deploy the test pod.
Verify that the test pod is running.
Output:
Create a test file inside the mounted CephFS volume.
Inside the container, create a test file.
Verify that the file exists.
Output:
The Ceph NFS service enables external systems and legacy applications to access CephFS storage using the standard NFS protocol. Rook deploys NFS-Ganesha pods to export CephFS shares over the network. The NFS service is defined through the CephNFS custom resource, and exports are managed with the ceph nfs export commands.
Create the Ceph NFS configuration file.
Add the following configuration to the file:
Save and close the file.
The configuration:
ceph-nfs.nfs Reliable Autonomic Distributed Object Store (RADOS) pool for NFS recovery dataDeploy the NFS service.
Monitor the NFS resources during deployment.
Verify that the NFS-Ganesha pod is running.
Output:
Create a Rook Ceph toolbox pod to manage Ceph NFS exports.
Verify that the toolbox pod is running.
Output:
Create an NFS export for the CephFS filesystem.
Output:
The command exports the cephfs filesystem through the ceph-nfs NFS-Ganesha service using the /cephfs export path.
Verify that the NFS export is created.
Output:
Retrieve the NFS service details.
Output:
The NFS service is created with a ClusterIP address, which is reachable from the Kubernetes worker nodes and from pods running in the cluster. Mount the exported NFS share from one of the worker nodes.
A ClusterIP address is not reachable from outside the Kubernetes cluster network. To mount the export from a system outside the cluster, such as a separate virtual machine, expose the NFS service using a LoadBalancer or NodePort service instead of the default ClusterIP.
Create a temporary mount directory.
Install the NFS client utilities.
On Ubuntu and Debian:
On Rocky Linux and AlmaLinux:
Mount the exported CephFS NFS share. Replace NFS-SERVICE-IP with the ClusterIP address of the rook-ceph-nfs-ceph-nfs-a service.
Create a test file in the mounted NFS share.
Verify that the file exists.
Output:
This confirms that the CephFS filesystem is exported through NFS-Ganesha and accessible using the standard NFS protocol.
Ceph storage pools control how data is distributed and replicated across the cluster. In addition to the pools that back the CephFS filesystem deployed earlier, you can create dedicated block pools for other Kubernetes workloads and configure replica placement policies to improve resiliency.
Create the Ceph block pool configuration file.
Add the following configuration to the file:
Save and close the file.
The configuration:
app-block-pool, independent of the pools backing the CephFS filesystem, for workloads that need RBD-backed block storagehost failure domain to distribute replicas across separate nodesDeploy the storage pool.
Verify that the storage pool is created.
Output:
View the Ceph cluster health.
Output:
This confirms that the Ceph block pool is configured and the cluster is operating in a healthy state.
CephFS snapshots allow you to capture point-in-time copies of persistent volumes and restore data when needed. Kubernetes uses the CSI snapshot controller together with the Rook CephFS CSI driver to manage volume snapshot operations.
The Kubernetes CSI snapshot CRDs enable Kubernetes to manage volume snapshots for CSI-compatible storage drivers such as Rook CephFS.
Deploy the VolumeSnapshotClass CRD.
Deploy the VolumeSnapshotContent CRD.
Deploy the VolumeSnapshot CRD.
Deploy the snapshot controller RBAC resources.
Deploy the snapshot controller.
Verify that the snapshot controller pods are running.
Output:
The VolumeSnapshotClass defines how Kubernetes creates and manages snapshots using the Rook CephFS CSI driver.
Create the snapshot class configuration file.
Add the following configuration to the file:
Save and close the file.
The configuration:
cephfs-snapshotclassDeploy the snapshot class.
Verify that the snapshot class is created.
Output:
The VolumeSnapshot resource creates a point-in-time snapshot of a PersistentVolumeClaim using the CephFS CSI driver.
Create the snapshot configuration file.
Add the following configuration to the file:
Save and close the file.
The configuration creates a snapshot of the cephfs-pvc PersistentVolumeClaim using the cephfs-snapshotclass snapshot class.
Deploy the snapshot.
Verify that the snapshot is ready.
Output:
You can restore a CephFS snapshot to a new PersistentVolumeClaim to recover application data or create a duplicate volume from an existing snapshot.
Create the restore PVC configuration file.
Add the following configuration to the file:
Save and close the file.
The configuration:
cephfs-restore-pvccephfs-snapshot snapshotcephfs-storage StorageClass for CephFS storageThe restored PersistentVolumeClaim size must be equal to or larger than the source snapshot restore size. Kubernetes does not allow restoring snapshots into smaller volumes.
Deploy the restored PersistentVolumeClaim.
Verify that the restored PersistentVolumeClaim is bound.
Output:
Kubernetes does not create scheduled snapshots automatically. You can use a Kubernetes CronJob resource to create recurring CephFS snapshots for backup and recovery workflows. The CronJob runs kubectl inside the cluster, so it requires a ServiceAccount with role-based access control (RBAC) permission to manage VolumeSnapshot resources.
Create the snapshot RBAC configuration file.
Add the following configuration to the file:
Save and close the file.
The configuration:
cephfs-snapshot-sa for the snapshot CronJobVolumeSnapshot resources in the default namespaceDeploy the snapshot RBAC resources.
Create the scheduled snapshot configuration file.
Add the following configuration to the file:
Save and close the file.
The configuration:
cephfs-snapshot-cronjobcephfs-snapshot-sa ServiceAccount with permission to manage snapshotscephfs-snapshotclass snapshot classcephfs-pvc PersistentVolumeClaimDeploy the scheduled snapshot CronJob.
Verify that the CronJob is created.
Output:
CephFS uses CephX authentication to control client access to the filesystem. You can create restricted CephFS users, limit access to specific directories, and apply POSIX file permissions to isolate workloads between tenants and applications.
CephFS honors standard POSIX ownership and permission bits, so you can isolate directories for different tenants using the same chown and chmod commands you would use on a local filesystem.
Open a shell inside the test pod.
Create separate directories for different tenants inside the mounted CephFS volume.
Assign ownership to the tenant-a directory.
Restrict access to the directory owner only.
Verify the directory permissions.
Output:
Exit the pod shell.
CephFS supports path-based authorization using CephX authentication. You can create dedicated CephFS users and restrict access to specific filesystem paths for tenant isolation and workload security.
Open a shell inside the Rook toolbox pod.
Create a CephFS client user with read and write access restricted to the /tenant-a directory.
Retrieve the authentication key for the client.tenant-a CephFS user.
View the client capabilities.
Exit the toolbox shell.
The path passed to ceph fs authorize is resolved from the root of the CephFS filesystem, not from the pod's local PersistentVolumeClaim mount point. If the CSI driver provisions the PersistentVolumeClaim as a subvolume rather than exposing the filesystem root directly, retrieve the subvolume's actual path with ceph fs subvolume getpath before authorizing access, and adjust the path argument to match.
Verify that the client.tenant-a credentials restrict access to the intended path. Mount CephFS directly on a Linux client using the kernel client and the retrieved key. Replace MON-IP with the IP address of a Ceph monitor, and CLIENT-KEY with the key retrieved for client.tenant-a in the previous step.
Confirm that the mount succeeds and that only the authorized directory is visible.
A permission error when accessing paths outside the mounted directory confirms that the CephX authorization correctly restricts the client's access.
Ceph provides built-in monitoring features through the Ceph Dashboard, Prometheus metrics endpoints, and Grafana dashboards. You can use these services to monitor cluster health, storage utilization, CephFS activity, and OSD performance.
The Ceph Manager (MGR) service hosts the Ceph Dashboard and monitoring modules.
Verify that the Ceph cluster is healthy.
Output:
Verify that the Ceph Manager pod is running.
Retrieve the Ceph Dashboard service details.
Output:
The Ceph Dashboard service defaults to a ClusterIP address, so reach it from your local workstation using a kubectl port-forward session.
Forward the Ceph Dashboard service to your local workstation.
Open http://127.0.0.1:7000 in a web browser.
Retrieve the dashboard administrator password. Open a new terminal session and run the following command.
Copy the password from the command output.
Use the default username admin and paste the copied password to log in to the Ceph Dashboard.
Ceph exports monitoring metrics through the Prometheus module running on the Ceph Manager service.
Enable the Prometheus module.
Verify that the Prometheus module is enabled.
Retrieve the Ceph Manager service details.
Grafana visualizes Prometheus metrics using dashboards for Ceph cluster monitoring.
Add the Grafana Community Helm repository.
Update the Helm repository index.
Deploy Grafana.
Verify that the Grafana pod is running.
Output:
Retrieve the Grafana administrator password.
Copy the password value.
Forward the Grafana service to your local workstation.
Open http://127.0.0.1:3000 in a web browser.
Use the default username admin and the password retrieved in Step 5 to log in to Grafana.
You can perform an end-to-end validation to verify the CephFS deployment, NFS export, snapshot functionality, and monitoring services.
Confirm that the PersistentVolumeClaim provisioned earlier remains bound and that the test pod can still read and write to the mounted CephFS volume.
Verify that the CephFS-backed PersistentVolumeClaim is bound.
Output:
Verify that the CephFS test pod is running.
Output:
Create a validation file inside the mounted CephFS volume.
Verify that the file exists.
Output:
Confirm that the NFS-Ganesha export created earlier is still registered and that the underlying service remains reachable.
Verify that the NFS export is available through the Ceph NFS service.
Output:
Verify that the NFS service is running.
Output:
Confirm that the snapshot and restore workflow completed successfully and that both the original and restored volumes remain available.
Verify that the CephFS snapshot is ready.
Verify that the restored PersistentVolumeClaim is bound.
Output:
Confirm that the Ceph Dashboard and Grafana remain available and that the cluster continues reporting a healthy status after the storage operations performed throughout this article.
Verify that the Ceph Dashboard service is running.
Verify that the Grafana pod is running.
Output:
Verify that the Ceph cluster remains healthy after all storage operations.
This section outlines the strategy for migrating workloads from GCP Filestore to CephFS on Kubernetes. It focuses on the concepts and the tools involved so the approach stays applicable as environments and tooling versions change. Refer to the current GCP Filestore and Rook/Ceph CephFS documentation for the exact commands and configuration options before planning your migration.
Data migration copies the existing data set from the Filestore NFS export to CephFS while preserving file permissions and ownership. Because both Filestore and the CephFS NFS-Ganesha export present a standard NFS interface, a client that mounts both file systems can transfer data between them with a general-purpose tool such as rsync. Mount the Filestore export and the CephFS export on the same client, then run rsync in archive mode (rsync -avh) so it preserves ownership, permissions, symbolic links, and timestamps during the copy. For large data sets, parallelize the transfer by running rsync from multiple clients against different subdirectories, or copy the data into a pod that has the CephFS PersistentVolumeClaim mounted.
Application migration redirects Kubernetes workloads from Filestore-backed storage to CephFS. Because CephFS provides the same POSIX and ReadWriteMany semantics that Filestore offers, most applications continue to work without code changes. Update each workload's PersistentVolumeClaim to reference the cephfs-storage StorageClass instead of the Filestore StorageClass (for example, filestore-rwx), then recreate the PersistentVolumeClaim and restart the workload so it binds to the new CephFS volume. For applications that run outside Kubernetes, repoint the NFS mount target at the CephFS NFS-Ganesha export instead of the Filestore endpoint, using the same mount -t nfs command shown earlier in this article.
Kubernetes CSI VolumeSnapshot resources are the CephFS equivalent of Filestore snapshots. After the CSI snapshot controller and the cephfs-snapshotclass are in place, point-in-time snapshots of any CephFS PersistentVolumeClaim are created by referencing the claim from a VolumeSnapshot resource, as shown earlier in this article. If the existing environment uses scheduled Filestore backups, recreate the schedules with a Kubernetes CronJob or an external backup automation tool, and store long-term copies in an object storage backend.
GCP Filestore manages capacity expansion automatically, while CephFS requires manual OSD expansion and replication planning as storage usage grows. Plan capacity across the Ceph cluster based on expected workload patterns.
The following items require attention during the migration window:
You have deployed CephFS on a Kubernetes Engine cluster using the Rook operator and configured shared persistent storage for Kubernetes workloads. The setup includes dynamic CephFS volume provisioning, NFS exports using NFS-Ganesha, CSI snapshot and restore operations, CephX authentication, monitoring with the Ceph Dashboard and Grafana, and migration guidance from GCP Filestore. This configuration provides a scalable and self-managed distributed storage platform for containerized applications running on Kubernetes. For additional configuration options and production best practices, refer to the Rook documentation and Ceph documentation.
0 Comments
Be the first to comment and share your perspective with the community.