// Module included in the following assemblies:
//
// assembly-storage.adoc

[id='con-config-storage-zookeeper-{context}']
= Configuring Kafka storage with ZooKeeper

[role="_abstract"]
If you are using ZooKeeper, configure its storage in the `Kafka` resource.
Depending on whether the deployment uses node pools, configure storage for the Kafka cluster in `Kafka` or `KafkaNodePool` resources. 

This section focuses only on ZooKeeper storage and Kafka storage configuration in the `Kafka` resource.
For detailed information on Kafka storage, refer to the section describing xref:con-config-storage-kraft-{context}[storage configuration using node pools]. 
The same configuration options for storage are available in the `Kafka` resource.

NOTE: Replicated storage is not required for ZooKeeper, as it has built-in data replication.

== Configuring ephemeral storage

To use ephemeral storage, specify `ephemeral` as the storage type. 

.Example configuration for ephemeral storage
[source,yaml,subs="attributes+"]
----
apiVersion: {KafkaApiVersion}
kind: Kafka
metadata:
  name: my-cluster
spec:
  kafka:
    storage:
      type: ephemeral
  zookeeper:
    storage:
      type: ephemeral    
    # ...
----

The ephemeral volume used by Kafka brokers for log directories is mounted at `/var/lib/kafka/data/kafka-log<pod_id>`.

IMPORTANT: Ephemeral storage is unsuitable for single-node ZooKeeper clusters or Kafka topics with a replication factor of 1.

== Configuring persistent storage

The same persistent storage configuration options available for node pools can also be specified for Kafka in the `Kafka` resource.
For more information, see the section on xref:con-config-storage-kraft-{context}[configuring Kafka storage using node pools].
The `size` property can also be adjusted to xref:proc-resizing-persistent-volumes-{context}[resize persistent volumes]. 

The storage type must always be `persistent-claim` for ZooKeeper, as it does not support JBOD storage.

.Example configuration for persistent storage 
[source,yaml,subs="attributes+"]
----
apiVersion: {KafkaApiVersion}
kind: Kafka
metadata:
  name: my-cluster
spec:
  kafka:
    storage:
      type: persistent-claim
      size: 500Gi
      deleteClaim: true
  # ...
  zookeeper:
    storage:
      type: persistent-claim
      size: 1000Gi        
----

PVCs created for Kafka pods when storage is configured in the `Kafka` resource use the naming convention `data-<cluster_name>-kafka-<pod_id>`, and the persistent volumes for Kafka logs are mounted at `/var/lib/kafka/data/kafka-log<pod_id>`.

PVCs created for ZooKeeper follow the naming convention `data-<cluster_name>-zookeeper-<pod_id>`.

NOTE: As in KRaft mode, you can also specify custom storage classes and volume selectors.

== Configuring JBOD storage

ZooKeeper does not support JBOD storage, but Kafka nodes in a ZooKeeper-based cluster can still be configured to use JBOD storage.
The same JBOD configuration options available for node pools can also be specified for Kafka in the `Kafka` resource.
For more information, see the section on xref:con-config-storage-kraft-{context}[configuring Kafka storage using node pools].
The `volumes` array can also be adjusted to xref:proc-adding-removing-volumes-{context}[add or remove volumes].

.Example configuration for JBOD storage 
[source,yaml,subs="attributes+"]
----
apiVersion: {KafkaApiVersion}
kind: Kafka
metadata:
  name: my-cluster
spec:
  kafka:
    storage:
      type: jbod
      volumes:
      - id: 0
        type: persistent-claim
        size: 100Gi
        deleteClaim: false
      - id: 1
        type: persistent-claim
        size: 100Gi
        deleteClaim: false
      - id: 2
        type: persistent-claim
        size: 100Gi
        deleteClaim: false
  # ...
  zookeeper:
    storage:
      type: persistent-claim
      size: 1000Gi        
----

== Migrating from storage class overrides (deprecated)

The use of node pools to change the storage classes used by volumes replaces the deprecated `overrides` properties previously used for Kafka and ZooKeeper in the `Kafka` resource. 

.Example storage configuration with class overrides
[source,yaml,subs="attributes+"]
----
apiVersion: {KafkaApiVersion}
kind: Kafka
metadata:
  labels:
    app: my-cluster
  name: my-cluster
  namespace: myproject
spec:
  # ...
  kafka:
    replicas: 3
    storage:
      type: jbod
      volumes:
      - id: 0
        type: persistent-claim
        size: 100Gi
        deleteClaim: false
        class: my-storage-class
        overrides:
        - broker: 0
          class: my-storage-class-zone-1a
        - broker: 1
          class: my-storage-class-zone-1b
        - broker: 2
          class: my-storage-class-zone-1c
      # ...
  # ...
  zookeeper:
    replicas: 3
    storage:
      deleteClaim: true
      size: 100Gi
      type: persistent-claim
      class: my-storage-class
      overrides:
        - broker: 0
          class: my-storage-class-zone-1a
        - broker: 1
          class: my-storage-class-zone-1b
        - broker: 2
          class: my-storage-class-zone-1c
  # ...
----

If you are using storage class overrides for Kafka, we encourage you to transition to using node pools instead.
To migrate the existing configuration, follow these steps:

1. Make sure you already use node pools resources.
   If not, you should xref:proc-migrating-clusters-node-pools-str[migrate the cluster to use node pools] first.
2. Create new xref:config-node-pools-str[node pools] with storage configuration using the desired storage class without using the overrides.
3. Move all partition replicas from the old broker using the storage class overrides.
   You can do this using xref:cruise-control-concepts-str[Cruise Control] or xref:assembly-reassign-tool-str[using the partition reassignment tool].
4. Delete the old node pool with the old brokers using the storage class overrides. 