Strimzi KRaft 部署实战:基于 KafkaNodePool 构建去 ZooKeeper 化的 Apache Kafka 集群
2026/9/17 8:36:40 网站建设 项目流程

Strimzi KRaft 部署实战:基于 KafkaNodePool 构建去 ZooKeeper 化的 Apache Kafka 集群

【免费下载链接】strimzi-kafka-operatorApache Kafka® running on Kubernetes项目地址: https://gitcode.com/GitHub_Trending/st/strimzi-kafka-operator

本篇技术指南基于 Strimzi 仓库packaging/examples/kafka/目录下的官方示例文档,系统讲解如何在 Kubernetes 上使用 Strimzi 部署 KRaft(ZooKeeper-less)模式的 Apache Kafka 集群。读完本文,你将掌握五种典型拓扑(controller/broker 双池、JBOD 多卷、ephemeral 存储、dual-role 节点、单节点)的完整 YAML 配置方式,理解KafkaNodePoolroles、存储卷kraftMetadata等关键参数语义,并能结合源码级证据验证配置行为。

一、示例目录总览:五种 KRaft 部署拓扑

示例目录 README 明确说明:该目录下的示例演示如何结合 Strimzi 使用 Kraft(去 ZooKeeper 化的 Apache Kafka)。五个示例文件与它们部署的集群形态一一对应:

示例文件部署的集群形态
kafka-persistent.yaml一个KRaft controller节点池 + 一个KRaft broker节点池
kafka-jbod.yaml双节点池,且 broker 池使用多个数据卷(JBOD)
kafka-ephemeral.yaml双节点池 + ephemeral(临时)存储
kafka-with-dual-role-nodes.yaml单个节点池,节点同时承担brokercontroller角色
kafka-single-node.yaml单个 Kafka 节点,同时具备 broker 与 controller 角色

从源码结构看,这一设计与 KRaft 模式下 controller 与 broker 可以运行在不同进程/不同节点(分离部署)或同一进程(双角色部署)的架构选择直接对应;上图中分别示意了双角色节点仲裁(dual-role quorum)与单角色分离部署(single-role quorum)两种形态。

二、核心机制:KafkaNodePool 与 roles 字段

KRaft 示例不再沿用传统的“spec.kafka单池”模式,而是通过自定义资源KafkaNodePoolapiVersion: kafka.strimzi.io/v1)来定义节点池。每个节点池的关键字段为:

  • metadata.labels.strimzi.io/cluster:将节点池关联到对应的Kafka集群资源(示例中统一为my-cluster);
  • spec.replicas:该节点池的节点数量;
  • spec.roles:节点角色列表,可取值controllerbroker(可组合);
  • spec.storage:节点池的存储定义,类型为jbod时以volumes数组列出多个存储卷。

以 kafka-with-dual-role-nodes.yaml 中的节点池为例:

apiVersion: kafka.strimzi.io/v1 kind: KafkaNodePool metadata: name: dual-role labels: strimzi.io/cluster: my-cluster spec: replicas: 3 roles: - controller - broker storage: type: jbod volumes: - id: 0 type: persistent-claim size: 100Gi kraftMetadata: shared

roles同时列出controllerbroker即构成“dual-role 节点”:同一组 Pod 既参与 KRaft 元数据仲裁(quorum),又提供数据平面(replica、分区读写)。而 kafka-persistent.yaml 中的两个节点池则分别只声明- controller- broker,构成 controller 池与 broker 池完全分离的拓扑。

三、示例详解

3.1 分离部署:controller 池 + broker 池(kafka-persistent.yaml)

该文件包含三段资源:controller节点池、broker节点池和一个Kafka集群资源。两个节点池各 3 副本,均使用 100Gi 的persistent-claim卷,并声明kraftMetadata: shared(表示该卷同时承载 KRaft 元数据日志)。

Kafka资源的核心配置如下(完整文件):

apiVersion: kafka.strimzi.io/v1 kind: Kafka metadata: name: my-cluster spec: kafka: version: 4.3.1 metadataVersion: 4.3-IV0 listeners: - name: plain port: 9092 type: internal tls: false - name: tls port: 9093 type: internal tls: true config: offsets.topic.replication.factor: 3 transaction.state.log.replication.factor: 3 transaction.state.log.min.isr: 2 default.replication.factor: 3 min.insync.replicas: 2 entityOperator: topicOperator: {} userOperator: {}

