Kubernetes storage · object, block & file · Netherlands

Object, block, and file storage for Kubernetes and OpenShift.

Three storage types across four locality tiers, provisioned as Kubernetes objects through CSI drivers. Applications request storage with a PersistentVolumeClaim or an ObjectBucketClaim; the platform provisions, binds, and attaches it. Every tier uses the same interface, so moving between them is a StorageClass change, not an application change.

Dynamic provisioning · snapshots and clones · online volume expansion · S3 over HTTPS.

Why storage types differ

A database needs exclusive, low-latency access to a raw device it manages itself. A group of web servers needs one directory tree mounted read-write on every replica at once. A backup system needs durable, effectively unbounded capacity addressed over HTTP rather than mounted at all.

These are three access contracts, not three quality levels. Choosing the wrong one shows up as a design problem — a filesystem-shaped application forced onto object storage, or shared content serialised behind a single-writer volume — not as a tuning problem.

Why persistence matters

Container filesystems are ephemeral by design: when a pod is rescheduled, anything written inside it is gone. A PersistentVolume decouples the data lifecycle from the pod lifecycle.

That separation is what makes databases, message brokers, virtual machines, and stateful application platforms viable on the same cluster as stateless services.

Storage types

Block, file, and object storage differ in how they are accessed, how many writers they admit, and which tiers they are available at.

Block storage

RWO · RWX-Block for VM disks

A raw volume presented to a single consumer, formatted with whatever filesystem the workload needs. With no shared-access coordination in the I/O path, block storage has the shortest path to disk and the best latency and IOPS characteristics. Access is exclusive — the contract a database expects. VM disks are the exception: they use ReadWriteMany block mode so two nodes can hold the volume open during a live migration.

Access
One pod mounts the volume (block or filesystem)
Sharing
Single writer; RWX block mode for live-migratable VM disks
Latency
Lowest — IOPS and latency oriented
Scale
Per volume; expand online without downtime
Tiers
Local NVMe, replicated NVMe, shared durable
K8s
PersistentVolumeClaim with accessModes: ReadWriteOnce

Typical workloads: PostgreSQL, MySQL and MariaDB, MongoDB, Redis, Elasticsearch hot indices, message brokers, Git repositories, virtual machine disks.

File storage

RWX · shared POSIX

A POSIX filesystem that many pods mount and write to concurrently. A deployment scaled to five replicas can mount the same volume on all five, across different nodes, with normal POSIX semantics — directories, permissions, file locking, rename. Applications that assume a local filesystem keep working unmodified when scaled out. Available at the shared durable tier: a shared namespace requires a shared pool.

Access
Shared filesystem mount across nodes
Sharing
Many writers concurrently (ReadWriteMany)
Latency
Low to moderate; balanced for shared access
Scale
Grows with the shared pool; expandable
Tiers
Shared durable
K8s
PersistentVolumeClaim with accessModes: ReadWriteMany

Typical workloads: shared web document roots, CMS upload directories, shared model and asset directories, home directories, media repositories.

Object storage

S3-compatible · HTTPS

S3-compatible buckets addressed over HTTPS — no volume to size, no filesystem to maintain, no mount to manage. The namespace is flat rather than hierarchical, so it scales without directory-tree overhead, and objects are replaced whole rather than modified in place. Access is over HTTP from anywhere the endpoint is reachable, in or out of the cluster, with no attach step.

Access
S3 API from any client or SDK
Sharing
Any number of concurrent clients, in or out of cluster
Latency
Higher — HTTP request/response; throughput oriented
Scale
Flat namespace, no per-bucket ceiling
Tiers
Shared durable, offsite
K8s
ObjectBucketClaim; endpoint and credentials arrive in a Secret

Typical workloads: backup targets, AI and ML training datasets, model artifacts, CI/CD outputs, registry backing, log archives, media behind a CDN.

