docker-compose 搭建 kafka kraft 集群(避坑包成功)

1,638 阅读4分钟

随便找的博客,复制配置,启动,基本很难一步成功的! 原因是,人家成功的,但是没有把坑点暴露出来。

本文使用 bitnami/kafka 镜像。

心急的直接拿下面的配置启动即可,后文会介绍注意点。

docker-compose.yml

# 自行替换变量,可手动替换,可同级目录下放个 .env 文件里面放k=v对
# ${HOST}
# ${CLUSTER_ID}

version: "3"
services:
  kafka1:
    image: "bitnami/kafka:3.3.1"
    container_name: kafka11
    user: root
    ports:
      - 9192:9092
      - 9193:9093
      - 9194:9094
    environment:
      # 允许使用kraft,即Kafka替代Zookeeper
      - KAFKA_ENABLE_KRAFT=yes
      # kafka角色,做broker,也要做controller
      - KAFKA_CFG_PROCESS_ROLES=broker,controller
      # 指定供外部使用的控制类请求信息
      - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
      # 定义kafka服务端socket监听端口
      # - KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093
      # 定义安全协议
      # - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
      - KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://:9094
      # - KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093
      # 定义外网访问地址(宿主机ip地址和端口)
      - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka11:9092,EXTERNAL://${HOST}:9194
      # - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka11:9092
      - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT,PLAINTEXT:PLAINTEXT
      # - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
      # 使用Kafka时的集群id,集群内的Kafka都要用这个id做初始化,生成一个UUID即可
      - KAFKA_KRAFT_CLUSTER_ID=${CLUSTER_ID}
      # 集群地址
      - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=1@kafka11:9093,2@kafka22:9093,3@kafka33:9093
      # 允许使用PLAINTEXT监听器,默认false,不建议在生产环境使用
      - ALLOW_PLAINTEXT_LISTENER=yes
      # 设置broker最大内存,和初始内存
      # - KAFKA_HEAP_OPTS=-Xmx512M -Xms256M
      # 不允许自动创建主题
      - KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=true
      # broker.id,必须唯一
      - KAFKA_BROKER_ID=1
    volumes:
      - E:/data/kafka-kraft/1:/bitnami/kafka
  #extra_hosts:
  #- "kafka1:云服务器IP"
  #- "kafka2:云服务器IP"
  #- "kafka3:云服务器IP"
  kafka2:
    image: "bitnami/kafka:3.3.1"
    container_name: kafka22
    user: root
    ports:
      - 9292:9092
      - 9293:9093
      - 9294:9094
    environment:
      # 允许使用kraft,即Kafka替代Zookeeper
      - KAFKA_ENABLE_KRAFT=yes
      # kafka角色,做broker,也要做controller
      - KAFKA_CFG_PROCESS_ROLES=broker,controller
      # 指定供外部使用的控制类请求信息
      - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
      # 定义kafka服务端socket监听端口
      # - KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093
      # 定义安全协议
      # - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
      - KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://:9094
      # - KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093
      - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka22:9092,EXTERNAL://${HOST}:9294
      # - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka22:9092
      - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT,PLAINTEXT:PLAINTEXT
      # - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
      # 使用Kafka时的集群id,集群内的Kafka都要用这个id做初始化,生成一个UUID即可
      - KAFKA_KRAFT_CLUSTER_ID=${CLUSTER_ID}
      # 集群地址
      - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=1@kafka11:9093,2@kafka22:9093,3@kafka33:9093
      # 允许使用PLAINTEXT监听器,默认false,不建议在生产环境使用
      - ALLOW_PLAINTEXT_LISTENER=yes
      # 设置broker最大内存,和初始内存
      # - KAFKA_HEAP_OPTS=-Xmx512M -Xms256M
      # 不允许自动创建主题
      - KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=true
      # broker.id,必须唯一
      - KAFKA_BROKER_ID=2
    volumes:
      - E:/data/kafka-kraft/2:/bitnami/kafka
  kafka3:
    image: "bitnami/kafka:3.3.1"
    container_name: kafka33
    user: root
    ports:
      - 9392:9092
      - 9393:9093
      - 9394:9094
    environment:
      # 允许使用kraft,即Kafka替代Zookeeper
      - KAFKA_ENABLE_KRAFT=yes
      # kafka角色,做broker,也要做controller
      - KAFKA_CFG_PROCESS_ROLES=broker,controller
      # 指定供外部使用的控制类请求信息
      - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
      # 定义kafka服务端socket监听端口
      # - KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093
      # 定义安全协议
      # - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
      - KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://:9094
      # - KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093
      - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka33:9092,EXTERNAL://${HOST}:9394
      # - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka33:9092
      - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT,PLAINTEXT:PLAINTEXT
      # - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
      # 使用Kafka时的集群id,集群内的Kafka都要用这个id做初始化,生成一个UUID即可
      - KAFKA_KRAFT_CLUSTER_ID=${CLUSTER_ID}
      # 集群地址
      - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=1@kafka11:9093,2@kafka22:9093,3@kafka33:9093
      # 允许使用PLAINTEXT监听器,默认false,不建议在生产环境使用
      - ALLOW_PLAINTEXT_LISTENER=yes
      # 设置broker最大内存,和初始内存
      # - KAFKA_HEAP_OPTS=-Xmx512M -Xms256M
      # 不允许自动创建主题
      - KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=true
      # broker.id,必须唯一
      - KAFKA_BROKER_ID=3
    volumes:
      - E:/data/kafka-kraft/3:/bitnami/kafka

# networks:
#   br168:
#     external: true

配置介绍

  1. 客户端端口使用了内外分开的,EXTERNAL 9094 外部客户端,9092 内部。这个不是必选的,看个人喜好,不想分可以切换相关注释。官文引用:

image.png

  1. 关键配置KAFKA_CFG_ADVERTISED_LISTENERS,这个决定了kafka告诉客户端以什么地址访问它。所以,核心就是要保证它发布的这个地址,客户端可以访问

    1)内部客户端,使用 kafka11:9092 ,集群内其他节点是能够识别 kafka11 hostname 的。

    2)外部客户端(主要就是宿主机了),${HOST}:9194 ,所以这里的 HOSTlocalhost 是可以的。 如果不是分内外模式,就需要确保宿主机和集群内部都能访问的ip:port。我之所以分开,其一是实验下效果,其二是容器内通不了宿主机ip+port,原因不详。

image.png

关于这个广播的集群地址,还有其他思路。

思路2:不分内外,都用 kafka11:9192 (映射端口)。宿主机 hosts 文件 kafka11->localhost

思路3宿主机ip:9192 (映射端口)。前提是容器里能够通宿主机ip,我的不知道为啥不行?

看你选择咯。