docker-compose 部署单节点 kafka 4.0 测试环境
·
高版本kafka已经不再需要ZooKeeper当保姆才能启动了,现在部署一个单机单节点测试环境比原来方便不少。
不过最常用的bitnami/kafka不再提供免费镜像,导致我们只能用apache/kafka,新镜像的配置会稍微麻烦一些,所以记录一下。
部署内容:
- 单节点kafka服务,版本4.0+
- kafka UI,方便管理,版本用最新的
- 开启简单的用户名密码验证
docker-compose文件:
version: '3' |
|
networks: |
|
kafka-net: |
|
services: |
|
kafka: |
|
image: apache/kafka:latest |
|
container_name: kafka |
|
networks: |
|
- kafka-net |
|
ports: |
|
- "9092:9092" |
|
volumes: |
|
- ./kafka_data:/var/lib/kafka/data |
|
- ./kafka_server_jaas.conf:/etc/kafka/kafka_server_jaas.conf # 配置用户名密码 |
|
environment: |
|
KAFKA_NODE_ID: 1 |
|
KAFKA_PROCESS_ROLES: 'broker,controller' |
|
KAFKA_CONTROLLER_QUORUM_VOTERS: '1@localhost:9093' |
|
KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER' |
|
# 定义监听器:EXTERNAL(9092) 走 SASL 认证,PLAINTEXT(29092) 给容器内用(这里也改为 SASL 确保安全) |
|
KAFKA_LISTENERS: 'SASL_PLAINTEXT://0.0.0.0:29092,EXTERNAL://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093' |
|
KAFKA_ADVERTISED_LISTENERS: 'SASL_PLAINTEXT://kafka:29092,EXTERNAL://localhost:9092' |
|
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: 'CONTROLLER:PLAINTEXT,SASL_PLAINTEXT:SASL_PLAINTEXT,EXTERNAL:SASL_PLAINTEXT' |
|
KAFKA_INTER_BROKER_LISTENER_NAME: 'SASL_PLAINTEXT' |
|
# SASL/PLAIN 认证配置 |
|
KAFKA_SASL_ENABLED_MECHANISMS: 'PLAIN' |
|
KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL: 'PLAIN' |
|
# 告诉 Kafka 读取我们的 JAAS 文件 |
|
KAFKA_OPTS: "-Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf" |
|
# 数据持久化 |
|
KAFKA_LOG_DIRS: '/var/lib/kafka/data' |
|
kafka-ui: |
|
image: provectuslabs/kafka-ui:latest |
|
container_name: kafka-ui |
|
depends_on: |
|
- kafka |
|
networks: |
|
- kafka-net |
|
ports: |
|
# 映射到8090,因为8080一般还得挂其他的服务做测试 |
|
- "8090:8080" |
|
environment: |
|
KAFKA_CLUSTERS_0_NAME: local |
|
KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka:29092 |
|
# 配置 UI 使用用户名和密码连接 Kafka |
|
KAFKA_CLUSTERS_0_PROPERTIES_SECURITY_PROTOCOL: SASL_PLAINTEXT |
|
KAFKA_CLUSTERS_0_PROPERTIES_SASL_MECHANISM: PLAIN |
|
KAFKA_CLUSTERS_0_PROPERTIES_SASL_JAAS_CONFIG: 'org.apache.kafka.common.security.plain.PlainLoginModule required username="你配置的用户名" password="你配置的密码";' |
配置文件里输入用户和密码:
KafkaServer { |
|
org.apache.kafka.common.security.plain.PlainLoginModule required |
|
username="节点在集群内通信时的用户名" |
|
password="节点在集群内通信时的密码" |
|
# 下面这些才是用户配置 |
|
# 格式user_<用户名>="密码" |
|
user_apot="你配置的密码"; |
|
}; |
创建好文件和目录之后用docker-compose up -d就能启动服务了。访问localhost:8090可以看到kafka的web控制面板:

安装好之后可以用下面的命令查看版本:
$ docker exec -it kafka /opt/kafka/bin/kafka-server-start.sh --version |
|
[2025-12-29 11:08:34,595] INFO Registered kafka:type=kafka.Log4jController MBean (kafka.utils.Log4jControllerRegistration$) |
|
4.0.0 |
可以看到已经配置好了kafka 4.0环境。
apache/kafka的镜像里内置了各种操作kafka的脚本,不过这些脚本没被添加进$PATH,执行的时候需要指定路径:
# 先配置登录验证信息 |
|
docker exec -it kafka bash -c "cat <<EOF > /tmp/client.conf |
|
security.protocol=SASL_PLAINTEXT |
|
sasl.mechanism=PLAIN |
|
sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \ |
|
username='客户端登录用户名,就是我们之前用user_xxx配置的那些' \ |
|
password='客户端登录密码'; |
|
EOF" |
|
# 调用脚本创建一个topic,需要指定脚本路径 |
|
docker exec -it kafka /opt/kafka/bin/kafka-topics.sh --command-config /tmp/client.conf \ |
|
--bootstrap-server localhost:9092 \ |
|
--create \ |
|
--topic test.data \ |
|
--partitions 1 \ |
|
--replication-factor 1 \ |
|
--config cleanup.policy=delete \ |
|
--config retention.ms=86400000 |
所有脚本都存放在/opt/kafka/bin路径下,调用前还需要提供登录凭证信息,这些需要注意。打开localhost:8090上的web UI,就能找到我们刚刚创建的topic了:

过期处理策略和过期时间也已经被正确设置:

总体而言执行脚本还是有些繁琐,我更愿意通过代码或者web界面来做这些操作。
最后我们写一个go的测试代码,向我们的测试用单节点kafka里写入一些数据:
package main |
|
import ( |
|
"context" |
|
"math/rand/v2" |
|
"strconv" |
|
"time" |
|
"github.com/segmentio/kafka-go" |
|
"github.com/segmentio/kafka-go/sasl/plain" |
|
) |
|
const ( |
|
topic = "lean.data1" |
|
kafkaEndpoint = "localhost:9092" |
|
) |
|
func main() { |
|
mechanism := plain.Mechanism{ |
|
Username: "客户端登录用户名", |
|
Password: "客户端登录密码", |
|
} |
|
dialer := &kafka.Dialer{ |
|
Timeout: 10 * time.Second, |
|
DualStack: true, |
|
SASLMechanism: mechanism, |
|
} |
|
w := kafka.NewWriter(kafka.WriterConfig{ |
|
Brokers: []string{kafkaEndpoint}, |
|
Dialer: dialer, // 必须传入带 SASL 的 dialer |
|
Async: false, |
|
}) |
|
defer w.Close() |
|
msg := kafka.Message{ |
|
Topic: topic, |
|
Key: []byte("test"), |
|
Value: []byte(strconv.Itoa(rand.Int())), // 随便写入一些随机数据 |
|
} |
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) |
|
defer cancel() |
|
err := w.WriteMessages(ctx, msg) |
|
if err != nil { |
|
panic(err) |
|
} |
|
} |

可以看到我们的随机数已经正常写入topic了。
注意:这个配置只使用了最基本的验证,且是单节点,不适合在测试和学习之外的任何用途使用,为了安全我也建议在测试完成之后就立刻用docker-compose down关闭服务。
更多推荐




所有评论(0)