Property BlockRWO FileRWX ObjectS3 · HTTPS
InterfaceRaw volume, mountedShared POSIX mountS3 API over HTTPS
Concurrent writersOne per volumeManyMany
NamespaceDeviceHierarchical filesystemFlat, key-addressed
Write granularityBlock-level, in placeFile-level, in placeWhole object
LatencyLowestLow to moderateHigher
Optimised forIOPSBalanced shared accessThroughput and parallelism
Capacity modelPer volume, expandable onlineGrows with the shared poolNo per-bucket ceiling
Reachable outside the clusterNoNoYes, over HTTPS
Available at tiersLocal NVMe · replicated NVMe · shared durableShared durableShared durable · offsite
Kubernetes objectPersistentVolumeClaimPersistentVolumeClaimObjectBucketClaim
Best forDatabases, VM disks, brokersShared web roots, uploads, assetsBackups, datasets, artifacts, logs

Storage tiers

Storage sits at some distance from the compute using it, and that distance sets the trade between latency and durability. Four tiers are exposed rather than one blended tier, so each workload can be placed deliberately.

tier 01 · node-local

Local NVMe

Direct-attached NVMe on the node running the workload. No network hop, no replication: the volume is pinned to one node and its data does not survive that node’s disk. Durability comes from the application layer.

Block only
tier 02 · cluster-local

Replicated NVMe

Local NVMe on the cluster’s own storage nodes, replicated across nodes and exported over an NVMe-oF fabric. Near-local performance with replica durability, so a volume survives a node move. Scoped to one cluster.

Block only
tier 03 · datacenter

Shared durable

A shared, replicated pool serving all three storage types, expandable independently of any consumer cluster. The default tier, and the only one offering snapshots, clones, ReadWriteMany, and online expansion.

Object · block · file
tier 04 · global

Offsite object

Geo-remote S3 behind the same bucket interface as on-site object storage. Data here survives the loss of an entire location, which makes it the destination for disaster-recovery copies and long-retention backups.

Object only
◀ Lower latency Higher durability & features ▶

Choosing a tier. Moving down the spectrum adds durability and features at a latency cost; moving up trades durability for raw speed. Because every tier is addressed through the same PVC or ObjectBucketClaim interface, the choice is a StorageClass value rather than an architectural commitment. Geo-redundancy is available today through the offsite object tier; multi-datacenter replication of the shared durable tier is on the roadmap, not a current capability.

Architecture and Kubernetes integration

Storage is consumed entirely through standard Kubernetes objects. No portal step and no provider-specific API sits between an application manifest and a provisioned volume.

Applications and workloads

DatabasesVirtual machines AI / MLCMS and content CI/CD and backup tooling

Kubernetes / OpenShift

PersistentVolumeClaim PersistentVolume ObjectBucketClaim CSI drivers

StorageClasses · dynamic provisioning

Local NVMeReplicated NVMe Shared durableOffsite object

Storage types

Block
RWO volumes · VM disks
File
Shared POSIX filesystem
Object
S3 buckets over HTTPS

Storage platform · Netherlands

Replicated, snapshot-capable pools EU jurisdiction, GDPR 100% renewable energy

How provisioning works

Each tier and storage type is published as a StorageClass naming a CSI provisioner and its parameters. Selecting a StorageClass is how a workload selects a tier; the classes available to your account are listed in the console when you create a volume.

  • PersistentVolumeClaim — a namespaced request for capacity, access mode, and StorageClass. It lives with the application manifests and moves with them through GitOps.
  • PersistentVolume — the provisioned volume, a cluster-scoped object bound one-to-one to its claim, with a lifecycle independent of any pod.
  • Dynamic provisioning — naming a StorageClass causes the CSI provisioner to create backing storage and a matching PV and bind them, with no pre-provisioning step.
  • CSI drivers — the standard contract between Kubernetes and a storage backend, so snapshots, clones, expansion, and topology-aware scheduling behave as the upstream documentation describes, and manifests stay portable.
  • Stateful applications — a StatefulSet’s volumeClaimTemplates gives each replica its own volume, reattached to the same ordinal after rescheduling.