逐项说明:

  • version: 4.3.1:指定 Kafka 版本;metadataVersion: 4.3-IV0指定 KRaft 元数据格式版本。仓库的 KAFKA_VERSION_SUPPORT.md 说明 Strimzi 承诺至少支持 Apache Kafka 最近两个 major/minor 版本,且相邻两个 Strimzi 版本至少共用一个 Kafka 版本以便平滑升级——因此示例中的具体版本号会随 Strimzi 发布滚动更新,以仓库kafka-versions.yaml与当前示例文件为准。
  • listeners:定义两个集群内部监听器。plain(9092 端口)不启用 TLS,适合开发环境或内网低信任要求场景;tls(9093 端口)启用 TLS,由 Strimzi 自动签发集群 CA 证书。type: internal表示通过集群内部 Service 暴露。
  • config:面向 3 副本集群的高可用配置——内部 topic(offsets、事务状态日志)副本因子为 3,min.insync.replicas: 2保证多数派确认,default.replication.factor: 3为用户 topic 的默认副本数。
  • entityOperator:同时启用 Topic Operator 与 User Operator,负责KafkaTopic/KafkaUser等实体资源的调谐。

3.2 JBOD 多卷存储(kafka-jbod.yaml)

kafka-jbod.yaml 演示 broker 节点池使用多个数据卷(JBOD,Just a Bunch Of Disks):controller池保持单卷,broker池声明两个 100Gi 卷:

storage: type: jbod volumes: - id: 0 type: persistent-claim size: 100Gi # Indicates that this directory will be used to store Kraft metadata log kraftMetadata: shared - id: 1 type: persistent-claim size: 100Gi

要点:

  • id是卷标识符。从 API 源码(SingleVolumeStorage 的注解,EphemeralStorage.getId()的描述)可知:“Storage identification number. It is mandatory only for storage volumes defined in a storage of type 'jbod'”——即只有在type: jbod的存储中,id才是强制字段。
  • kraftMetadata: shared表示该目录/卷同时用于存放 KRaft 元数据日志。API 模型中对该字段的官方描述(见 PersistentClaimStorage.java)为:“Specifies whether this volume should be used for storing KRaft metadata. This property is optional. When set, the only currently supported value isshared. At most one volume can have this property set.”——即该属性可选、当前唯一支持的取值是shared,且同一节点池中至多一个卷可以设置该属性。示例中id: 0卷承担元数据与部分数据,id: 1卷仅存数据。

3.3 ephemeral 临时存储(kafka-ephemeral.yaml)

kafka-ephemeral.yaml 与持久化示例结构相同,差别仅在存储卷类型:

storage: type: jbod volumes: - id: 0 type: ephemeral kraftMetadata: shared
  • type: ephemeral基于 Kubernetes EmptyDir 实现,节点 Pod 删除或驱逐后数据即丢失,适用于开发测试或对数据无持久性要求、追求快速部署的场景。
  • 结合 API 源码 EphemeralStorage.java 可知,ephemeral 卷还有一个可选字段sizeLimit:“When type=ephemeral, defines the total amount of local storage required for this EmptyDir volume (for example 1Gi)”——示例未设置sizeLimit,表示不限制 EmptyDir 大小(实际仍受节点可分配空目录存储配额约束)。
  • 其余Kafka资源配置(listeners、config、entityOperator)与持久化示例完全一致。

3.4 双角色节点池(kafka-with-dual-role-nodes.yaml)

该示例只定义一个节点池dual-role(3 副本,roles同时包含controllerbroker),Kafka 集群部分与 3.1 相同。其意义在于:

  • 资源占用更省:controller 与 broker 共 Pod、共存储,3 节点即可同时满足 quorum 仲裁与数据副本需求;
  • 与完全分离的双池(3 controller + 3 broker = 6 Pod)相比,运维上只需管理一个节点池;
  • 代价是两种负载互相竞争 CPU/内存/磁盘 IO,且单池副本数同时决定仲裁法定人数,扩容时两类角色只能一起扩。

3.5 单节点开发集群(kafka-single-node.yaml)

kafka-single-node.yaml 面向本地开发与一次性测试:节点池replicas: 1,roles 为 dual-role。由于集群只有一个节点,内部 topic 无法做到多数派复制,因此其config段被整体下调为单副本语义:

