<a id="co-migrate-kraft-prerequisites-v2"></a>

# KRaft Migration Prerequisites

Before you migrate from ZooKeeper to KRaft with Confluent for Kubernetes, verify that your
deployment meets the prerequisites.

#### IMPORTANT
Before you start the KRaft migration, upgrade the Confluent for Kubernetes operator to
version 3.3.0 or later. It adds reliability features for migration,
including Custom Resource (CR) lock enforcement, preflight validations,
expanded rollback support for the `SETUP` and `MIGRATE` phases, and
the `kubectl confluent cluster kraft-migration` command.

<a id="co-migrate-kraft-requirements-v2"></a>

## Confluent Platform version

You need Confluent Platform 7.6 or later.

Check your version:

```bash
# Check the Confluent Platform version
kubectl get kafka <kafka-cr-name> -n <namespace> -o jsonpath='{.status.currentClusterVersion}'
```

Expected:

```text
7.9
```

## CFK version

You need one of the following CFK versions:

* 2.9.2 or later in the 2.9.x branch
* 2.10.x or later

Check your installed version:

```bash
# Check the CFK version
helm list -n <operator-namespace>
```

Expected:

```text
NAME                NAMESPACE             REVISION  UPDATED      STATUS    CHART                                     APP VERSION
confluent-operator  <operator-namespace>  1         <timestamp>  deployed  confluent-for-kubernetes-<chart-version>  3.2.2
```

In the output, the `CHART` column shows the Helm chart name and version, and
the `APP VERSION` column shows the CFK release. Ensure the `APP VERSION`
matches one of the supported CFK versions listed earlier in this section.

