欢迎光临
我们一直在努力

kafka-4.1.1-cluster-k8s-helm

Apache Kafka 4.1.1 集群部署实战:三节点 KRaft 集群 + Kubernetes/Helm 方案

这篇是上一篇《Kafka 4.1.1 单机部署全指南》的“进阶版”,主要聚焦:

  • 裸机/虚机三节点 KRaft 集群 部署(无 ZooKeeper)
  • 在 Kubernetes 中使用 Helm 部署 Kafka 集群 的一个参考模板
  • 所有示例默认使用 Apache Kafka 4.1.1 + KRaft 模式。


    0. 集群架构设计示例

    这里先给一个典型的 3 节点小型集群 架构设定,方便后文统一:

    角色主机名IP 示例端口
    Broker #1 kafka-1 192.168.10.11 9092 / 9093
    Broker #2 kafka-2 192.168.10.12 9092 / 9093
    Broker #3 kafka-3 192.168.10.13 9092 / 9093

    设计思路:

    • 每个节点同时是 broker + controller(process.roles=broker,controller),适合中小集群,避免额外维护独立 controller 组。
    • 所有节点共享一个 KRaft 集群 ID,但 node.id 不同。
    • Controller 选举端口 统一用 9093,客户端访问 broker 使用 9092(也可自行调整)。

    如果你是大集群,可以再扩展为:3 controller(不带 broker) + N broker,但配置思路是类似的。


    一、裸机/虚机三节点 Kafka 4.1.1 KRaft 集群部署

    1.1 环境准备(所有节点)

    假设你的操作系统是 Linux(CentOS7/8、Ubuntu、麒麟等),三台机器都执行:

    # 1)安装 JDK(以 Java 17 为例)
    yum install -y java-17-openjdk java-17-openjdk-devel # RHEL/CentOS 系列
    # 或者 apt install openjdk-17-jdk # Debian/Ubuntu 系列

    # 2)创建 kafka 用户 & 目录
    useradd -m -s /bin/bash kafka
    mkdir -p /opt/kafka /data/kafka-logs /data/kafka-meta
    chown -R kafka:kafka /opt/kafka /data/kafka-logs /data/kafka-meta

    1.2 下载并分发 Kafka 4.1.1

    在其中一台机器上(比如 kafka-1)下载 Kafka 4.1.1 二进制包:

    cd /opt
    # 具体下载 URL 以官网为准,这里仅示例
    curl -O https://downloads.apache.org/kafka/4.1.1/kafka_2.13-4.1.1.tgz

    tar -xzf kafka_2.13-4.1.1.tgz
    ln -s kafka_2.13-4.1.1 kafka
    chown -R kafka:kafka /opt/kafka_2.13-4.1.1 /opt/kafka

    然后可以用 scp 把 /opt/kafka_2.13-4.1.1 拷到其他两台节点,分别创建 /opt/kafka 软链接(或者在每台机器重复一次下载解压过程):

    # 在 kafka-1 上
    scp -r /opt/kafka_2.13-4.1.1 root@kafka-2:/opt/
    scp -r /opt/kafka_2.13-4.1.1 root@kafka-3:/opt/

    # 在 kafka-2、kafka-3 上各自执行
    ln -s /opt/kafka_2.13-4.1.1 /opt/kafka
    chown -R kafka:kafka /opt/kafka_2.13-4.1.1 /opt/kafka

    后续所有命令默认在 kafka 用户下执行:

    su – kafka
    cd /opt/kafka


    1.3 KRaft 集群配置(server.properties)

    Kafka 4.x 默认推荐使用 KRaft 模式来替代 ZooKeeper。我们以 config/kraft/server.properties 为基础配置文件。

    1.3.1 公共配置(3 节点类似)

    先在任意一节点上编辑:

    cd /opt/kafka
    cp config/kraft/server.properties config/kraft/server.properties.bak
    vi config/kraft/server.properties

    设置 所有节点通用的部分(以下内容在三台机器保持一致):

    ######################### KRaft 基本角色配置 #########################
    # 进程角色:同时作为 broker 和 controller
    process.roles=broker,controller

    # Controller 仲裁投票者(3 个节点)
    controller.quorum.voters=1@kafka-1:9093,2@kafka-2:9093,3@kafka-3:9093

    # Controller 使用的 listener 名称
    controller.listener.names=CONTROLLER

    ######################### 监听地址 #########################
    # 监听地址:PLAINTEXT 用于客户端 & broker 间,CONTROLLER 用于控制器选举
    listeners=PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
    listener.security.protocol.map=PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT

    # broker 间通信使用的 listener 名称
    inter.broker.listener.name=PLAINTEXT

    ######################### 数据 & 元数据目录 #########################
    # Topic 数据目录(可配置多个挂载点)
    log.dirs=/data/kafka-logs

    # KRaft 元数据存储目录
    metadata.log.dir=/data/kafka-meta

    ######################### Topic 默认配置 #########################
    # 默认分区数
    num.partitions=3

    # 日志保留时间(小时)
    log.retention.hours=168

    # 单个日志段大小:1GB
    log.segment.bytes=1073741824

    # 内部 topic 副本相关(3 节点生产环境建议为 3,这里先示例 3)
    offsets.topic.replication.factor=3
    transaction.state.log.replication.factor=3
    transaction.state.log.min.isr=2

    注意:controller.quorum.voters 中的 node.id@host:port 需要与每个节点的 node.id、主机名、Controller 监听端口保持一致。

    1.3.2 节点专属配置

    三个节点唯一需要区别的,是:

    • node.id(整数且集群唯一)
    • advertised.listeners(对客户端和其他 broker 公布的地址)

    分别在三台机器上,基于上面的公共配置,再追加/修改以下内容:

    kafka-1(192.168.10.11):

    # 当前节点 ID
    node.id=1

    # 对外公布地址(客户端访问用)
    advertised.listeners=PLAINTEXT://192.168.10.11:9092

    kafka-2(192.168.10.12):

    node.id=2
    advertised.listeners=PLAINTEXT://192.168.10.12:9092

    kafka-3(192.168.10.13):

    node.id=3
    advertised.listeners=PLAINTEXT://192.168.10.13:9092

    如果你有内外网、LB 等,可以把 advertised.listeners 写成域名或负载均衡地址。


    1.4 初始化 KRaft 存储(cluster ID)

    KRaft 集群必须先格式化存储,并且 三台机器使用同一个集群 ID。

    1.4.1 生成集群 ID(仅一次)

    在任意一台机器(比如 kafka-1)上执行:

    su – kafka
    cd /opt/kafka

    bin/kafka-storage.sh random-uuid
    # 示例输出:
    # fRbs-vkR9Uevh5Cwlwk

    假设生成的 cluster ID 为:fRbs-vkR9Uevh5Cwlwk。

    1.4.2 每台机器执行 format

    三台机器都要执行一次 format,但用同一个 cluster ID:

    # 在 kafka-1、kafka-2、kafka-3 上分别执行(kafka 用户)
    cd /opt/kafka

    bin/kafka-storage.sh format -t fRbs-vkR9Uevh5Cwlwk -c config/kraft/server.properties

    如果之后修改了 log.dirs 或 metadata.log.dir,需要先清空目录再重新 format。


    1.5 启动三节点集群

    可以先手工启动验证,再接入 systemd。

    1.5.1 手工后台启动

    在三台机器上分别执行:

    su – kafka
    cd /opt/kafka

    bin/kafka-server-start.sh -daemon config/kraft/server.properties

    查看进程和端口:

    ps -ef | grep kafka
    netstat -lnpt | grep 9092
    netstat -lnpt | grep 9093

    查看日志:

    tail -f /opt/kafka/logs/server.log

    正常情况下,三个节点启动成功后,会完成 controller 选举,并形成集群。

    1.5.2 配置 systemd(可选)

    在每台机器上,以 root 身份创建 /etc/systemd/system/kafka.service:

    [Unit]
    Description=Apache Kafka 4.1.1 (KRaft Cluster Node)
    After=network.target

    [Service]
    User=kafka
    Group=kafka
    Type=simple
    Environment="JAVA_HOME=/usr/lib/jvm/java-17-openjdk"
    ExecStart=/opt/kafka/bin/kafka-server-start.sh /opt/kafka/config/kraft/server.properties
    ExecStop=/opt/kafka/bin/kafka-server-stop.sh
    Restart=on-failure
    RestartSec=5

    [Install]
    WantedBy=multi-user.target

    重新加载并启动:

    systemctl daemon-reload
    systemctl enable kafka
    systemctl start kafka
    systemctl status kafka

    也可以根据需要为 controller 机器单独写一个带 “controller-only” 的 unit,这里先保持简单。


    1.6 集群验证:Topic 分布情况

    任选一台机器(例如 kafka-1),使用 Kafka CLI 验证:

    su – kafka
    cd /opt/kafka

    1.6.1 创建带副本的 Topic

    bin/kafka-topics.sh –create –topic demo-cluster-topic –bootstrap-server 192.168.10.11:9092 –partitions 6 –replication-factor 3

    1.6.2 查看 Topic 描述

    bin/kafka-topics.sh –describe –topic demo-cluster-topic –bootstrap-server 192.168.10.11:9092

    你应该能看到:6 个分区被均匀分布在 3 台 broker 上,并且每个分区都有 3 副本。

    1.6.3 跨节点生产/消费测试
    • 在 kafka-1 上起生产者:

    bin/kafka-console-producer.sh –topic demo-cluster-topic –bootstrap-server 192.168.10.11:9092

    • 在 kafka-2 或 kafka-3 上起消费者:

    bin/kafka-console-consumer.sh –topic demo-cluster-topic –from-beginning –bootstrap-server 192.168.10.12:9092

    如果能看到消息正常消费,说明 集群 + 副本 + 网络 都没问题。


    二、在 Kubernetes 中用 Helm 部署 Kafka 4.1.x 集群(KRaft)

    这一部分给出一个基于 Bitnami Kafka Helm Chart 的示例。Bitnami 的 Kafka Chart 已支持 KRaft 模式,并且可以通过 kraft.enabled、controller.replicaCount、broker.replicaCount 等参数配置 controller 和 broker 副本数。

    不同版本 chart 的字段可能略有变化,实际部署时一定要以 helm show values bitnami/kafka 输出为准。

    2.1 前置条件

    • 已有一套可用的 Kubernetes 集群(本地 kind/minikube 或云上均可)
    • 已安装 kubectl 并配置好 kubeconfig
    • 已安装 Helm 3

    2.2 添加 Bitnami 仓库并更新

    helm repo add bitnami https://charts.bitnami.com/bitnami
    helm repo update

    你可以先查看默认 values:

    helm show values bitnami/kafka > values-default.yaml

    2.3 编写自定义 values(KRaft 集群示例)

    新建一个 values-kraft.yaml,示例:

    说明:以下字段名称是根据当前 Bitnami Chart 的典型用法示意,实际字段名请以你环境的 chart 版本为准。

    # 命名空间与通用设置(可选)
    fullnameOverride: "kafka"

    # 存储设置示例
    persistence:
    enabled: true
    size: 20Gi
    storageClass: "" # 留空使用默认,或填写你实际的 storageClass 名称

    # 启用 KRaft 模式
    kraft:
    enabled: true
    # 集群 ID 可以自定义一个合法字符串,也可以留空让 chart 自动生成
    clusterId: "MkU3OEVBNTcwNTJENDM2Qk"

    # Controller 配置(负责元数据 & 选举)
    controller:
    replicaCount: 3
    # 某些版本的 chart 提供 controllerOnly 选项,表示只作为 controller,不处理数据
    # controllerOnly: false

    # Broker 配置(处理客户端读写)
    broker:
    replicaCount: 3

    # Listener 配置示意(不同 chart 版本字段可能不同)
    listeners:
    client:
    protocol: PLAINTEXT
    interbroker:
    protocol: PLAINTEXT
    controller:
    protocol: PLAINTEXT
    external:
    enabled: false # 如需对集群外暴露,再启用并配置 Ingress/LB

    # 资源(示例,可按需调整)
    resources:
    requests:
    cpu: "500m"
    memory: "1Gi"
    limits:
    cpu: "2"
    memory: "4Gi"

    如果你计划在生产中使用,建议:

    • 给 Broker/Controller 设置合理的 resources 和 affinity,确保 Pod 分散到不同节点。
    • 启用 external listener 并结合 LoadBalancer / Ingress 来对外暴露。

    2.4 使用 Helm 安装 Kafka 集群

    # 创建命名空间(可选)
    kubectl create namespace kafka

    # 安装
    helm install kafka bitnami/kafka -n kafka -f values-kraft.yaml

    查看 Pod 状态:

    kubectl get pods -n kafka -w

    正常情况下,你会看到类似:

    NAME READY STATUS RESTARTS AGE
    kafka-controller-0 1/1 Running 0 2m
    kafka-controller-1 1/1 Running 0 2m
    kafka-controller-2 1/1 Running 0 2m
    kafka-broker-0 1/1 Running 0 2m
    kafka-broker-1 1/1 Running 0 2m
    kafka-broker-2 1/1 Running 0 2m

    实际 Pod 名称取决于 chart 版本与 fullnameOverride 配置,这里仅作示例。


    2.5 在 Kubernetes 集群内测试 Kafka

    最简单的办法是 起一个临时的 Client Pod,进入后使用 Kafka CLI 进行测试。例如:

    kubectl run kafka-client –rm -it –image=bitnami/kafka:4.1.1 –namespace kafka –restart=Never — bash

    进入容器后:

  • 查看 Kafka 服务名(在另一个终端执行):

    kubectl get svc -n kafka

    通常会有一个类似 kafka-broker 或 kafka 的 Service(具体名称受 chart 版本与配置影响)。

  • 在 client 容器内创建 Topic:

    kafka-topics –create –topic demo-k8s-topic –partitions 6 –replication-factor 3 –bootstrap-server kafka:9092 # 这里的 kafka:9092 替换为你实际的 Service 名称

  • 启动生产者:

    kafka-console-producer –topic demo-k8s-topic –bootstrap-server kafka:9092

  • 再起一个客户端消费:

    kafka-console-consumer –topic demo-k8s-topic –from-beginning –bootstrap-server kafka:9092

  • 只要消息能从一个 client Pod 发出,再在另一个 Pod 中消费,就说明 Kubernetes + Helm 部署的 Kafka 集群是正常的。


    2.6 Helm 日常运维操作

    • 查看当前 values:

      helm get values kafka -n kafka

    • 修改配置并滚动更新:

      # 例如修改 values-kraft.yaml
      helm upgrade kafka bitnami/kafka -n kafka -f values-kraft.yaml

    • 扩容 broker 副本:

      在 values-kraft.yaml 中修改:

      broker:
      replicaCount: 5

      然后执行 helm upgrade 即可触发滚动扩容。

    • 卸载集群:

      helm uninstall kafka -n kafka
      # 注意:PVC 默认不会被删除,需要手动 kubectl delete pvc


    三、快速对比:裸机集群 vs Kubernetes/Helm

    维度裸机/虚机集群Kubernetes + Helm 集群
    部署成本 一开始稍复杂,后期靠脚本/systemd 初始有 Helm 学习成本,但一旦熟悉非常适合集群管理
    运维方式 SSH + systemd + 自建监控/告警 kubectl + Helm + K8s 生态(Prometheus / Grafana 等)
    弹性扩缩容 一般需要手动加节点 & 修改配置 修改 replicaCount + helm upgrade 即可
    环境隔离 依赖物理机/虚机隔离 Namespace + NetworkPolicy + ResourceQuota 等
    适用场景 小规模、对 K8s 依赖较小的传统环境 已有 K8s 平台或云原生环境,需快速弹性扩展

    两种方式没有绝对的好坏——更推荐的做法是:

    • 开发 / 测试环境:Docker / K8s 都可以,非常灵活;
    • 传统机房 / 虚机环境:可以用本文的三节点 KRaft 集群方案;
    • 已全面上云 / K8s:优先考虑 Helm 部署,并在上层引入 Operator 或自研运维平台。

    四、总结 & 后续可以扩展的方向

    到这里,你已经完成了:

  • 在裸机/虚机上搭建一个 三节点 Kafka 4.1.1 KRaft 集群;
  • 在 Kubernetes 中,使用 Helm + Bitnami Kafka Chart 部署了一套 多副本 Kafka 集群。
  • 赞(0)
    未经允许不得转载:171主机测评 » kafka-4.1.1-cluster-k8s-helm
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址