k8s-csi-s3

Kubernetes CSI driver that mounts S3-compatible buckets as PersistentVolumes using FUSE. Supports s3fs, goofys, and rclone as mount backends.

Install

helm repo add yandex-s3 https://yandex-cloud.github.io/k8s-csi-s3/charts
helm install csi-s3 yandex-s3/csi-s3 --namespace kube-system

Manual Installation:

cd deploy/kubernetes
kubectl create -f provisioner.yaml
kubectl create -f driver.yaml
kubectl create -f csi-s3.yaml

Secret

apiVersion: v1
kind: Secret
metadata:
  name: csi-s3-secret
  namespace: kube-system
stringData:
  accessKeyID: YOUR_ACCESS_KEY
  secretAccessKey: YOUR_SECRET_KEY
  endpoint: https://s3.example.com
  region: us-east-1

StorageClass

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: csi-s3
provisioner: ru.yandex.s3.csi
parameters:
  mounter: geesefs # geesefs | s3fs | rclone
  options: "--memory-limit 1000 --dir-mode 0777 --file-mode 0666"
  csi.storage.k8s.io/provisioner-secret-name: csi-s3-secret
  csi.storage.k8s.io/provisioner-secret-namespace: kube-system
  csi.storage.k8s.io/controller-publish-secret-name: csi-s3-secret
  csi.storage.k8s.io/controller-publish-secret-namespace: kube-system
  csi.storage.k8s.io/node-stage-secret-name: csi-s3-secret
  csi.storage.k8s.io/node-stage-secret-namespace: kube-system
  csi.storage.k8s.io/node-publish-secret-name: csi-s3-secret
  csi.storage.k8s.io/node-publish-secret-namespace: kube-system

PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-s3-pvc
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: csi-s3
  resources:
    requests:
      storage: 5Gi # informational only — S3 has no quota enforcement

PV

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  accessModes:
    - ReadWriteMany
  capacity:
    storage: 100Gi
 
  storageClassName: csi-s3
  persistentVolumeReclaimPolicy: Retain
 
  claimRef:
    apiVersion: v1
    kind: PersistentVolumeClaim
    name: my-pvc
    namespace: ns
 
  csi:
    driver: ru.yandex.s3.csi
 
    controllerPublishSecretRef:
      name: csi-s3-secret
      namespace: kube-system
 
    nodePublishSecretRef:
      name: csi-s3-secret
      namespace: kube-system
 
    nodeStageSecretRef:
      name: csi-s3-secret
      namespace: kube-system
 
    volumeHandle: my-bucket
 
    volumeAttributes:
      capacity: 100Gi
      mounter: geesefs
      options: "--memory-limit 1000 --dir-mode 0777 --file-mode 0666 --no-systemd"

Mounter comparison

MounterNotes
geesefsRecommended; best performance, partial POSIX
s3fsMost compatible; slower
rcloneBroadest S3-compatible support

Caveats

  • Not a real POSIX filesystem — no hard links, limited locking
  • Performance is bound by FUSE overhead and S3 latency
  • Better suited for read-heavy or write-once workloads