Docker - Kafka

博文目录


说明

Docker Hub - bitnami/kafka
Docker Hub - apache/kafka
Kafka QuickStart

Kafka 目前没有 Docker 官方镜像, 目前拉取次数最多的是 bitnami/kafka, Apache 提供的是 apache/kafka (更新最及时), 本文使用 bitnami/kafka

bitnami/kafka 镜像支持的环境变量有很多, 除 DockerHub 文档中列出的外, Kafka 的每一个配置项都可以与一个以 KAFKA_CFG_ 开头的环境变量相对应, 如 KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE 对应 auto.create.topics.enable, KAFKA_CFG_BACKGROUND_THREADS 对应 background.threads

Kafka 现在有两种启动方式, ZooKeeper 或 KRaft, 后者不需要依赖 Zookeeper, 本文使用 KRaft

Kafka KRaft Config

数据卷数据卷印射在容器内的路径
kafka/bitnami/kafka

命令

Kafka 文档
bitnami configuration
bitnami security
bitnami apache-kafka-kraft-mode-configuration
bitnami apache-kafka-zookeeper-mode-configuration
bitnami setting-up-a-apache-kafka-cluster

docker pull bitnami/kafka
docker network create network
docker volume create kafka

说明

Kafka 集群的安全认证机制主要包括 认证(Authentication)、授权(Authorization) 和 数据加密(Encryption), 确保集群和客户端的安全通信

  • Kafka 主要支持 SASL(Simple Authentication and Security Layer) 认证方式
  • 认证成功后, 还需要 授权 来控制不同用户的访问权限, 默认使用 ACL(Access Control List) 进行权限管理
  • 常见的 ACL 权限有: Read(消费权限), Write(生产权限), Create(创建主题), Delete(删除主题), Alter(修改主题)
  • 如果不启用 ACL, Kafka 允许所有用户访问
  • Kafka 支持 TLS/SSL 加密, 用于 客户端-服务器 之间的数据传输保护

Kafka 可以分别配置 与 Controller 相关的通信 / Broker 之间的通信 / Broker 与 Client 之间的通信 是否做安全认证与是否加密, 但是 Spring 与 Kafka 的集成仅限于 Client 与 Broker 通信 这一种, 所以这里不关注其他两个通信方式的认证与加密与否, 只考虑客户端相关的配置

Spring 与 Kafka 集成有几个核心配置参数如下

  • spring.kafka.security.protocol 配置对应 Kafka 的 安全协议, 用于指定 Kafka 客户端 和 集群 之间的认证与通信方式, 有如下可选值
    • PLAINTEXT: 无认证,无加密, 默认值
    • SSL: 无认证, 有加密(TLS/SSL)
    • SASL_PLAINTEXT: 有认证(SASL), 无加密
    • SASL_SSL: 有认证(SASL), 有加密(TLS/SSL)
  • spring.kafka.properties.sasl.mechanism 用于配置 Kafka SASL 认证机制, 只在安全协议为 SASL_PLAINTEXTSASL_SSL 时生效, 有如下可选值, 这里只记录 PLAIN 机制, 因为其他的很难搞没成功
    • PLAIN: 明文用户名/密码认证
    • SCRAM-SHA-256: 更安全的用户名/密码认证
    • SCRAM-SHA-512: 更安全的用户名/密码认证
    • GSSAPI: 基于 Kerberos 认证, 默认值
    • OAUTHBEARER: 基于 OAuth 令牌认证

PLAINTEXT, 无认证, 无加密

docker run -d --name kafka --restart=always --network network -p 9092:9092 -e TZ=Asia/Shanghai -e KAFKA_CFG_PROCESS_ROLES=controller,broker -e KAFKA_CFG_NODE_ID=0 -e KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT -e KAFKA_CFG_LISTENERS=CONTROLLER://:9099,PLAINTEXT://:9092 -e KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092 -e KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER -e KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka:9099 -e KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=false -v kafka:/bitnami/kafka bitnami/kafka:latest
docker run -d --name kafka --restart=always --network network -p 9092:9092 -e TZ=Asia/Shanghai 
# process.roles, 本节点扮演的角色, 即是 broker 也是 controller, 没有该配置则认为处于ZK模式
-e KAFKA_CFG_PROCESS_ROLES=controller,broker 
# node.id, 本节点的唯一标识
-e KAFKA_CFG_NODE_ID=0 
# listener.security.protocol.map, 侦听器名称和安全协议之间的映射,默认值:PLAINTEXT:PLAINTEXT,SASL_PLAINTEXT:SASL_PLAINTEXT,SSL:SSL,SASL_SSL:SASL_SSL
-e KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT 
# listeners, 可用的监听器, 用于 Controller 相关的通信, Broker 之间通信, Client 和 Broker 之间通信
-e KAFKA_CFG_LISTENERS=CONTROLLER://:9099,PLAINTEXT://:9092 
# advertised.listeners, 用于告诉外部客户端和其他 Broker 该节点的访问地址
-e KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092 
# controller.listener.names, 指定用于控制器通信的监听器名称, 作用是告诉 Kafka 控制器节点应该使用哪个监听器来进行通信。控制器节点是 Kafka 集群中的一种特殊节点,负责管理集群的元数据、领导者选举、分区分配和其他集群管理任务。在 KRaft 模式下,控制器节点通过与其他节点之间的通信来执行这些任务。KRaft 模式下, 控制器节点必须配置
-e KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER 
# controller.quorum.voters, 投票者列表, 奇数, 格式为 {id}@{host}:{port}, 这里的 host 为 kafka 是因为 docker 支持用容器名称来访问
-e KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka:9099 
-e KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=false 
-v kafka:/bitnami/kafka bitnami/kafka:latest
spring.kafka.bootstrap-servers=localhost:9092
spring.kafka.listener.ack-mode=manual_immediate
spring.kafka.consumer.enable-auto-commit=false
spring.kafka.consumer.group-id=test
spring.kafka.consumer.auto-offset-reset=latest
spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer
spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer
spring.kafka.producer.acks=all
spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer
spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer

