K8s环境中KRaft控制器启动失败问题排查求助
Kafka KRaft从ZooKeeper迁移启动失败问题
问题背景
我们在K8s环境中手动执行从ZooKeeper到Kafka KRaft的迁移,第一步是部署迁移模式的KRaft控制器,通过ConfigMap提供启动所需的controller.properties配置。
所用ConfigMap配置
--- apiVersion: v1 kind: ConfigMap metadata: name: kraft-controller-config namespace: cgbu-ums-dev data: controller.properties: | zookeeper.metadata.migration.enable=true zookeeper.connect=zookeeper:2181 process.roles=controller node.id=0 controller.quorum.voters=0@kraft-controller-0.kraft-controller:9092 #controller.quorum.bootstrap.servers=kraft-controller:9092 listeners=CONTROLLER://kraft-controller-0:9092 advertised.listeners=CONTROLLER://kraft-controller-0:9092 controller.listener.names=CONTROLLER num.network.threads=3 num.io.threads=8 socket.send.buffer.bytes=102400 socket.receive.buffer.bytes=102400 socket.request.max.bytes=104857600 log.dirs=/var/lib/kafka/data/kraft-controller-0 num.partitions=1 num.recovery.threads.per.data.dir=1 offsets.topic.replication.factor=1 transaction.state.log.replication.factor=1 transaction.state.log.min.isr=1 share.coordinator.state.topic.replication.factor=1 share.coordinator.state.topic.min.isr=1 log.retention.hours=168 log.segment.bytes=1073741824 log.retention.check.interval.ms=300000
启动报错信息
[2025-05-06 05:25:13,768] ERROR Encountered fatal fault: exception while completing controller activation (org.apache.kafka.server.fault.ProcessTerminatingFaultHandler) java.lang.RuntimeException: Should not have ZK migrations enabled on a cluster that was created in KRaft mode. at org.apache.kafka.controller.ActivationRecordsGenerator.recordsForNonEmptyLog(ActivationRecordsGenerator.java:168) at org.apache.kafka.controller.ActivationRecordsGenerator.generate(ActivationRecordsGenerator.java:234) at org.apache.kafka.controller.QuorumController$CompleteActivationEvent.generateRecordsAndResult(QuorumController.java:1243) at org.apache.kafka.controller.QuorumController$ControllerWriteEvent.run(QuorumController.java:791) at org.apache.kafka.queue.KafkaEventQueue$EventContext.run(KafkaEventQueue.java:132) at org.apache.kafka.queue.KafkaEventQueue$EventHandler.handleEvents(KafkaEventQueue.java:215) at org.apache.kafka.queue.KafkaEventQueue$EventHandler.run(KafkaEventQueue.java:186) at java.base/java.lang.Thread.run(Thread.java:842)
排查过程
最初先启动了无迁移配置的KRaft控制器,启动成功后修改ConfigMap添加迁移配置并执行kubectl rollout restart,重启时出现相同错误。推测是Pod先以纯KRaft模式启动,后续启用迁移时log.dir目录下已有纯KRaft模式生成的元数据,导致迁移模式启动失败。现在直接启用迁移配置启动,仍出现该错误,需要排查问题原因并获取解决方法。
补充ZooKeeper配置
env: - name: ZK_REPLICAS value: "3" - name: ZK_CLIENT_PORT value: "2181" - name: ZK_SERVER_PORT value: "2888" - name: ZK_ELECTION_PORT value: "3888" - name: ZK_TICK_TIME value: "2000" - name: ZK_INIT_LIMIT value: "10" - name: ZK_SYNC_LIMIT value: "5" - name: ZK_MAX_CLIENT_CNXNS value: "500" - name: ZK_SNAP_RETAIN_COUNT value: "3" - name: ZK_PURGE_INTERVAL value: "0" - name: LOG4J_FORMAT_MSG_NO_LOOKUPS value: "true"
问题原因
报错提示明确说明:不能在KRaft模式创建的集群上启用ZK迁移,核心原因是log.dirs目录下已经存在纯KRaft模式生成的元数据文件(比如集群ID、控制器日志等),即使后续修改配置启用迁移,Kafka会识别到该目录属于纯KRaft集群,拒绝执行ZK迁移流程。
解决方法
清理KRaft控制器的存储目录
- 如果使用PersistentVolumeClaim(PVC)挂载
/var/lib/kafka/data/kraft-controller-0,需删除对应PVC和PersistentVolume(PV),或直接清理PV中的数据。 - 执行命令删除旧控制器Pod并清理存储:
kubectl delete pod kraft-controller-0 -n cgbu-ums-dev kubectl delete pvc <kraft-controller-pvc-name> -n cgbu-ums-dev - 确保重新部署时使用全新的空存储目录。
- 如果使用PersistentVolumeClaim(PVC)挂载
严格遵循ZK到KRaft的迁移流程
- 正确步骤:
- 确保原ZooKeeper集群正常运行,原ZK模式Kafka集群处于可用状态。
- 部署KRaft控制器时必须直接启用迁移配置,禁止先以纯KRaft模式启动。
- 启动迁移模式控制器后,根据Kafka版本,要么等待自动执行元数据迁移,要么手动运行
kafka-metadata-migrate.sh工具完成迁移。 - 验证迁移完成后,再逐步切换Kafka Broker到KRaft模式。
- 正确步骤:
检查配置细节
- 确认
zookeeper.connect配置正确指向ZooKeeper集群服务地址,确保KRaft控制器能正常访问ZK。 - 确保
controller.quorum.voters配置的节点地址在K8s集群内可解析(当前配置0@kraft-controller-0.kraft-controller:9092符合Headless Service地址格式,无需调整)。
- 确认
内容的提问来源于stack exchange,提问作者BloodFury
相关产品推荐
相关产品推荐

