Skip to main content
This guide covers how the operator provisions persistent storage for a ClickHouseCluster: the primary data volume, attaching extra disks in a multi-disk (JBOD) layout, expanding capacity, and the rules that govern what you can and cannot change after a cluster exists. For the field-by-field reference, see Configuration → Storage configuration and the API Reference.

Primary data volume

spec.dataVolumeClaimSpec is a standard Kubernetes PersistentVolumeClaimSpec. The operator turns it into a StatefulSet volumeClaimTemplate, so the StatefulSet controller creates and retains one PersistentVolumeClaim per replica and mounts it at the ClickHouse data path /var/lib/clickhouse.
  • When accessModes is omitted, the operator defaults it to ReadWriteOnce.
  • The per-replica PVC is retained when the cluster is deleted, so data survives a delete-and-recreate of the Custom Resource.
  • The same field exists on KeeperCluster and behaves the same way.

Running without a persistent data volume

dataVolumeClaimSpec is optional. If you omit it and do not mount your own volume at the data path, ClickHouse writes to the container’s ephemeral filesystem and the admission webhook returns a warning that data may be lost if the cluster is restarted. This is intended only for throwaway or test clusters. To supply your own storage instead of dataVolumeClaimSpec — for example an emptyDir or a pre-provisioned volume — define it through spec.podTemplate.volumes and mount it at /var/lib/clickhouse with spec.containerTemplate.volumeMounts.
dataVolumeClaimSpec and a custom volume at the data path are mutually exclusive. If dataVolumeClaimSpec is set, mounting a custom volume at /var/lib/clickhouse is rejected. The reserved volume names clickhouse-storage-volume, clickhouse-server-tls-volume, and clickhouse-server-custom-ca-volume cannot be used in podTemplate.volumes.

Expanding storage

To grow a volume, increase resources.requests.storage and apply the change. The operator updates the existing PVCs in place.
Expansion only works when the underlying StorageClass has allowVolumeExpansion: true. Kubernetes does not support shrinking a PVC, so the new size must be greater than or equal to the current size.

Multi-disk (JBOD) storage

spec.additionalVolumeClaimTemplates attaches extra disks to each ClickHouse replica on top of the primary dataVolumeClaimSpec. Each entry is a named PVC template — a metadata.name plus a PVC spec — reconciled exactly like the primary data disk, so the StatefulSet controller creates and retains one PVC per replica named <name>-<statefulset>-0.
The operator mounts each additional volume at /var/lib/clickhouse/disks/<name> and generates the ClickHouse storage_configuration for you — you do not write it by hand. It registers every additional disk and adds it to the built-in default storage policy. The primary data disk (default) and every additional disk share a single volume of the default policy, so ClickHouse spreads new data parts across all of them in round-robin fashion. Usable capacity is the sum of all disks, and every table that does not set its own storage_policy — including system.* tables — uses the combined set.
The mount path keeps the template name verbatim, but the disk identifier inside storage_configuration replaces hyphens with underscores. A template named cold-disk is mounted at /var/lib/clickhouse/disks/cold-disk and appears as cold_disk in the generated configuration.

Custom storage policies

You do not need extraConfig for the JBOD layout above — the operator generates the default policy automatically. Reach for spec.settings.extraConfig only when you want storage policies beyond the generated default, for example a tiered hot/cold policy with move_factor and prefer_not_to_merge, or an S3-backed disk. Configuration you add there is merged on top of the generated storage_configuration. See the ClickHouse storage documentation for the policy fields.

What you cannot change after creation

Storage layout is largely fixed once a cluster exists. The admission webhook rejects updates that would orphan or rebind PersistentVolumeClaims:
  • The presence of dataVolumeClaimSpec is immutable — you cannot add a data volume to a cluster created without one, nor remove it from a cluster created with one.
  • The set of additionalVolumeClaimTemplates is fixed — you cannot add, remove, or rename entries after creation.
  • Expanding resources.requests.storage on an existing entry is allowed (subject to StorageClass support, see Expanding storage).

Validation reference

Last modified on June 23, 2026