SASL_PLAINTEXT/PLAIN, 有认证(SASL), 无加密

docker run -d --name kafka --restart=always --network network -p 9093:9093 -e TZ=Asia/Shanghai -e KAFKA_CFG_PROCESS_ROLES=controller,broker -e KAFKA_CFG_NODE_ID=0 -e KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,SASL_PLAINTEXT:SASL_PLAINTEXT -e KAFKA_CFG_LISTENERS=CONTROLLER://:9099,PLAINTEXT://:9092,SASL_PLAINTEXT://:9093 -e KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092,SASL_PLAINTEXT://localhost:9093 -e KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka:9099 -e KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER -e KAFKA_CFG_SASL_ENABLED_MECHANISMS=PLAIN -e KAFKA_CFG_SASL_MECHANISMS=PLAIN -e KAFKA_CLIENT_USERS=kafka -e KAFKA_CLIENT_PASSWORDS=Mrv587.. -e KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=false -v kafka:/bitnami/kafka bitnami/kafka:latest
docker run -d --name kafka --restart=always --network network -p 9093:9093 -e TZ=Asia/Shanghai 
-e KAFKA_CFG_PROCESS_ROLES=controller,broker 
-e KAFKA_CFG_NODE_ID=0 
-e KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,SASL_PLAINTEXT:SASL_PLAINTEXT 
-e KAFKA_CFG_LISTENERS=CONTROLLER://:9099,PLAINTEXT://:9092,SASL_PLAINTEXT://:9093 
# 客户端可通过 advertised.listeners 公开的地址连接集群, 即 9092(无认证) 和 9093(有认证) 同时生效, 通过 -p 控制允许访问的端口
-e KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092,SASL_PLAINTEXT://localhost:9093 
-e KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka:9099 
-e KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER 
-e KAFKA_CFG_SASL_ENABLED_MECHANISMS=PLAIN 
-e KAFKA_CFG_SASL_MECHANISMS=PLAIN 
-e KAFKA_CLIENT_USERS=kafka 
-e KAFKA_CLIENT_PASSWORDS=Mrv587.. 
-e KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=false 
-v kafka:/bitnami/kafka bitnami/kafka:latest
spring.kafka.bootstrap-servers=localhost:9093
spring.kafka.security.protocol=SASL_PLAINTEXT
spring.kafka.properties.sasl.mechanism=PLAIN
spring.kafka.properties.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username="kafka" password="Mrv587..";
spring.kafka.listener.ack-mode=manual_immediate
spring.kafka.consumer.enable-auto-commit=false
spring.kafka.consumer.group-id=test
spring.kafka.consumer.auto-offset-reset=latest
spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer
spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer
spring.kafka.producer.acks=all
spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer
spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer

SSL, 无认证, 有加密

好难搞, 等真的需要的时候再研究吧

SASL_SSL/PLAIN, 有认证(SASL), 有加密

好难搞, 等真的需要的时候再研究吧

其他

可以在启动日志中找到 Kafka 节点的完整配置

# 查看日志(启动失败也可查看)
docker logs kafka
# 跟踪日志
docker logs -f kafka
docker logs --follow kafka
# 查看最后10条日志
docker logs --tail 10 kafka
# 查看最近10分钟的日志
docker logs --since 10m kafka
# 进入容器并执行 bash
docker exec -it kafka bash
# 退出容器
exit

Kafka 脚本文件在容器中的存放路径 /opt/bitnami/kafka/bin

默认情况下, 新建的 Topic 有一个分区, 每个分区有一个副本, 由 num.partitionsdefault.replication.factor 指定, 默认值都是 1