pvc.yaml
# A single-writer block volume for a database
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-data
spec:
  storageClassName:    # selects the tier
  accessModes: [ ReadWriteOnce ]
  resources:
    requests:
      storage: 50Gi

# Expand later — online, no unmount:
# kubectl patch pvc postgres-data \
#   -p '{"spec":{"resources":{"requests":{"storage":"100Gi"}}}}'

Data services

What each service protects against, and where it applies.

Replication

Redundancy is a property of the tier. Local NVMe does not replicate — durability is delegated to applications that keep their own copies. The replicated-NVMe and shared durable tiers keep replicas so a volume survives node loss. Object storage adds server-side replication between buckets, including to the offsite tier.

Snapshots and clones

Point-in-time copies as standard VolumeSnapshot objects, restorable into a new PVC. A PVC can also be cloned from another PVC, producing a disposable copy of production data without a full restore cycle. Being Kubernetes objects, both are drivable from CI and GitOps. Available at the shared durable tier.

Backup and disaster recovery

Snapshots protect against logical error and live alongside the source data; backups protect against loss of the source location. The offsite object tier is the destination for backup copies, and any tool that speaks S3 can target it. Scheduling, retention, and restore orchestration are functions of the backup tool you run.

Online expansion

Volumes grow by editing the capacity request on the PVC. The CSI driver expands the backing volume and the filesystem in place — no unmount, no migration, no downtime window. Object buckets have no fixed size and need no expansion step.

Encryption

Object storage supports server-side encryption applied as a bucket policy, and all access to object storage is over HTTPS. Encryption requirements for block and file volumes, including encryption at rest and customer-managed keys, are scoped per environment — discuss them with an architect before designing against a specific model.

Compression

Object storage supports server-side compression as a bucket policy, reducing stored capacity for compressible content such as logs, text corpora, and build artifacts. It trades a little CPU on write for capacity on disk; for already-compressed content such as video, leave it off.

Storage and compute

Storage is a shared platform service rather than a per-product feature. The same tiers and types back every compute model.

Virtual machines

VM disks are block volumes, provisioned as PVCs like any other storage, usually on the shared durable tier so they are replicated and snapshot-capable independently of the hypervisor node. Live migration uses ReadWriteMany block-mode volumes: source and destination nodes hold the volume open together, so a running VM relocates without detaching its disk. That is what makes node maintenance possible without scheduling VM downtime.

Containers

Stateless services need no storage. Stateful ones declare a PVC, or — for a StatefulSet — a volumeClaimTemplate producing one volume per replica, reattached to the same ordinal after rescheduling. The CSI driver handles attach, mount, and detach as pods move. Access mode is the main design decision: ReadWriteOnce for anything that owns its data, ReadWriteMany only where replicas genuinely share a tree.

Event-driven and scale-to-zero

Scale-to-zero workloads are stateless by construction: they hold nothing between invocations and must not assume a volume is mounted. State belongs in an external service — object storage for payloads and artifacts, a database on block storage for transactional state. Object storage suits this well, because an S3 endpoint is reachable over HTTP with no attach step, so a function starting cold can read and write immediately.

GPU and AI workloads

GPU training is usually throughput-bound on the data path rather than capacity-bound, so the pattern is tiered: hold the corpus in object storage, where it is durable and shareable across clusters, and stage the working set onto replicated NVMe for the run. Checkpoints are written to fast NVMe during training and promoted to object storage for retention; model artifacts are versioned in buckets and pulled onto block storage for serving. The same buckets act as the handoff between pipeline stages.

Recommended storage type by workload

A starting point with the reasoning attached, so it can be adapted to your own replication and recovery requirements.

