
Why?
GCS offer quite a few benefits over traditional block storage. To highlight a few (thanks ChatGPT):
- Scalability: GCS buckets are highly scalable, allowing you to store virtually unlimited amounts of data.
- Durability: GCS is designed for long-term storage and offers robust data durability with automatic replication and redundancy.
- Cost-Effective: GCS offers flexible pricing models, including tiered storage classes, making it cost-effective for various data storage needs.
- Security and Access Control: GCS provides strong security features, including encryption, access controls, and identity and access management (IAM).
- Versioning and Lifecycle Management: GCS provides built-in versioning and lifecycle management features, allowing you to manage data retention policies and recover previous versions of files.
Common use cases for these buckets include storing application data, such as static HTML files and images for websites. Since the bucket can be mounted by multiple pods simultaneously, it also facilitates data sharing among them.
You cannot, however, use GCS buckets for applications requiring extremely low latency and high IOPS (Input/Output Operations Per Second), databases or any other application design for object storage.
How?
There are three parts to this section:
- enable the fuse plugin
- create the bucket
- mount the bucket.
Enable CSI Fuse
Assuming you’ve done the smart thing and you built the GKE cluster using this terraform module, it should be as simple as adding the option
gcs_fuse_csi_driver = true
Create
locals {
app_namespace = "my-k8s-app-namespace"
app_sa = "my-cool-app-service-account"
}
resource "google_storage_bucket" "app" {
name = "my-app-bucket-${var.project}"
location = "EU"
uniform_bucket_level_access = true
}
resource "google_storage_bucket_iam_binding" "bucket_access" {
bucket = google_storage_bucket.app.name
role = "roles/storage.admin"
members = [
"principal://iam.googleapis.com/projects/${google_storage_bucket.app.project_number}/locations/global/workloadIdentityPools/${google_storage_bucket.app.project}.svc.id.goog/subject/ns/${local.app_namespace}/sa/${local.app_sa}"
]
}
You’ll need to know in advance the namespace where you will be deploying the application and the name of the service account it’s going to use.
Mount
Finally, we just need a couple of tweaks to the application for it to work.
- Annotation
gke-gcsfuse/volumes: "true"
Add the following annotation to the deployment or statefulset:
- Volume
Add the volume confg like
- name: gcs-fuse-csi-ephemeral
csi:
driver: gcsfuse.csi.storage.gke.io
readOnly: false
volumeAttributes:
bucketName: my-app-bucket-PROJECT
mountOptions: "implicit-dirs"
gcsfuseLoggingSeverity: warning
- Mount the volume to the pods
volumeMounts:
- name: gcs-fuse-csi-ephemeral
mountPath: /data
readOnly: false
Full Example
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: website
name: website
spec:
replicas: 1
selector:
matchLabels:
app: website
strategy: {}
template:
metadata:
annotations:
gke-gcsfuse/volumes: "true"
labels:
app: website
spec:
containers:
- image: ubuntu:24.04
name: ubuntu
command: ["sleep", "infinity"]
resources: {}
volumeMounts:
- name: gcs-fuse-csi-ephemeral
mountPath: /data
readOnly: false
- name: gcs-fuse-csi-ephemeral
csi:
driver: gcsfuse.csi.storage.gke.io
readOnly: false
volumeAttributes:
bucketName: my-app-bucket-PROJECT
mountOptions: "implicit-dirs"
gcsfuseLoggingSeverity: warning
Conclusion
If you want to know more, have a look at the Google Docs:
Access Cloud Storage buckets with the Cloud Storage FUSE CSI driver | Google Kubernetes Engine…
Filesystem in Userspace (FUSE) is an interface used to export a filesystem to the Linux kernel. Cloud Storage FUSE…
cloud.google.com
And if you can’t read, get in touch, and we’ll read it for you. 😄
I hope you enjoy it. Stay safe.
I for one welcome our robot overlords