config: offsets.topic.replication.factor: 1 transaction.state.log.replication.factor: 1 transaction.state.log.min.isr: 1 default.replication.factor: 1 min.insync.replicas: 1

这一点值得在实际操作中特别留意:多节点示例中的replication.factor: 3 / min.insync.replicas: 2若照搬到单节点集群,将导致内部 topic 无法满足 ISR 条件、Producer 端写请求按acks语义持续失败。示例文件正是在这一点上给出了单节点场景的正确取值组合。

四、KRaft 存储参数速查(对照 API 模型)

五个示例覆盖的存储参数集中在KafkaNodePool.spec.storage下,其字段语义可由仓库 API 模型源码直接确认:

参数取值/类型说明(依据 API 模型描述)
typejbod多卷存储模式;volumes中每个卷的id必填
volumes[].typepersistent-claim/ephemeral卷类型,见 PersistentClaimStorage.java 与 EphemeralStorage.java
volumes[].size100Gitype=persistent-claim时必填,定义 PVC 大小
volumes[].class字符串用于动态卷分配的 StorageClass(源码中@JsonProperty("class")映射)
volumes[].selector键值对按标签选择特定的持久卷
volumes[].deleteClaim布尔,默认false节点删除时是否同时删除 PVC
volumes[].sizeLimit1Gitype=ephemeral有效,限制 EmptyDir 总大小
volumes[].kraftMetadatashared声明该卷存放 KRaft 元数据;可选,每池至多一个卷可设置

另外,PersistentClaimStorage模型中还定义了volumeAttributesClass(为动态配置存储属性指定VolumeAttributeClass名称),示例文件未使用,但在需要按卷调整存储属性(如性能档位)时可以考虑。

五、部署与验证

所有示例均可直接通过kubectl应用(以持久化示例为例):

kubectl apply -f packaging/examples/kafka/kafka-persistent.yaml

部署后可以从以下方面验证集群状态:

  1. Kafka资源状态:kubectl get kafka my-cluster -o yaml,观察status.conditionsReady条件与集群地址信息;
  2. Pod 与节点池:kubectl get pods -l strimzi.io/cluster=my-cluster,确认my-cluster-controller-0..2my-cluster-broker-0..2(或my-cluster-dual-role-0..2)就绪;
  3. 监听器连通性:在集群内通过my-cluster-kafka-bootstrap:9092(plain)或:9093(tls)访问;
  4. Entity Operator:topicOperator: {}/userOperator: {}启用后,集群内会自动创建对应的 Entity Operator Deployment,用于后续管理KafkaTopicKafkaUser等资源(仓库 examples/topic 与 examples/user 目录提供相应示例)。

需要注意的前提:示例假定 Strimzi Cluster Operator 已先行部署并运行(安装文件见 install/cluster-operator),且集群内可用的 Kafka 版本包含示例指定的4.3.1;更换版本时应以当前仓库kafka-versions.yaml中列出的受支持版本为准。

六、总结

packaging/examples/kafka/目录下的五个示例构成了一套完整的 KRaft 部署参照系:

  • 生产取向:kafka-persistent.yaml 的 controller/broker 双池分离部署,职责清晰、故障域隔离;kafka-jbod.yaml 进一步展示多卷扩展数据容量、并用kraftMetadata: shared指定元数据卷的做法;
  • 开发取向:kafka-ephemeral.yaml 免去 PVC 管理成本,kafka-single-node.yaml 将节点数与副本因子同时降到 1,适合本地调试;
  • 折中取向:kafka-with-dual-role-nodes.yaml 用单一 dual-role 节点池同时承载仲裁与数据平面,以资源效率换取一定程度的负载隔离性。

修改任何配置前,建议对照本文第四节的参数表与仓库 API 模型源码(api/src/main/java/io/strimzi/api/kafka/model/kafka/下的存储模型类)确认字段约束,尤其是kraftMetadata“每池至多一个卷” 的限制,以及副本因子与min.insync.replicas必须与节点池副本数匹配的经验法则。

【免费下载链接】strimzi-kafka-operatorApache Kafka® running on Kubernetes项目地址: https://gitcode.com/GitHub_Trending/st/strimzi-kafka-operator

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询