WorkloadStorage typeReasoning
PostgreSQL, MySQL, MariaDBBlockSingle-writer RWO volume. Operator-replicated clusters can use local NVMe and let the database own durability; standalone instances belong on shared durable block.
Microsoft SQL ServerBlockSingle-writer volume with low-latency requirements. Shared durable block for platform-managed durability.
MongoDBBlockOne volume per replica-set member via volumeClaimTemplates. The replica set provides durability, so the faster local tiers fit well.
RedisBlockFast RWO volume for AOF or RDB persistence. Local NVMe when it is a cache the application can rebuild.
ElasticsearchBlock ObjectHot indices on block for IOPS; roll cold segments out to object storage for retention.
NextcloudFile ObjectUser files on RWX file or S3 primary storage, database on block, backups to the offsite tier.
GitLabBlock ObjectRepositories and database on block; LFS objects, CI artifacts, and container registry on object storage.
JenkinsBlock ObjectController home directory on block; build artifacts and caches to object storage.
AI training datasetsObject BlockCorpus in buckets for durability and sharing; working set staged on replicated NVMe for the run.
Kubernetes loggingObjectHot index on fast block; long-term segments and archives on object storage.
Object backup repositoryObjectOffsite tier, so a copy survives loss of the whole location.
Virtual machine hostingBlockRWO for standard disks; RWX block mode where live migration is required.

Platform characteristics

What each property means in operational terms.

CharacteristicWhat it means technically
High availabilityReplicated pools at the cluster and datacenter tiers keep volumes available through node loss. Object endpoints are load-balanced across gateways.
ScalabilityCapacity is added by adding disks and servers to the pool, with no reconfiguration on the consumer side. Object capacity, block capacity, and fast NVMe scale independently.
ResiliencyDurability is selected per workload, from application-replicated local NVMe through to a geo-remote copy at the offsite tier.
AutomationProvisioning, snapshotting, cloning, and expansion are Kubernetes API operations, drivable from GitOps controllers and CI pipelines.
Kubernetes-nativePersistentVolumeClaims, StorageClasses, VolumeSnapshots, and ObjectBucketClaims — no separate storage management plane to operate.
API-driven provisioningThe Kubernetes API and the S3 API are the interfaces. Manifests remain portable to any conformant cluster.
Self-serviceTeams provision storage from their own namespaces within their quota, without a platform-team request.
Multi-tenancyTenants are isolated at the StorageClass and namespace level. Dedicated-cluster customers can run storage inside their own cluster or consume the shared pool.
Data sovereigntyDutch datacenters under EU jurisdiction, with a GDPR data processing agreement as standard and no US Cloud Act exposure.
Sustainability100% renewable energy, with server heat reused to warm nearby greenhouses and buildings.

Common questions

Is the object storage genuinely S3-compatible?

Yes. Buckets are addressed through the standard S3 API, so existing SDKs and tools work unchanged. Provision one with an ObjectBucketClaim and the endpoint, bucket name, and credentials arrive in a generated ConfigMap and Secret.

Can I move a workload between tiers later?

Yes, but it is a data migration rather than a live change. A PersistentVolume’s StorageClass is fixed at provisioning, so moving tiers means provisioning a new volume on the target class and copying the data across — for a StatefulSet, updating the template and rolling the replicas. The application code does not change; the StorageClass value and the copy step do.

What happens to my data if a node fails?

It depends on the tier. Volumes on local NVMe are lost with the node’s disk, which is why that tier is reserved for workloads that replicate themselves. Volumes on the replicated-NVMe and shared durable tiers have replicas elsewhere and are reattached when the pod is rescheduled.

Is there vendor lock-in?

No proprietary interface sits between you and your data. Storage is consumed through CSI, PersistentVolumeClaims, and the S3 API — all portable standards. Manifests move to any conformant Kubernetes cluster, and buckets are reachable with any S3 client.

Match the storage to the workload.

Object, block, and file across four locality tiers, provisioned as Kubernetes objects, in EU-owned datacenters running on 100% renewable energy.