docker exec -it kafka bash
cd /opt/bitnami/kafka
# 创建 topic, 创建一个1分区1副本的主题, 集群每个节点都需要写到 --bootstrap-server 中, 用逗号分割
# host 用 kafka 是因为启动容器指定了 hostname
# 分区数会影响消费者的最大并行度
bin/kafka-topics.sh --bootstrap-server kafka:9092 --create --partitions 1 --replication-factor 1 --topic test
bin/kafka-topics.sh --bootstrap-server kafka:9092 --create --topic test
# 查看 topic
bin/kafka-topics.sh --bootstrap-server kafka:9092 --list
bin/kafka-topics.sh --bootstrap-server kafka:9092 --describe --topic test
# 修改 topic, 分区改为两个(分区数只能增不能减)
bin/kafka-topics.sh --bootstrap-server kafka:9092 -alter --partitions 2 --topic test
# 删除 topic
bin/kafka-topics.sh --bootstrap-server kafka:9092 --delete --topic test
# 生产
bin/kafka-console-producer.sh --broker-list kafka:9092 --topic test
<think>嗯,用户想在单机环境下使用docker-compose部署Kafka。我需要回忆一下相关的步骤。首先,我记得Kafka依赖Zookeeper,所以需要同时部署这两个服务。用户提供的引用中有提到使用wurstmeister的镜像,比如引用5提到拉取这两个镜像,然后启动服务。还有引用3提到docker-compose部署kafka集群,但用户只需要单机,所以可能需要调整配置。 用户的问题是如何用docker-compose在单机上部署Kafka。根据引用1中的示例,启动命令是docker-compose up -d kafka,但可能需要先确保Zookeeper和Kafka的配置正确。引用4提到启动后生成zk和kafka文件夹,可能涉及到卷的映射。 接下来,我需要整理步骤。首先创建一个docker-compose.yml文件,定义两个服务:zookeeper和kafka。Zookeeper使用wurstmeister/zookeeper镜像,端口2181。Kafka使用wurstmeister/kafka,依赖Zookeeper,需要设置环境变量如KAFKA_ADVERTISED_LISTENERS,端口9092。还要挂载卷到/tmp/kafka-logs,并设置KAFKA_ZOOKEEPER_CONNECT指向Zookeeper。 需要注意环境变量的配置是否正确,特别是广告监听器,确保Kafka能被外部访问。另外,单机部署可能不需要集群配置,所以副本数设为1。然后启动命令是docker-compose up -d,测试的话可以用一个生产者消费者示例,比如用kafka-console-producer.sh和consumer.sh。 用户可能遇到的问题包括端口是否正确开放,环境变量配置错误导致连接不上,或者docker-compose版本问题,如引用3提到的赋予执行权限。另外,数据持久化也是需要考虑的,挂载卷到本地目录。 总结下来,步骤是编写docker-compose.yml,启动服务,验证。可能还需要检查防火墙设置,或者Docker的网络配置是否正确。如果用户是单机测试,可能不需要复杂的网络设置,但广告地址要设为宿主机的IP或localhost。</think>### 单机环境下使用 Docker Compose 部署 Kafka 的步骤 #### 1. 创建 `docker-compose.yml` 文件 新建一个目录(例如 `kafka-single`),并在其中创建 `docker-compose.yml` 文件,内容如下: ```yaml version: '3' services: zookeeper: image: wurstmeister/zookeeper ports: - "2181:2181" networks: - kafka-net kafka: image: wurstmeister/kafka ports: - "9092:9092" environment: KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092 KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092 KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true" volumes: - /tmp/kafka-logs:/kafka depends_on: - zookeeper networks: - kafka-net networks: kafka-net: driver: bridge ``` #### 2. 启动服务 在包含 `docker-compose.yml` 的目录下执行: ```bash docker-compose up -d ``` 此命令会启动 Zookeeper 和 Kafka 容器,日志文件将映射到 `/tmp/kafka-logs`(通过 `volumes` 配置)[^4]。 #### 3. 验证服务 - **检查容器状态**: ```bash docker-compose ps ``` 应显示 `zookeeper` 和 `kafka` 容器状态为 `Up`。 - **测试 Kafka 生产者/消费者**: ```bash # 进入 Kafka 容器 docker exec -it kafka-single_kafka_1 bash # 创建主题 kafka-topics.sh --create --topic test-topic --bootstrap-server localhost:9092 --partitions 1 --replication-factor 1 # 启动生产者 kafka-console-producer.sh --topic test-topic --bootstrap-server localhost:9092 # 另开终端启动消费者 kafka-console-consumer.sh --topic test-topic --bootstrap-server localhost:9092 --from-beginning ``` #### 关键配置说明 - **`KAFKA_ADVERTISED_LISTENERS`**:声明 Kafka 对外暴露的地址(需与客户端访问地址一致)[^1] - **`KAFKA_ZOOKEEPER_CONNECT`**:指定 Zookeeper 服务地址 - **`volumes`**:持久化 Kafka 数据到宿主机目录 - **`networks`**:自定义网络确保容器间通信
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
OSZAR »