#### NOTE
Migrating a two-and-a-half datacenter (2.5DC) topology requires CFK 3.3.0
or later. For details, see [Two-and-a-half datacenter (2.5DC) considerations](#co-migrate-kraft-2-5dc-considerations-v2).

## RBAC requirements

If RBAC is enabled, verify that the principal configured in
`dependencies.mdsKafkaCluster.authentication` on the KRaftController CR is
listed as a super user in both the Kafka and KRaftController CRs. The
`SystemAdmin` role alone is not enough for migration.

<a id="co-migrate-kraft-plugin-setup-v2"></a>

## Confluent plugin

The Confluent plugin provides `kubectl confluent` commands that simplify
the migration and is available in CFK 3.2.2 or later. To use these commands,
verify the plugin is installed. If it is not installed, see
[Install Confluent plugin using Krew](co-deploy-cfk.md#co-install-plugin-using-krew).

```bash
kubectl confluent cluster kraft-migration --help
```

#### IMPORTANT
Keep the Confluent plugin and Confluent operator at the same version.

The plugin uses the following syntax. The alias is `kmj`:

```bash
kubectl confluent cluster kraft-migration <subcommand> [flags]
```

<a id="co-migrate-kraft-preflight-prereq-v2"></a>

## ZooKeeper metadata preflight check

Confluent recommends enabling the ZooKeeper metadata preflight check for
single-cluster migrations. The check validates ZooKeeper metadata state before
migration and catches issues that have
caused migration failures. The check runs the Confluent Platform KRaft migration tool. For
details about the tool, see [KRaft migration tool](https://docs.confluent.io/platform/current/installation/migrate-zk-kraft.html#migration-tool).
To use it, you need:

* Confluent Platform 7.7.9 or later.
* CFK 2.9.10 or later.
* An `init` container image of 2.9.10 or later, because the check depends on
  the `kafka-migration-check` binary that ships in the `init` container.

#### NOTE
Do not enable this check for MRC deployments.

To enable the check for single-cluster migrations, see [Step 3.2: Enable the ZooKeeper metadata preflight check](co-migrate-kraft-procedure.md#co-migrate-kraft-enable-preflight-v2).

## Confluent CRDs match the operator version

CFK does not upgrade CRDs automatically when you upgrade the operator.
Stale CRDs can cause migration to fail in confusing ways, for example,
missing fields on the `KRaftController` or `KRaftMigrationJob` CR, or
admission policies that do not exist in your cluster. Before starting the
migration, reinstall the CRDs from the same CFK version you upgraded to.
For details, see [Install Confluent CRDs](co-prepare.md#co-crd-install).

<a id="co-migrate-kraft-enforce-cr-locks-v2"></a>

## CR lock enforcement

During migration, CFK locks the Kafka, ZooKeeper, and `KRaftController` CRs with
the `platform.confluent.io/kraft-migration-cr-lock=true` annotation to
prevent accidental modifications or deletions. Only the CFK operator service
account can modify locked CRs. CFK denies `UPDATE` and `DELETE` on these
CRs for all other users.

How CFK enforces the lock depends on your versions and configuration, which
CFK auto-detects at Helm install or upgrade. Confirm which case applies to
your setup:

* **Confluent for Kubernetes 3.2.2 or later on Kubernetes 1.30 or later (default)**

  ValidatingAdmissionPolicy (VAP) is active when Kubernetes is 1.30 or later
  and `vapPolicies.enabled: true`. Verify with:
  ```bash
  kubectl get validatingadmissionpolicies | grep kraft-migration
  ```

  Expected:
  ```text
  cfk-kraft-migration-cr-lock-confluent   1   <unset>   5h14m
  ```

  The policy name follows the pattern
  `cfk-kraft-migration-cr-lock-<operator-namespace>`. The preceding example
  shows the `confluent` namespace.

  To disable VAP, set `vapPolicies.enabled: false` during Helm install or
  upgrade.
* **Older Confluent for Kubernetes versions or when VAP is disabled**

  The validating webhook is the automatic fallback when the VAP API is
  unavailable or VAP is disabled. Verify with:
  ```bash
  kubectl get validatingwebhookconfigurations | grep confluent
  ```

  Expected:
  ```text
  confluent-operator-validating-webhook-configuration
  ```
* **Deployments without webhooks or VAP**

  If your deployment has neither enabled, ensure no other actor updates or
  deletes ZooKeeper, Kafka, and KRaft resources during migration. Other actors
  include continuous integration and continuous delivery (CI/CD) tools such as
  GitOps or FluxCD.

To make an emergency change to a locked CR during migration, see
[Bypass CR locks for emergency changes](co-migrate-kraft-troubleshooting.md#co-migrate-kraft-bypass-cr-locks-v2) on the troubleshooting page.

## Pre-migration backup

Take a backup of your Kafka, ZooKeeper, and any related CRs before you start.
Export the CR YAML files so you can restore the configuration if you need
to roll back.

```bash
kubectl get zookeeper <zookeeper-name> -n <namespace> -o yaml > zookeeper-backup.yaml
kubectl get kafka <kafka-name> -n <namespace> -o yaml > kafka-backup.yaml
```

Also back up ZooKeeper persistent data through your standard process, for
example, a PVC snapshot. After finalization, you cannot recover the ZooKeeper
state.

<a id="co-migrate-kraft-mrc-zookeeper-connect-v2"></a>

## Multi-region cluster considerations

A multi-region cluster (MRC) is a Kafka deployment that spans more than one
Kubernetes cluster or region, with one `KRaftController` quorum per
region. In CFK 3.3.0 and later, CFK derives the ZooKeeper endpoint for each
region using Kafka, so no manual `zookeeper.connect` configuration is
required in the `KRaftController`.

<a id="co-migrate-kraft-2-5dc-considerations-v2"></a>

## Two-and-a-half datacenter (2.5DC) considerations

A two-and-a-half datacenter (2.5DC) topology has a 0.5DC that runs
ZooKeeper and KRaft controllers but no Kafka brokers. Migrating the 0.5DC requires
CFK 3.3.0 or later, which introduces the lite-mode `KRaftMigrationJob`.

Because the 0.5DC has no Kafka CR, plan for the following before you migrate:

* Set the ZooKeeper endpoint directly on the 0.5DC `KRaftController`, because CFK
  cannot derive it from a local Kafka CR.
* Fetch the cluster ID from an existing Kafka broker and set `spec.clusterID`
  manually on the 0.5DC `KRaftController`. An incorrect cluster ID blocks
  migration across all datacenters. For details, see
  [Known Issues in ZooKeeper to KRaft Migration](co-migrate-kraft-known-issues.md#co-migrate-kraft-known-issues-v2).
* Migrate the 0.5DC with a lite-mode `KRaftMigrationJob`.

For the configuration and steps, see
[Migrate a multi-region cluster](co-migrate-kraft-mrc.md#co-migrate-kraft-mrc-0-5dc-v2).

<a id="co-migrate-kraft-annotation-conventions-v2"></a>

## Migration command conventions

KRaft migration is driven entirely by annotations on the `Kafka`,
`KRaftController`, `Zookeeper`, and `KRaftMigrationJob` CRs. The
rollback and release-lock annotations are re-applied during the procedure,
so those commands include `--overwrite`.

The commands use two distinct namespace placeholders. Substitute the
correct value for each:

`<namespace>`
: The namespace where your Kafka, ZooKeeper, and KRaftController CRs run.

`<operator-namespace>`
: The namespace where CFK is installed (`confluent` by default). This
  might be the same as `<namespace>` or different, depending on how you
  installed CFK. Use `<operator-namespace>` only when the command
  targets the operator itself, such as `helm list` or
  `kubectl logs deployment/confluent-operator`.

## Next steps

After you complete the prerequisites, start the migration by following the
[migration procedure](co-migrate-kraft-procedure.md#co-migrate-kraft-procedure-v2).
